Skip to content

Commit eb623e6

Browse files
authored
[RISCV][GISel] Lower G_ABDS and G_ABDU (#155888)
Implementation follows the `ISD::ABDS` handling in `RISCVTargetLowering`.
1 parent 8e4457b commit eb623e6

File tree

6 files changed

+597
-4
lines changed

6 files changed

+597
-4
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,8 @@ class LegalizerHelper {
522522
LLVM_ABI LegalizeResult lowerAbsToAddXor(MachineInstr &MI);
523523
LLVM_ABI LegalizeResult lowerAbsToMaxNeg(MachineInstr &MI);
524524
LLVM_ABI LegalizeResult lowerAbsToCNeg(MachineInstr &MI);
525+
LLVM_ABI LegalizeResult lowerAbsDiffToSelect(MachineInstr &MI);
526+
LLVM_ABI LegalizeResult lowerAbsDiffToMinMax(MachineInstr &MI);
525527
LLVM_ABI LegalizeResult lowerFAbs(MachineInstr &MI);
526528
LLVM_ABI LegalizeResult lowerVectorReduction(MachineInstr &MI);
527529
LLVM_ABI LegalizeResult lowerMemcpyInline(MachineInstr &MI);

llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4742,6 +4742,16 @@ LegalizerHelper::lower(MachineInstr &MI, unsigned TypeIdx, LLT LowerHintTy) {
47424742
return lowerShlSat(MI);
47434743
case G_ABS:
47444744
return lowerAbsToAddXor(MI);
4745+
case G_ABDS:
4746+
case G_ABDU: {
4747+
bool IsSigned = MI.getOpcode() == G_ABDS;
4748+
LLT Ty = MRI.getType(MI.getOperand(0).getReg());
4749+
if ((IsSigned && LI.isLegal({G_SMIN, Ty}) && LI.isLegal({G_SMAX, Ty})) ||
4750+
(!IsSigned && LI.isLegal({G_UMIN, Ty}) && LI.isLegal({G_UMAX, Ty}))) {
4751+
return lowerAbsDiffToMinMax(MI);
4752+
}
4753+
return lowerAbsDiffToSelect(MI);
4754+
}
47454755
case G_FABS:
47464756
return lowerFAbs(MI);
47474757
case G_SELECT:
@@ -9925,6 +9935,54 @@ LegalizerHelper::lowerAbsToCNeg(MachineInstr &MI) {
99259935
return Legalized;
99269936
}
99279937

9938+
LegalizerHelper::LegalizeResult
9939+
LegalizerHelper::lowerAbsDiffToSelect(MachineInstr &MI) {
9940+
assert((MI.getOpcode() == TargetOpcode::G_ABDS ||
9941+
MI.getOpcode() == TargetOpcode::G_ABDU) &&
9942+
"Expected G_ABDS or G_ABDU instruction");
9943+
9944+
auto [DstReg, LHS, RHS] = MI.getFirst3Regs();
9945+
LLT Ty = MRI.getType(LHS);
9946+
9947+
// abds(lhs, rhs) -> select(sgt(lhs,rhs), sub(lhs,rhs), sub(rhs,lhs))
9948+
// abdu(lhs, rhs) -> select(ugt(lhs,rhs), sub(lhs,rhs), sub(rhs,lhs))
9949+
Register LHSSub = MIRBuilder.buildSub(Ty, LHS, RHS).getReg(0);
9950+
Register RHSSub = MIRBuilder.buildSub(Ty, RHS, LHS).getReg(0);
9951+
CmpInst::Predicate Pred = (MI.getOpcode() == TargetOpcode::G_ABDS)
9952+
? CmpInst::ICMP_SGT
9953+
: CmpInst::ICMP_UGT;
9954+
auto ICmp = MIRBuilder.buildICmp(Pred, LLT::scalar(1), LHS, RHS);
9955+
MIRBuilder.buildSelect(DstReg, ICmp, LHSSub, RHSSub);
9956+
9957+
MI.eraseFromParent();
9958+
return Legalized;
9959+
}
9960+
9961+
LegalizerHelper::LegalizeResult
9962+
LegalizerHelper::lowerAbsDiffToMinMax(MachineInstr &MI) {
9963+
assert((MI.getOpcode() == TargetOpcode::G_ABDS ||
9964+
MI.getOpcode() == TargetOpcode::G_ABDU) &&
9965+
"Expected G_ABDS or G_ABDU instruction");
9966+
9967+
auto [DstReg, LHS, RHS] = MI.getFirst3Regs();
9968+
LLT Ty = MRI.getType(LHS);
9969+
9970+
// abds(lhs, rhs) -→ sub(smax(lhs, rhs), smin(lhs, rhs))
9971+
// abdu(lhs, rhs) -→ sub(umax(lhs, rhs), umin(lhs, rhs))
9972+
Register MaxReg, MinReg;
9973+
if (MI.getOpcode() == TargetOpcode::G_ABDS) {
9974+
MaxReg = MIRBuilder.buildSMax(Ty, LHS, RHS).getReg(0);
9975+
MinReg = MIRBuilder.buildSMin(Ty, LHS, RHS).getReg(0);
9976+
} else {
9977+
MaxReg = MIRBuilder.buildUMax(Ty, LHS, RHS).getReg(0);
9978+
MinReg = MIRBuilder.buildUMin(Ty, LHS, RHS).getReg(0);
9979+
}
9980+
MIRBuilder.buildSub(DstReg, MaxReg, MinReg);
9981+
9982+
MI.eraseFromParent();
9983+
return Legalized;
9984+
}
9985+
99289986
LegalizerHelper::LegalizeResult LegalizerHelper::lowerFAbs(MachineInstr &MI) {
99299987
Register SrcReg = MI.getOperand(1).getReg();
99309988
Register DstReg = MI.getOperand(0).getReg();

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,8 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
488488
.minScalar(ST.hasStdExtZbb(), 0, sXLen)
489489
.lower();
490490

491+
getActionDefinitionsBuilder({G_ABDS, G_ABDU}).lower();
492+
491493
getActionDefinitionsBuilder({G_UMAX, G_UMIN, G_SMAX, G_SMIN})
492494
.legalFor(ST.hasStdExtZbb(), {sXLen})
493495
.minScalar(ST.hasStdExtZbb(), 0, sXLen)

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,13 @@
7373
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
7474
#
7575
# DEBUG-NEXT: G_ABDS (opcode 65): 1 type index, 0 imm indices
76-
# DEBUG-NEXT:.. type index coverage check SKIPPED: no rules defined
77-
# DEBUG-NEXT:.. imm index coverage check SKIPPED: no rules defined
76+
# DEBUG-NEXT:.. type index coverage check SKIPPED: user-defined predicate detected
77+
# DEBUG-NEXT:.. imm index coverage check SKIPPED: user-defined predicate detected
7878
#
7979
# DEBUG-NEXT:G_ABDU (opcode 66): 1 type index, 0 imm indices
80-
# DEBUG-NEXT:.. type index coverage check SKIPPED: no rules defined
81-
# DEBUG-NEXT:.. imm index coverage check SKIPPED: no rules defined
80+
# DEBUG-NEXT:.. opcode 66 is aliased to 65
81+
# DEBUG-NEXT:.. type index coverage check SKIPPED: user-defined predicate detected
82+
# DEBUG-NEXT:.. imm index coverage check SKIPPED: user-defined predicate detected
8283
#
8384
# DEBUG-NEXT: G_IMPLICIT_DEF (opcode {{[0-9]+}}): 1 type index, 0 imm indices
8485
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
Lines changed: 264 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,264 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2+
# RUN: llc -mtriple=riscv32 -run-pass=legalizer %s -o - \
3+
# RUN: | FileCheck %s --check-prefixes=CHECK,RV32I
4+
# RUN: llc -mtriple=riscv32 -mattr=+zbb -run-pass=legalizer %s -o - \
5+
# RUN: | FileCheck %s --check-prefixes=CHECK,RV32ZBB
6+
7+
---
8+
name: abds_i8
9+
body: |
10+
bb.0.entry:
11+
liveins: $x10, $x11
12+
; CHECK-LABEL: name: abds_i8
13+
; CHECK: liveins: $x10, $x11
14+
; CHECK-NEXT: {{ $}}
15+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
16+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
17+
; CHECK-NEXT: [[ASSERT_SEXT:%[0-9]+]]:_(s32) = G_ASSERT_SEXT [[COPY]], 8
18+
; CHECK-NEXT: [[ASSERT_SEXT1:%[0-9]+]]:_(s32) = G_ASSERT_SEXT [[COPY1]], 8
19+
; CHECK-NEXT: [[SUB:%[0-9]+]]:_(s32) = G_SUB [[ASSERT_SEXT]], [[ASSERT_SEXT1]]
20+
; CHECK-NEXT: [[SUB1:%[0-9]+]]:_(s32) = G_SUB [[ASSERT_SEXT1]], [[ASSERT_SEXT]]
21+
; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(sgt), [[ASSERT_SEXT]](s32), [[ASSERT_SEXT1]]
22+
; CHECK-NEXT: [[SELECT:%[0-9]+]]:_(s32) = G_SELECT [[ICMP]](s32), [[SUB]], [[SUB1]]
23+
; CHECK-NEXT: $x10 = COPY [[SELECT]](s32)
24+
; CHECK-NEXT: PseudoRET implicit $x10
25+
%1:_(s32) = COPY $x10
26+
%2:_(s32) = COPY $x11
27+
%3:_(s32) = G_ASSERT_SEXT %1, 8
28+
%4:_(s32) = G_ASSERT_SEXT %2, 8
29+
%5:_(s8) = G_TRUNC %3(s32)
30+
%6:_(s8) = G_TRUNC %4(s32)
31+
%7:_(s8) = G_ABDS %5, %6
32+
%8:_(s32) = G_ANYEXT %7(s8)
33+
$x10 = COPY %8(s32)
34+
PseudoRET implicit $x10
35+
...
36+
---
37+
name: abds_i16
38+
body: |
39+
bb.0.entry:
40+
liveins: $x10, $x11
41+
; CHECK-LABEL: name: abds_i16
42+
; CHECK: liveins: $x10, $x11
43+
; CHECK-NEXT: {{ $}}
44+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
45+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
46+
; CHECK-NEXT: [[ASSERT_SEXT:%[0-9]+]]:_(s32) = G_ASSERT_SEXT [[COPY]], 16
47+
; CHECK-NEXT: [[ASSERT_SEXT1:%[0-9]+]]:_(s32) = G_ASSERT_SEXT [[COPY1]], 16
48+
; CHECK-NEXT: [[SUB:%[0-9]+]]:_(s32) = G_SUB [[ASSERT_SEXT]], [[ASSERT_SEXT1]]
49+
; CHECK-NEXT: [[SUB1:%[0-9]+]]:_(s32) = G_SUB [[ASSERT_SEXT1]], [[ASSERT_SEXT]]
50+
; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(sgt), [[ASSERT_SEXT]](s32), [[ASSERT_SEXT1]]
51+
; CHECK-NEXT: [[SELECT:%[0-9]+]]:_(s32) = G_SELECT [[ICMP]](s32), [[SUB]], [[SUB1]]
52+
; CHECK-NEXT: $x10 = COPY [[SELECT]](s32)
53+
; CHECK-NEXT: PseudoRET implicit $x10
54+
%1:_(s32) = COPY $x10
55+
%2:_(s32) = COPY $x11
56+
%3:_(s32) = G_ASSERT_SEXT %1, 16
57+
%4:_(s32) = G_ASSERT_SEXT %2, 16
58+
%5:_(s16) = G_TRUNC %3(s32)
59+
%6:_(s16) = G_TRUNC %4(s32)
60+
%7:_(s16) = G_ABDS %5, %6
61+
%8:_(s32) = G_ANYEXT %7(s16)
62+
$x10 = COPY %8(s32)
63+
PseudoRET implicit $x10
64+
...
65+
---
66+
name: abds_i32
67+
body: |
68+
bb.0.entry:
69+
liveins: $x10, $x11
70+
; RV32I-LABEL: name: abds_i32
71+
; RV32I: liveins: $x10, $x11
72+
; RV32I-NEXT: {{ $}}
73+
; RV32I-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
74+
; RV32I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
75+
; RV32I-NEXT: [[SUB:%[0-9]+]]:_(s32) = G_SUB [[COPY]], [[COPY1]]
76+
; RV32I-NEXT: [[SUB1:%[0-9]+]]:_(s32) = G_SUB [[COPY1]], [[COPY]]
77+
; RV32I-NEXT: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(sgt), [[COPY]](s32), [[COPY1]]
78+
; RV32I-NEXT: [[SELECT:%[0-9]+]]:_(s32) = G_SELECT [[ICMP]](s32), [[SUB]], [[SUB1]]
79+
; RV32I-NEXT: $x10 = COPY [[SELECT]](s32)
80+
; RV32I-NEXT: PseudoRET implicit $x10
81+
;
82+
; RV32ZBB-LABEL: name: abds_i32
83+
; RV32ZBB: liveins: $x10, $x11
84+
; RV32ZBB-NEXT: {{ $}}
85+
; RV32ZBB-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
86+
; RV32ZBB-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
87+
; RV32ZBB-NEXT: [[SMAX:%[0-9]+]]:_(s32) = G_SMAX [[COPY]], [[COPY1]]
88+
; RV32ZBB-NEXT: [[SMIN:%[0-9]+]]:_(s32) = G_SMIN [[COPY]], [[COPY1]]
89+
; RV32ZBB-NEXT: [[SUB:%[0-9]+]]:_(s32) = G_SUB [[SMAX]], [[SMIN]]
90+
; RV32ZBB-NEXT: $x10 = COPY [[SUB]](s32)
91+
; RV32ZBB-NEXT: PseudoRET implicit $x10
92+
%1:_(s32) = COPY $x10
93+
%2:_(s32) = COPY $x11
94+
%3:_(s32) = G_ABDS %1, %2
95+
$x10 = COPY %3(s32)
96+
PseudoRET implicit $x10
97+
...
98+
---
99+
name: abds_i64
100+
body: |
101+
bb.0.entry:
102+
; CHECK-LABEL: name: abds_i64
103+
; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
104+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
105+
; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x10
106+
; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $x11
107+
; CHECK-NEXT: [[SUB:%[0-9]+]]:_(s32) = G_SUB [[COPY]], [[COPY2]]
108+
; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(ult), [[COPY]](s32), [[COPY2]]
109+
; CHECK-NEXT: [[SUB1:%[0-9]+]]:_(s32) = G_SUB [[COPY1]], [[COPY3]]
110+
; CHECK-NEXT: [[SUB2:%[0-9]+]]:_(s32) = G_SUB [[SUB1]], [[ICMP]]
111+
; CHECK-NEXT: [[SUB3:%[0-9]+]]:_(s32) = G_SUB [[COPY2]], [[COPY]]
112+
; CHECK-NEXT: [[ICMP1:%[0-9]+]]:_(s32) = G_ICMP intpred(ult), [[COPY2]](s32), [[COPY]]
113+
; CHECK-NEXT: [[SUB4:%[0-9]+]]:_(s32) = G_SUB [[COPY3]], [[COPY1]]
114+
; CHECK-NEXT: [[SUB5:%[0-9]+]]:_(s32) = G_SUB [[SUB4]], [[ICMP1]]
115+
; CHECK-NEXT: [[ICMP2:%[0-9]+]]:_(s32) = G_ICMP intpred(ugt), [[COPY]](s32), [[COPY2]]
116+
; CHECK-NEXT: [[ICMP3:%[0-9]+]]:_(s32) = G_ICMP intpred(sgt), [[COPY1]](s32), [[COPY3]]
117+
; CHECK-NEXT: [[ICMP4:%[0-9]+]]:_(s32) = G_ICMP intpred(eq), [[COPY1]](s32), [[COPY3]]
118+
; CHECK-NEXT: [[SELECT:%[0-9]+]]:_(s32) = G_SELECT [[ICMP4]](s32), [[ICMP2]], [[ICMP3]]
119+
; CHECK-NEXT: [[SELECT1:%[0-9]+]]:_(s32) = G_SELECT [[SELECT]](s32), [[SUB]], [[SUB3]]
120+
; CHECK-NEXT: [[SELECT2:%[0-9]+]]:_(s32) = G_SELECT [[SELECT]](s32), [[SUB2]], [[SUB5]]
121+
; CHECK-NEXT: $x10 = COPY [[SELECT1]](s32)
122+
; CHECK-NEXT: $x11 = COPY [[SELECT2]](s32)
123+
; CHECK-NEXT: PseudoRET implicit $x10, implicit $x11
124+
%0:_(s32) = COPY $x10
125+
%1:_(s32) = COPY $x11
126+
%2:_(s64) = G_MERGE_VALUES %0(s32), %1(s32)
127+
%3:_(s32) = COPY $x10
128+
%4:_(s32) = COPY $x11
129+
%5:_(s64) = G_MERGE_VALUES %3(s32), %4(s32)
130+
%6:_(s64) = G_ABDS %2, %5
131+
%7:_(s32), %8:_(s32) = G_UNMERGE_VALUES %6(s64)
132+
$x10 = COPY %7(s32)
133+
$x11 = COPY %8(s32)
134+
PseudoRET implicit $x10, implicit $x11
135+
...
136+
---
137+
name: abdu_i8
138+
body: |
139+
bb.0.entry:
140+
liveins: $x10, $x11
141+
; CHECK-LABEL: name: abdu_i8
142+
; CHECK: liveins: $x10, $x11
143+
; CHECK-NEXT: {{ $}}
144+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
145+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
146+
; CHECK-NEXT: [[ASSERT_ZEXT:%[0-9]+]]:_(s32) = G_ASSERT_ZEXT [[COPY]], 8
147+
; CHECK-NEXT: [[ASSERT_ZEXT1:%[0-9]+]]:_(s32) = G_ASSERT_ZEXT [[COPY1]], 8
148+
; CHECK-NEXT: [[SUB:%[0-9]+]]:_(s32) = G_SUB [[ASSERT_ZEXT]], [[ASSERT_ZEXT1]]
149+
; CHECK-NEXT: [[SUB1:%[0-9]+]]:_(s32) = G_SUB [[ASSERT_ZEXT1]], [[ASSERT_ZEXT]]
150+
; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(ugt), [[ASSERT_ZEXT]](s32), [[ASSERT_ZEXT1]]
151+
; CHECK-NEXT: [[SELECT:%[0-9]+]]:_(s32) = G_SELECT [[ICMP]](s32), [[SUB]], [[SUB1]]
152+
; CHECK-NEXT: $x10 = COPY [[SELECT]](s32)
153+
; CHECK-NEXT: PseudoRET implicit $x10
154+
%1:_(s32) = COPY $x10
155+
%2:_(s32) = COPY $x11
156+
%3:_(s32) = G_ASSERT_ZEXT %1, 8
157+
%4:_(s32) = G_ASSERT_ZEXT %2, 8
158+
%5:_(s8) = G_TRUNC %3(s32)
159+
%6:_(s8) = G_TRUNC %4(s32)
160+
%7:_(s8) = G_ABDU %5, %6
161+
%8:_(s32) = G_ANYEXT %7(s8)
162+
$x10 = COPY %8(s32)
163+
PseudoRET implicit $x10
164+
...
165+
---
166+
name: abdu_i16
167+
body: |
168+
bb.0.entry:
169+
liveins: $x10, $x11
170+
; CHECK-LABEL: name: abdu_i16
171+
; CHECK: liveins: $x10, $x11
172+
; CHECK-NEXT: {{ $}}
173+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
174+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
175+
; CHECK-NEXT: [[ASSERT_ZEXT:%[0-9]+]]:_(s32) = G_ASSERT_ZEXT [[COPY]], 16
176+
; CHECK-NEXT: [[ASSERT_ZEXT1:%[0-9]+]]:_(s32) = G_ASSERT_ZEXT [[COPY1]], 16
177+
; CHECK-NEXT: [[SUB:%[0-9]+]]:_(s32) = G_SUB [[ASSERT_ZEXT]], [[ASSERT_ZEXT1]]
178+
; CHECK-NEXT: [[SUB1:%[0-9]+]]:_(s32) = G_SUB [[ASSERT_ZEXT1]], [[ASSERT_ZEXT]]
179+
; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(ugt), [[ASSERT_ZEXT]](s32), [[ASSERT_ZEXT1]]
180+
; CHECK-NEXT: [[SELECT:%[0-9]+]]:_(s32) = G_SELECT [[ICMP]](s32), [[SUB]], [[SUB1]]
181+
; CHECK-NEXT: $x10 = COPY [[SELECT]](s32)
182+
; CHECK-NEXT: PseudoRET implicit $x10
183+
%1:_(s32) = COPY $x10
184+
%2:_(s32) = COPY $x11
185+
%3:_(s32) = G_ASSERT_ZEXT %1, 16
186+
%4:_(s32) = G_ASSERT_ZEXT %2, 16
187+
%5:_(s16) = G_TRUNC %3(s32)
188+
%6:_(s16) = G_TRUNC %4(s32)
189+
%7:_(s16) = G_ABDU %5, %6
190+
%8:_(s32) = G_ANYEXT %7(s16)
191+
$x10 = COPY %8(s32)
192+
PseudoRET implicit $x10
193+
...
194+
---
195+
name: abdu_i32
196+
body: |
197+
bb.0.entry:
198+
liveins: $x10, $x11
199+
; RV32I-LABEL: name: abdu_i32
200+
; RV32I: liveins: $x10, $x11
201+
; RV32I-NEXT: {{ $}}
202+
; RV32I-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
203+
; RV32I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
204+
; RV32I-NEXT: [[SUB:%[0-9]+]]:_(s32) = G_SUB [[COPY]], [[COPY1]]
205+
; RV32I-NEXT: [[SUB1:%[0-9]+]]:_(s32) = G_SUB [[COPY1]], [[COPY]]
206+
; RV32I-NEXT: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(ugt), [[COPY]](s32), [[COPY1]]
207+
; RV32I-NEXT: [[SELECT:%[0-9]+]]:_(s32) = G_SELECT [[ICMP]](s32), [[SUB]], [[SUB1]]
208+
; RV32I-NEXT: $x10 = COPY [[SELECT]](s32)
209+
; RV32I-NEXT: PseudoRET implicit $x10
210+
;
211+
; RV32ZBB-LABEL: name: abdu_i32
212+
; RV32ZBB: liveins: $x10, $x11
213+
; RV32ZBB-NEXT: {{ $}}
214+
; RV32ZBB-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
215+
; RV32ZBB-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
216+
; RV32ZBB-NEXT: [[UMAX:%[0-9]+]]:_(s32) = G_UMAX [[COPY]], [[COPY1]]
217+
; RV32ZBB-NEXT: [[UMIN:%[0-9]+]]:_(s32) = G_UMIN [[COPY]], [[COPY1]]
218+
; RV32ZBB-NEXT: [[SUB:%[0-9]+]]:_(s32) = G_SUB [[UMAX]], [[UMIN]]
219+
; RV32ZBB-NEXT: $x10 = COPY [[SUB]](s32)
220+
; RV32ZBB-NEXT: PseudoRET implicit $x10
221+
%1:_(s32) = COPY $x10
222+
%2:_(s32) = COPY $x11
223+
%3:_(s32) = G_ABDU %1, %2
224+
$x10 = COPY %3(s32)
225+
PseudoRET implicit $x10
226+
...
227+
---
228+
name: abdu_i64
229+
body: |
230+
bb.0.entry:
231+
; CHECK-LABEL: name: abdu_i64
232+
; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
233+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
234+
; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x10
235+
; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $x11
236+
; CHECK-NEXT: [[SUB:%[0-9]+]]:_(s32) = G_SUB [[COPY]], [[COPY2]]
237+
; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(ult), [[COPY]](s32), [[COPY2]]
238+
; CHECK-NEXT: [[SUB1:%[0-9]+]]:_(s32) = G_SUB [[COPY1]], [[COPY3]]
239+
; CHECK-NEXT: [[SUB2:%[0-9]+]]:_(s32) = G_SUB [[SUB1]], [[ICMP]]
240+
; CHECK-NEXT: [[SUB3:%[0-9]+]]:_(s32) = G_SUB [[COPY2]], [[COPY]]
241+
; CHECK-NEXT: [[ICMP1:%[0-9]+]]:_(s32) = G_ICMP intpred(ult), [[COPY2]](s32), [[COPY]]
242+
; CHECK-NEXT: [[SUB4:%[0-9]+]]:_(s32) = G_SUB [[COPY3]], [[COPY1]]
243+
; CHECK-NEXT: [[SUB5:%[0-9]+]]:_(s32) = G_SUB [[SUB4]], [[ICMP1]]
244+
; CHECK-NEXT: [[ICMP2:%[0-9]+]]:_(s32) = G_ICMP intpred(ugt), [[COPY]](s32), [[COPY2]]
245+
; CHECK-NEXT: [[ICMP3:%[0-9]+]]:_(s32) = G_ICMP intpred(ugt), [[COPY1]](s32), [[COPY3]]
246+
; CHECK-NEXT: [[ICMP4:%[0-9]+]]:_(s32) = G_ICMP intpred(eq), [[COPY1]](s32), [[COPY3]]
247+
; CHECK-NEXT: [[SELECT:%[0-9]+]]:_(s32) = G_SELECT [[ICMP4]](s32), [[ICMP2]], [[ICMP3]]
248+
; CHECK-NEXT: [[SELECT1:%[0-9]+]]:_(s32) = G_SELECT [[SELECT]](s32), [[SUB]], [[SUB3]]
249+
; CHECK-NEXT: [[SELECT2:%[0-9]+]]:_(s32) = G_SELECT [[SELECT]](s32), [[SUB2]], [[SUB5]]
250+
; CHECK-NEXT: $x10 = COPY [[SELECT1]](s32)
251+
; CHECK-NEXT: $x11 = COPY [[SELECT2]](s32)
252+
; CHECK-NEXT: PseudoRET implicit $x10, implicit $x11
253+
%0:_(s32) = COPY $x10
254+
%1:_(s32) = COPY $x11
255+
%2:_(s64) = G_MERGE_VALUES %0(s32), %1(s32)
256+
%3:_(s32) = COPY $x10
257+
%4:_(s32) = COPY $x11
258+
%5:_(s64) = G_MERGE_VALUES %3(s32), %4(s32)
259+
%6:_(s64) = G_ABDU %2, %5
260+
%7:_(s32), %8:_(s32) = G_UNMERGE_VALUES %6(s64)
261+
$x10 = COPY %7(s32)
262+
$x11 = COPY %8(s32)
263+
PseudoRET implicit $x10, implicit $x11
264+
...

0 commit comments

Comments
 (0)