Skip to content

Commit cad1eef

Browse files
committed
[GlobalISel][X86] Add s8/s16/s64 handling of G_UADDE opcodes
1 parent 835cdcb commit cad1eef

File tree

3 files changed

+42
-19
lines changed

3 files changed

+42
-19
lines changed

llvm/lib/Target/X86/X86InstructionSelector.cpp

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1081,9 +1081,33 @@ bool X86InstructionSelector::selectUadde(MachineInstr &I,
10811081
Register CarryInReg = I.getOperand(4).getReg();
10821082

10831083
const LLT DstTy = MRI.getType(DstReg);
1084+
assert(DstTy.isScalar() && "G_UADDE only supported for scalar types");
10841085

1085-
if (DstTy != LLT::scalar(32))
1086-
return false;
1086+
// TODO: Handle immediate argument variants?
1087+
unsigned OpADC, OpADD;
1088+
switch (DstTy.getSizeInBits()) {
1089+
case 8:
1090+
OpADC = X86::ADC8rr;
1091+
OpADD = X86::ADD8rr;
1092+
break;
1093+
case 16:
1094+
OpADC = X86::ADC16rr;
1095+
OpADD = X86::ADD16rr;
1096+
break;
1097+
case 32:
1098+
OpADC = X86::ADC32rr;
1099+
OpADD = X86::ADD32rr;
1100+
break;
1101+
case 64:
1102+
OpADC = X86::ADC64rr;
1103+
OpADD = X86::ADD64rr;
1104+
break;
1105+
default:
1106+
llvm_unreachable("Can't select G_UADDE, unsupported type.");
1107+
}
1108+
1109+
const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
1110+
const TargetRegisterClass *DstRC = getRegClass(DstTy, DstRB);
10871111

10881112
// find CarryIn def instruction.
10891113
MachineInstr *Def = MRI.getVRegDef(CarryInReg);
@@ -1092,23 +1116,23 @@ bool X86InstructionSelector::selectUadde(MachineInstr &I,
10921116
Def = MRI.getVRegDef(CarryInReg);
10931117
}
10941118

1095-
unsigned Opcode;
1119+
unsigned Opcode = 0;
10961120
if (Def->getOpcode() == TargetOpcode::G_UADDE) {
10971121
// carry set by prev ADD.
10981122

10991123
BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::COPY), X86::EFLAGS)
11001124
.addReg(CarryInReg);
11011125

1102-
if (!RBI.constrainGenericRegister(CarryInReg, X86::GR32RegClass, MRI))
1126+
if (!RBI.constrainGenericRegister(CarryInReg, *DstRC, MRI))
11031127
return false;
11041128

1105-
Opcode = X86::ADC32rr;
1129+
Opcode = OpADC;
11061130
} else if (auto val = getIConstantVRegVal(CarryInReg, MRI)) {
11071131
// carry is constant, support only 0.
11081132
if (*val != 0)
11091133
return false;
11101134

1111-
Opcode = X86::ADD32rr;
1135+
Opcode = OpADD;
11121136
} else
11131137
return false;
11141138

@@ -1121,7 +1145,7 @@ bool X86InstructionSelector::selectUadde(MachineInstr &I,
11211145
.addReg(X86::EFLAGS);
11221146

11231147
if (!constrainSelectedInstRegOperands(AddInst, TII, TRI, RBI) ||
1124-
!RBI.constrainGenericRegister(CarryOutReg, X86::GR32RegClass, MRI))
1148+
!RBI.constrainGenericRegister(CarryOutReg, *DstRC, MRI))
11251149
return false;
11261150

11271151
I.eraseFromParent();

llvm/lib/Target/X86/X86LegalizerInfo.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -148,12 +148,15 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI,
148148
.clampScalar(0, s8, sMaxScalar)
149149
.scalarize(0);
150150

151-
// TODO: Add all legal scalar types.
152151
// TODO: Add G_UADDO/G_USUBO/G_USUBE handling
153152
getActionDefinitionsBuilder(G_UADDE)
154-
.legalFor({{s32, s1}})
153+
.legalIf([=](const LegalityQuery &Query) -> bool {
154+
return typePairInSet(0, 1, {{s8, s1}, {s16, s1}, {s32, s1}})(Query) ||
155+
(Is64Bit && typePairInSet(0, 1, {{s64, s1}})(Query));
156+
})
155157
.widenScalarToNextPow2(0, /*Min=*/32)
156-
.clampScalar(0, s32, s32)
158+
.clampScalar(0, s8, sMaxScalar)
159+
.clampScalar(1, s1, s1)
157160
.scalarize(0);
158161

159162
// integer multiply

llvm/test/CodeGen/X86/GlobalISel/legalize-add.mir

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -232,15 +232,11 @@ body: |
232232
; X64-NEXT: [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[DEF]](s128)
233233
; X64-NEXT: [[UV2:%[0-9]+]]:_(s64), [[UV3:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[DEF1]](s128)
234234
; X64-NEXT: [[UADDO:%[0-9]+]]:_(s64), [[UADDO1:%[0-9]+]]:_(s1) = G_UADDO [[UV]], [[UV2]]
235-
; X64-NEXT: [[UV4:%[0-9]+]]:_(s32), [[UV5:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[UV1]](s64)
236-
; X64-NEXT: [[UV6:%[0-9]+]]:_(s32), [[UV7:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[UV3]](s64)
237-
; X64-NEXT: [[UADDE:%[0-9]+]]:_(s32), [[UADDE1:%[0-9]+]]:_(s1) = G_UADDE [[UV4]], [[UV6]], [[UADDO1]]
238-
; X64-NEXT: [[UADDE2:%[0-9]+]]:_(s32), [[UADDE3:%[0-9]+]]:_(s1) = G_UADDE [[UV5]], [[UV7]], [[UADDE1]]
239-
; X64-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[UADDE]](s32), [[UADDE2]](s32)
240-
; X64-NEXT: [[MV1:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[UADDO]](s64), [[MV]](s64)
241-
; X64-NEXT: [[UV8:%[0-9]+]]:_(s64), [[UV9:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[MV1]](s128)
242-
; X64-NEXT: $rax = COPY [[UV8]](s64)
243-
; X64-NEXT: $rdx = COPY [[UV9]](s64)
235+
; X64-NEXT: [[UADDE:%[0-9]+]]:_(s64), [[UADDE1:%[0-9]+]]:_(s1) = G_UADDE [[UV1]], [[UV3]], [[UADDO1]]
236+
; X64-NEXT: [[MV:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[UADDO]](s64), [[UADDE]](s64)
237+
; X64-NEXT: [[UV4:%[0-9]+]]:_(s64), [[UV5:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[MV]](s128)
238+
; X64-NEXT: $rax = COPY [[UV4]](s64)
239+
; X64-NEXT: $rdx = COPY [[UV5]](s64)
244240
; X64-NEXT: RET 0
245241
; X32-LABEL: name: test_add_i128
246242
; X32: [[DEF:%[0-9]+]]:_(s128) = IMPLICIT_DEF

0 commit comments

Comments
 (0)