Skip to content

Commit c691726

Browse files
authored
[RISCV][GISel] Lower G_SADDE (#156865)
### Summary Try to implemente Lower G_SADDE in LegalizerHelper::lower
1 parent 902f1fc commit c691726

File tree

6 files changed

+415
-3
lines changed

6 files changed

+415
-3
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,7 @@ class LegalizerHelper {
510510
LLVM_ABI LegalizeResult lowerExtract(MachineInstr &MI);
511511
LLVM_ABI LegalizeResult lowerInsert(MachineInstr &MI);
512512
LLVM_ABI LegalizeResult lowerSADDO_SSUBO(MachineInstr &MI);
513+
LLVM_ABI LegalizeResult lowerSADDE(MachineInstr &MI);
513514
LLVM_ABI LegalizeResult lowerAddSubSatToMinMax(MachineInstr &MI);
514515
LLVM_ABI LegalizeResult lowerAddSubSatToAddoSubo(MachineInstr &MI);
515516
LLVM_ABI LegalizeResult lowerShlSat(MachineInstr &MI);

llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4449,6 +4449,8 @@ LegalizerHelper::lower(MachineInstr &MI, unsigned TypeIdx, LLT LowerHintTy) {
44494449
case TargetOpcode::G_SADDO:
44504450
case TargetOpcode::G_SSUBO:
44514451
return lowerSADDO_SSUBO(MI);
4452+
case TargetOpcode::G_SADDE:
4453+
return lowerSADDE(MI);
44524454
case TargetOpcode::G_UMULH:
44534455
case TargetOpcode::G_SMULH:
44544456
return lowerSMULH_UMULH(MI);
@@ -9300,6 +9302,28 @@ LegalizerHelper::lowerSADDO_SSUBO(MachineInstr &MI) {
93009302
return Legalized;
93019303
}
93029304

9305+
LegalizerHelper::LegalizeResult LegalizerHelper::lowerSADDE(MachineInstr &MI) {
9306+
auto [Res, OvOut, LHS, RHS, CarryIn] = MI.getFirst5Regs();
9307+
const LLT Ty = MRI.getType(Res);
9308+
9309+
// sum = LHS + RHS + zext(CarryIn)
9310+
auto Tmp = MIRBuilder.buildAdd(Ty, LHS, RHS);
9311+
auto CarryZ = MIRBuilder.buildZExt(Ty, CarryIn);
9312+
auto Sum = MIRBuilder.buildAdd(Ty, Tmp, CarryZ);
9313+
MIRBuilder.buildCopy(Res, Sum);
9314+
9315+
// OvOut = icmp slt ((sum ^ lhs) & (sum ^ rhs)), 0
9316+
auto AX = MIRBuilder.buildXor(Ty, Sum, LHS);
9317+
auto BX = MIRBuilder.buildXor(Ty, Sum, RHS);
9318+
auto T = MIRBuilder.buildAnd(Ty, AX, BX);
9319+
9320+
auto Zero = MIRBuilder.buildConstant(Ty, 0);
9321+
MIRBuilder.buildICmp(CmpInst::ICMP_SLT, OvOut, T, Zero);
9322+
9323+
MI.eraseFromParent();
9324+
return Legalized;
9325+
}
9326+
93039327
LegalizerHelper::LegalizeResult
93049328
LegalizerHelper::lowerAddSubSatToMinMax(MachineInstr &MI) {
93059329
auto [Res, LHS, RHS] = MI.getFirst3Regs();

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

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

154-
getActionDefinitionsBuilder({G_SADDO, G_SSUBO}).minScalar(0, sXLen).lower();
154+
getActionDefinitionsBuilder({G_SADDO, G_SADDE, G_SSUBO})
155+
.minScalar(0, sXLen)
156+
.lower();
155157

156158
// TODO: Use Vector Single-Width Saturating Instructions for vector types.
157159
getActionDefinitionsBuilder(

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -407,8 +407,9 @@
407407
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
408408
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
409409
# DEBUG-NEXT: G_SADDE (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
410-
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
411-
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
410+
# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
411+
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
412+
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
412413
# DEBUG-NEXT: G_SSUBO (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
413414
# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
414415
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
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: sadde_i8
6+
body: |
7+
bb.1:
8+
liveins: $x10, $x11, $x12
9+
10+
; CHECK-LABEL: name: sadde_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: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[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: [[ADD1:%[0-9]+]]:_(s32) = G_ADD [[ADD]], [[AND]]
25+
; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY [[ADD1]](s32)
26+
; CHECK-NEXT: [[SHL2:%[0-9]+]]:_(s32) = G_SHL [[COPY3]], [[C]](s32)
27+
; CHECK-NEXT: [[ASHR2:%[0-9]+]]:_(s32) = G_ASHR [[SHL2]], [[C]](s32)
28+
; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(ne), [[COPY3]](s32), [[ASHR2]]
29+
; CHECK-NEXT: $x10 = COPY [[COPY3]](s32)
30+
; CHECK-NEXT: $x11 = COPY [[ICMP]](s32)
31+
; CHECK-NEXT: PseudoRET implicit $x10, implicit $x11
32+
%0:_(s32) = COPY $x10
33+
%1:_(s8) = G_TRUNC %0(s32)
34+
%2:_(s32) = COPY $x11
35+
%3:_(s8) = G_TRUNC %2(s32)
36+
%4:_(s32) = COPY $x12
37+
%5:_(s1) = G_TRUNC %4(s32)
38+
%6:_(s8), %7:_(s1) = G_SADDE %1, %3, %5
39+
%8:_(s32) = G_ANYEXT %6(s8)
40+
%9:_(s32) = G_ANYEXT %7(s1)
41+
$x10 = COPY %8(s32)
42+
$x11 = COPY %9(s32)
43+
PseudoRET implicit $x10, implicit $x11
44+
45+
...
46+
---
47+
name: sadde_i16
48+
body: |
49+
bb.1:
50+
liveins: $x10, $x11, $x12
51+
52+
; CHECK-LABEL: name: sadde_i16
53+
; CHECK: liveins: $x10, $x11, $x12
54+
; CHECK-NEXT: {{ $}}
55+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
56+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
57+
; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x12
58+
; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
59+
; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[COPY]], [[C]](s32)
60+
; CHECK-NEXT: [[ASHR:%[0-9]+]]:_(s32) = G_ASHR [[SHL]], [[C]](s32)
61+
; CHECK-NEXT: [[SHL1:%[0-9]+]]:_(s32) = G_SHL [[COPY1]], [[C]](s32)
62+
; CHECK-NEXT: [[ASHR1:%[0-9]+]]:_(s32) = G_ASHR [[SHL1]], [[C]](s32)
63+
; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[ASHR]], [[ASHR1]]
64+
; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
65+
; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY2]], [[C1]]
66+
; CHECK-NEXT: [[ADD1:%[0-9]+]]:_(s32) = G_ADD [[ADD]], [[AND]]
67+
; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY [[ADD1]](s32)
68+
; CHECK-NEXT: [[SHL2:%[0-9]+]]:_(s32) = G_SHL [[COPY3]], [[C]](s32)
69+
; CHECK-NEXT: [[ASHR2:%[0-9]+]]:_(s32) = G_ASHR [[SHL2]], [[C]](s32)
70+
; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(ne), [[COPY3]](s32), [[ASHR2]]
71+
; CHECK-NEXT: $x10 = COPY [[COPY3]](s32)
72+
; CHECK-NEXT: $x11 = COPY [[ICMP]](s32)
73+
; CHECK-NEXT: PseudoRET implicit $x10, implicit $x11
74+
%0:_(s32) = COPY $x10
75+
%1:_(s16) = G_TRUNC %0(s32)
76+
%2:_(s32) = COPY $x11
77+
%3:_(s16) = G_TRUNC %2(s32)
78+
%4:_(s32) = COPY $x12
79+
%5:_(s1) = G_TRUNC %4(s32)
80+
%6:_(s16), %7:_(s1) = G_SADDE %1, %3, %5
81+
%8:_(s32) = G_ANYEXT %6(s16)
82+
%9:_(s32) = G_ANYEXT %7(s1)
83+
$x10 = COPY %8(s32)
84+
$x11 = COPY %9(s32)
85+
PseudoRET implicit $x10, implicit $x11
86+
87+
...
88+
---
89+
name: sadde_i32
90+
body: |
91+
bb.1:
92+
liveins: $x10, $x11, $x12
93+
94+
; CHECK-LABEL: name: sadde_i32
95+
; CHECK: liveins: $x10, $x11, $x12
96+
; CHECK-NEXT: {{ $}}
97+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
98+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
99+
; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x12
100+
; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[COPY]], [[COPY1]]
101+
; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
102+
; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY2]], [[C]]
103+
; CHECK-NEXT: [[ADD1:%[0-9]+]]:_(s32) = G_ADD [[ADD]], [[AND]]
104+
; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY [[ADD1]](s32)
105+
; CHECK-NEXT: [[XOR:%[0-9]+]]:_(s32) = G_XOR [[ADD1]], [[COPY]]
106+
; CHECK-NEXT: [[XOR1:%[0-9]+]]:_(s32) = G_XOR [[ADD1]], [[COPY1]]
107+
; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[XOR]], [[XOR1]]
108+
; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
109+
; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(slt), [[AND1]](s32), [[C1]]
110+
; CHECK-NEXT: $x10 = COPY [[COPY3]](s32)
111+
; CHECK-NEXT: $x11 = COPY [[ICMP]](s32)
112+
; CHECK-NEXT: PseudoRET implicit $x10, implicit $x11
113+
%0:_(s32) = COPY $x10
114+
%1:_(s32) = COPY $x11
115+
%2:_(s32) = COPY $x12
116+
%3:_(s1) = G_TRUNC %2(s32)
117+
%4:_(s32), %5:_(s1) = G_SADDE %0, %1, %3
118+
%6:_(s32) = G_ANYEXT %5(s1)
119+
$x10 = COPY %4(s32)
120+
$x11 = COPY %6(s32)
121+
PseudoRET implicit $x10, implicit $x11
122+
123+
...
124+
---
125+
name: sadde_i64
126+
body: |
127+
bb.1:
128+
liveins: $x10, $x11, $x12, $x13, $x14
129+
130+
; CHECK-LABEL: name: sadde_i64
131+
; CHECK: liveins: $x10, $x11, $x12, $x13, $x14
132+
; CHECK-NEXT: {{ $}}
133+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
134+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
135+
; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x12
136+
; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $x13
137+
; CHECK-NEXT: [[COPY4:%[0-9]+]]:_(s32) = COPY $x14
138+
; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[COPY]], [[COPY2]]
139+
; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
140+
; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY4]], [[C]]
141+
; CHECK-NEXT: [[ADD1:%[0-9]+]]:_(s32) = G_ADD [[ADD]], [[AND]]
142+
; CHECK-NEXT: [[COPY5:%[0-9]+]]:_(s32) = COPY [[ADD1]](s32)
143+
; CHECK-NEXT: [[XOR:%[0-9]+]]:_(s32) = G_XOR [[ADD1]], [[COPY]]
144+
; CHECK-NEXT: [[XOR1:%[0-9]+]]:_(s32) = G_XOR [[ADD1]], [[COPY2]]
145+
; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[XOR]], [[XOR1]]
146+
; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
147+
; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(slt), [[AND1]](s32), [[C1]]
148+
; CHECK-NEXT: [[ADD2:%[0-9]+]]:_(s32) = G_ADD [[COPY1]], [[COPY3]]
149+
; CHECK-NEXT: [[ADD3:%[0-9]+]]:_(s32) = G_ADD [[ADD2]], [[ICMP]]
150+
; CHECK-NEXT: [[COPY6:%[0-9]+]]:_(s32) = COPY [[ADD3]](s32)
151+
; CHECK-NEXT: [[XOR2:%[0-9]+]]:_(s32) = G_XOR [[ADD3]], [[COPY1]]
152+
; CHECK-NEXT: [[XOR3:%[0-9]+]]:_(s32) = G_XOR [[ADD3]], [[COPY3]]
153+
; CHECK-NEXT: [[AND2:%[0-9]+]]:_(s32) = G_AND [[XOR2]], [[XOR3]]
154+
; CHECK-NEXT: [[ICMP1:%[0-9]+]]:_(s32) = G_ICMP intpred(slt), [[AND2]](s32), [[C1]]
155+
; CHECK-NEXT: $x10 = COPY [[COPY5]](s32)
156+
; CHECK-NEXT: $x11 = COPY [[COPY6]](s32)
157+
; CHECK-NEXT: $x12 = COPY [[ICMP1]](s32)
158+
; CHECK-NEXT: PseudoRET implicit $x10, implicit $x11, implicit $x12
159+
%0:_(s32) = COPY $x10
160+
%1:_(s32) = COPY $x11
161+
%2:_(s32) = COPY $x12
162+
%3:_(s32) = COPY $x13
163+
%4:_(s32) = COPY $x14
164+
%5:_(s1) = G_TRUNC %4(s32)
165+
%6:_(s32), %7:_(s1) = G_SADDE %0, %2, %5
166+
%8:_(s32), %9:_(s1) = G_SADDE %1, %3, %7
167+
%10:_(s32) = G_ANYEXT %9(s1)
168+
$x10 = COPY %6(s32)
169+
$x11 = COPY %8(s32)
170+
$x12 = COPY %10(s32)
171+
172+
PseudoRET implicit $x10, implicit $x11, implicit $x12
173+
...

0 commit comments

Comments
 (0)