Skip to content

Commit 1a172b9

Browse files
authored
[RISCV][GISel] Lower G_SSUBE (#157855)
### Summary Try to implemente Lower G_SSUBE in LegalizerHelper::lower
1 parent 7ca448e commit 1a172b9

File tree

6 files changed

+429
-4
lines changed

6 files changed

+429
-4
lines changed

llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,7 @@ class LegalizerHelper {
511511
LLVM_ABI LegalizeResult lowerInsert(MachineInstr &MI);
512512
LLVM_ABI LegalizeResult lowerSADDO_SSUBO(MachineInstr &MI);
513513
LLVM_ABI LegalizeResult lowerSADDE(MachineInstr &MI);
514+
LLVM_ABI LegalizeResult lowerSSUBE(MachineInstr &MI);
514515
LLVM_ABI LegalizeResult lowerAddSubSatToMinMax(MachineInstr &MI);
515516
LLVM_ABI LegalizeResult lowerAddSubSatToAddoSubo(MachineInstr &MI);
516517
LLVM_ABI LegalizeResult lowerShlSat(MachineInstr &MI);

llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4457,6 +4457,8 @@ LegalizerHelper::lower(MachineInstr &MI, unsigned TypeIdx, LLT LowerHintTy) {
44574457
return lowerSADDO_SSUBO(MI);
44584458
case TargetOpcode::G_SADDE:
44594459
return lowerSADDE(MI);
4460+
case TargetOpcode::G_SSUBE:
4461+
return lowerSSUBE(MI);
44604462
case TargetOpcode::G_UMULH:
44614463
case TargetOpcode::G_SMULH:
44624464
return lowerSMULH_UMULH(MI);
@@ -9330,6 +9332,27 @@ LegalizerHelper::LegalizeResult LegalizerHelper::lowerSADDE(MachineInstr &MI) {
93309332
return Legalized;
93319333
}
93329334

9335+
LegalizerHelper::LegalizeResult LegalizerHelper::lowerSSUBE(MachineInstr &MI) {
9336+
auto [Res, OvOut, LHS, RHS, CarryIn] = MI.getFirst5Regs();
9337+
const LLT Ty = MRI.getType(Res);
9338+
9339+
// Diff = LHS - (RHS + zext(CarryIn))
9340+
auto CarryZ = MIRBuilder.buildZExt(Ty, CarryIn);
9341+
auto RHSPlusCI = MIRBuilder.buildAdd(Ty, RHS, CarryZ);
9342+
auto Diff = MIRBuilder.buildSub(Ty, LHS, RHSPlusCI);
9343+
MIRBuilder.buildCopy(Res, Diff);
9344+
9345+
// ov = msb((LHS ^ RHS) & (LHS ^ Diff))
9346+
auto X1 = MIRBuilder.buildXor(Ty, LHS, RHS);
9347+
auto X2 = MIRBuilder.buildXor(Ty, LHS, Diff);
9348+
auto T = MIRBuilder.buildAnd(Ty, X1, X2);
9349+
auto Zero = MIRBuilder.buildConstant(Ty, 0);
9350+
MIRBuilder.buildICmp(CmpInst::ICMP_SLT, OvOut, T, Zero);
9351+
9352+
MI.eraseFromParent();
9353+
return Legalized;
9354+
}
9355+
93339356
LegalizerHelper::LegalizeResult
93349357
LegalizerHelper::lowerAddSubSatToMinMax(MachineInstr &MI) {
93359358
auto [Res, LHS, RHS] = MI.getFirst3Regs();

llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
151151
getActionDefinitionsBuilder(
152152
{G_UADDE, G_UADDO, G_USUBE, G_USUBO}).lower();
153153

154-
getActionDefinitionsBuilder({G_SADDO, G_SADDE, G_SSUBO})
154+
getActionDefinitionsBuilder({G_SADDE, G_SADDO, G_SSUBE, G_SSUBO})
155155
.minScalar(0, sXLen)
156156
.lower();
157157

llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -405,19 +405,20 @@
405405
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
406406
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
407407
# DEBUG-NEXT: G_SADDO (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
408+
# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
408409
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
409410
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
410411
# DEBUG-NEXT: G_SADDE (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
411-
# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
412412
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
413413
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
414414
# DEBUG-NEXT: G_SSUBO (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
415415
# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
416416
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
417417
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
418418
# DEBUG-NEXT: G_SSUBE (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
419-
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
420-
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
419+
# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
420+
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
421+
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
421422
# DEBUG-NEXT: G_UMULO (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
422423
# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
423424
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2+
# RUN: llc -mtriple=riscv32 -run-pass=legalizer %s -o - | FileCheck %s
3+
4+
---
5+
name: ssube_i8
6+
body: |
7+
bb.1:
8+
liveins: $x10, $x11, $x12
9+
10+
; CHECK-LABEL: name: ssube_i8
11+
; CHECK: liveins: $x10, $x11, $x12
12+
; CHECK-NEXT: {{ $}}
13+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
14+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
15+
; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x12
16+
; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
17+
; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[COPY]], [[C]](s32)
18+
; CHECK-NEXT: [[ASHR:%[0-9]+]]:_(s32) = G_ASHR [[SHL]], [[C]](s32)
19+
; CHECK-NEXT: [[SHL1:%[0-9]+]]:_(s32) = G_SHL [[COPY1]], [[C]](s32)
20+
; CHECK-NEXT: [[ASHR1:%[0-9]+]]:_(s32) = G_ASHR [[SHL1]], [[C]](s32)
21+
; CHECK-NEXT: [[SUB:%[0-9]+]]:_(s32) = G_SUB [[ASHR]], [[ASHR1]]
22+
; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
23+
; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY2]], [[C1]]
24+
; CHECK-NEXT: [[SUB1:%[0-9]+]]:_(s32) = G_SUB [[SUB]], [[AND]]
25+
; CHECK-NEXT: [[SHL2:%[0-9]+]]:_(s32) = G_SHL [[SUB1]], [[C]](s32)
26+
; CHECK-NEXT: [[ASHR2:%[0-9]+]]:_(s32) = G_ASHR [[SHL2]], [[C]](s32)
27+
; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(ne), [[SUB1]](s32), [[ASHR2]]
28+
; CHECK-NEXT: $x10 = COPY [[SUB1]](s32)
29+
; CHECK-NEXT: $x11 = COPY [[ICMP]](s32)
30+
; CHECK-NEXT: PseudoRET implicit $x10, implicit $x11
31+
%0:_(s32) = COPY $x10
32+
%1:_(s8) = G_TRUNC %0(s32)
33+
%2:_(s32) = COPY $x11
34+
%3:_(s8) = G_TRUNC %2(s32)
35+
%4:_(s32) = COPY $x12
36+
%5:_(s1) = G_TRUNC %4(s32)
37+
%6:_(s8), %7:_(s1) = G_SSUBE %1, %3, %5
38+
%8:_(s32) = G_ANYEXT %6(s8)
39+
%9:_(s32) = G_ANYEXT %7(s1)
40+
$x10 = COPY %8(s32)
41+
$x11 = COPY %9(s32)
42+
PseudoRET implicit $x10, implicit $x11
43+
44+
...
45+
---
46+
name: ssube_i16
47+
body: |
48+
bb.1:
49+
liveins: $x10, $x11, $x12
50+
51+
; CHECK-LABEL: name: ssube_i16
52+
; CHECK: liveins: $x10, $x11, $x12
53+
; CHECK-NEXT: {{ $}}
54+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
55+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
56+
; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x12
57+
; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
58+
; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[COPY]], [[C]](s32)
59+
; CHECK-NEXT: [[ASHR:%[0-9]+]]:_(s32) = G_ASHR [[SHL]], [[C]](s32)
60+
; CHECK-NEXT: [[SHL1:%[0-9]+]]:_(s32) = G_SHL [[COPY1]], [[C]](s32)
61+
; CHECK-NEXT: [[ASHR1:%[0-9]+]]:_(s32) = G_ASHR [[SHL1]], [[C]](s32)
62+
; CHECK-NEXT: [[SUB:%[0-9]+]]:_(s32) = G_SUB [[ASHR]], [[ASHR1]]
63+
; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
64+
; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY2]], [[C1]]
65+
; CHECK-NEXT: [[SUB1:%[0-9]+]]:_(s32) = G_SUB [[SUB]], [[AND]]
66+
; CHECK-NEXT: [[SHL2:%[0-9]+]]:_(s32) = G_SHL [[SUB1]], [[C]](s32)
67+
; CHECK-NEXT: [[ASHR2:%[0-9]+]]:_(s32) = G_ASHR [[SHL2]], [[C]](s32)
68+
; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(ne), [[SUB1]](s32), [[ASHR2]]
69+
; CHECK-NEXT: $x10 = COPY [[SUB1]](s32)
70+
; CHECK-NEXT: $x11 = COPY [[ICMP]](s32)
71+
; CHECK-NEXT: PseudoRET implicit $x10, implicit $x11
72+
%0:_(s32) = COPY $x10
73+
%1:_(s16) = G_TRUNC %0(s32)
74+
%2:_(s32) = COPY $x11
75+
%3:_(s16) = G_TRUNC %2(s32)
76+
%4:_(s32) = COPY $x12
77+
%5:_(s1) = G_TRUNC %4(s32)
78+
%6:_(s16), %7:_(s1) = G_SSUBE %1, %3, %5
79+
%8:_(s32) = G_ANYEXT %6(s16)
80+
%9:_(s32) = G_ANYEXT %7(s1)
81+
$x10 = COPY %8(s32)
82+
$x11 = COPY %9(s32)
83+
PseudoRET implicit $x10, implicit $x11
84+
85+
...
86+
---
87+
name: ssube_i32
88+
body: |
89+
bb.1:
90+
liveins: $x10, $x11, $x12
91+
92+
; CHECK-LABEL: name: ssube_i32
93+
; CHECK: liveins: $x10, $x11, $x12
94+
; CHECK-NEXT: {{ $}}
95+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
96+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
97+
; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x12
98+
; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
99+
; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY2]], [[C]]
100+
; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[COPY1]], [[AND]]
101+
; CHECK-NEXT: [[SUB:%[0-9]+]]:_(s32) = G_SUB [[COPY]], [[ADD]]
102+
; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY [[SUB]](s32)
103+
; CHECK-NEXT: [[XOR:%[0-9]+]]:_(s32) = G_XOR [[COPY]], [[COPY1]]
104+
; CHECK-NEXT: [[XOR1:%[0-9]+]]:_(s32) = G_XOR [[COPY]], [[SUB]]
105+
; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[XOR]], [[XOR1]]
106+
; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
107+
; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(slt), [[AND1]](s32), [[C1]]
108+
; CHECK-NEXT: $x10 = COPY [[COPY3]](s32)
109+
; CHECK-NEXT: $x11 = COPY [[ICMP]](s32)
110+
; CHECK-NEXT: PseudoRET implicit $x10, implicit $x11
111+
%0:_(s32) = COPY $x10
112+
%1:_(s32) = COPY $x11
113+
%2:_(s32) = COPY $x12
114+
%3:_(s1) = G_TRUNC %2(s32)
115+
%4:_(s32), %5:_(s1) = G_SSUBE %0, %1, %3
116+
%6:_(s32) = G_ANYEXT %5(s1)
117+
$x10 = COPY %4(s32)
118+
$x11 = COPY %6(s32)
119+
PseudoRET implicit $x10, implicit $x11
120+
121+
...
122+
---
123+
name: ssube_i64
124+
body: |
125+
bb.1:
126+
liveins: $x10, $x11, $x12, $x13, $x14
127+
128+
; CHECK-LABEL: name: ssube_i64
129+
; CHECK: liveins: $x10, $x11, $x12, $x13, $x14
130+
; CHECK-NEXT: {{ $}}
131+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
132+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
133+
; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x12
134+
; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $x13
135+
; CHECK-NEXT: [[COPY4:%[0-9]+]]:_(s32) = COPY $x14
136+
; CHECK-NEXT: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
137+
; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
138+
; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
139+
; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY4]], [[C]]
140+
; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[DEF]], [[C1]]
141+
; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[COPY2]], [[AND]]
142+
; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(ult), [[ADD]](s32), [[AND]]
143+
; CHECK-NEXT: [[COPY5:%[0-9]+]]:_(s32) = COPY [[ADD]](s32)
144+
; CHECK-NEXT: [[ADD1:%[0-9]+]]:_(s32) = G_ADD [[COPY3]], [[AND1]]
145+
; CHECK-NEXT: [[ADD2:%[0-9]+]]:_(s32) = G_ADD [[ADD1]], [[ICMP]]
146+
; CHECK-NEXT: [[COPY6:%[0-9]+]]:_(s32) = COPY [[ADD2]](s32)
147+
; CHECK-NEXT: [[SUB:%[0-9]+]]:_(s32) = G_SUB [[COPY]], [[COPY5]]
148+
; CHECK-NEXT: [[ICMP1:%[0-9]+]]:_(s32) = G_ICMP intpred(ult), [[COPY]](s32), [[COPY5]]
149+
; CHECK-NEXT: [[SUB1:%[0-9]+]]:_(s32) = G_SUB [[COPY1]], [[COPY6]]
150+
; CHECK-NEXT: [[SUB2:%[0-9]+]]:_(s32) = G_SUB [[SUB1]], [[ICMP1]]
151+
; CHECK-NEXT: [[XOR:%[0-9]+]]:_(s32) = G_XOR [[COPY]], [[COPY2]]
152+
; CHECK-NEXT: [[XOR1:%[0-9]+]]:_(s32) = G_XOR [[COPY1]], [[COPY3]]
153+
; CHECK-NEXT: [[XOR2:%[0-9]+]]:_(s32) = G_XOR [[COPY]], [[SUB]]
154+
; CHECK-NEXT: [[XOR3:%[0-9]+]]:_(s32) = G_XOR [[COPY1]], [[SUB2]]
155+
; CHECK-NEXT: [[AND2:%[0-9]+]]:_(s32) = G_AND [[XOR]], [[XOR2]]
156+
; CHECK-NEXT: [[AND3:%[0-9]+]]:_(s32) = G_AND [[XOR1]], [[XOR3]]
157+
; CHECK-NEXT: [[ICMP2:%[0-9]+]]:_(s32) = G_ICMP intpred(ult), [[AND2]](s32), [[C1]]
158+
; CHECK-NEXT: [[ICMP3:%[0-9]+]]:_(s32) = G_ICMP intpred(slt), [[AND3]](s32), [[C1]]
159+
; CHECK-NEXT: [[ICMP4:%[0-9]+]]:_(s32) = G_ICMP intpred(eq), [[AND3]](s32), [[C1]]
160+
; CHECK-NEXT: [[SELECT:%[0-9]+]]:_(s32) = G_SELECT [[ICMP4]](s32), [[ICMP2]], [[ICMP3]]
161+
; CHECK-NEXT: $x10 = COPY [[SUB]](s32)
162+
; CHECK-NEXT: $x11 = COPY [[SUB2]](s32)
163+
; CHECK-NEXT: $x12 = COPY [[SELECT]](s32)
164+
; CHECK-NEXT: PseudoRET implicit $x10, implicit $x11, implicit $x12
165+
%0:_(s32) = COPY $x10
166+
%1:_(s32) = COPY $x11
167+
%2:_(s64) = G_MERGE_VALUES %0(s32), %1(s32)
168+
%3:_(s32) = COPY $x12
169+
%4:_(s32) = COPY $x13
170+
%5:_(s64) = G_MERGE_VALUES %3(s32), %4(s32)
171+
%6:_(s32) = COPY $x14
172+
%7:_(s1) = G_TRUNC %6(s32)
173+
%8:_(s64), %9:_(s1) = G_SSUBE %2, %5, %7
174+
%10:_(s32), %11:_(s32) = G_UNMERGE_VALUES %8(s64)
175+
%12:_(s32) = G_ANYEXT %9(s1)
176+
$x10 = COPY %10(s32)
177+
$x11 = COPY %11(s32)
178+
$x12 = COPY %12(s32)
179+
PseudoRET implicit $x10, implicit $x11, implicit $x12
180+
...

0 commit comments

Comments
 (0)