-
Notifications
You must be signed in to change notification settings - Fork 14.9k
[RISCV][GISel] Lower G_SADDE #156865
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
[RISCV][GISel] Lower G_SADDE #156865
Conversation
@llvm/pr-subscribers-llvm-globalisel Author: woruyu (woruyu) ChangesSummaryTry to implemente Lower G_SADDE in LegalizerHelper::lower Patch is 22.73 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/156865.diff 6 Files Affected:
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
index aef7891af8f93..aa93c884ac76c 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
@@ -510,6 +510,7 @@ class LegalizerHelper {
LLVM_ABI LegalizeResult lowerExtract(MachineInstr &MI);
LLVM_ABI LegalizeResult lowerInsert(MachineInstr &MI);
LLVM_ABI LegalizeResult lowerSADDO_SSUBO(MachineInstr &MI);
+ LLVM_ABI LegalizeResult lowerSADDE(MachineInstr &MI);
LLVM_ABI LegalizeResult lowerAddSubSatToMinMax(MachineInstr &MI);
LLVM_ABI LegalizeResult lowerAddSubSatToAddoSubo(MachineInstr &MI);
LLVM_ABI LegalizeResult lowerShlSat(MachineInstr &MI);
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index 40e6b1bf81bd0..abab4a61ea127 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -4447,6 +4447,8 @@ LegalizerHelper::lower(MachineInstr &MI, unsigned TypeIdx, LLT LowerHintTy) {
case TargetOpcode::G_SADDO:
case TargetOpcode::G_SSUBO:
return lowerSADDO_SSUBO(MI);
+ case TargetOpcode::G_SADDE:
+ return lowerSADDE(MI);
case TargetOpcode::G_UMULH:
case TargetOpcode::G_SMULH:
return lowerSMULH_UMULH(MI);
@@ -9288,6 +9290,40 @@ LegalizerHelper::lowerSADDO_SSUBO(MachineInstr &MI) {
return Legalized;
}
+LegalizerHelper::LegalizeResult LegalizerHelper::lowerSADDE(MachineInstr &MI) {
+ auto [Res, OvOut, LHS, RHS, CarryIn] = MI.getFirst5Regs();
+ const LLT Ty = MRI.getType(Res);
+ const LLT BoolTy = MRI.getType(OvOut);
+
+ Register NewRes = MRI.cloneVirtualRegister(Res);
+
+ // Step 1: tmp = LHS + RHS
+ auto Tmp = MIRBuilder.buildAdd(Ty, LHS, RHS);
+
+ // ov0 = (tmp < lhs) XOR (rhs < 0)
+ auto TmpLtLHS = MIRBuilder.buildICmp(CmpInst::ICMP_SLT, BoolTy, Tmp, LHS);
+ auto Zero = MIRBuilder.buildConstant(Ty, 0);
+ auto RHSLt0 = MIRBuilder.buildICmp(CmpInst::ICMP_SLT, BoolTy, RHS, Zero);
+ auto Ov0 = MIRBuilder.buildXor(BoolTy, TmpLtLHS, RHSLt0);
+
+ // Step 2: sum = tmp + zext(CarryIn)
+ auto CarryInZ = MIRBuilder.buildZExt(Ty, CarryIn);
+ MIRBuilder.buildAdd(NewRes, Tmp, CarryInZ);
+
+ // ov1 = CarryIn & (sum < tmp)
+ auto SumLtTmp = MIRBuilder.buildICmp(CmpInst::ICMP_SLT, BoolTy, NewRes, Tmp);
+ auto Ov1 = MIRBuilder.buildAnd(BoolTy, SumLtTmp, CarryIn);
+
+ // ov = ov0 | ov1
+ auto Ov = MIRBuilder.buildOr(BoolTy, Ov0, Ov1);
+
+ MIRBuilder.buildCopy(OvOut, Ov);
+ MIRBuilder.buildCopy(Res, NewRes);
+
+ MI.eraseFromParent();
+ return Legalized;
+}
+
LegalizerHelper::LegalizeResult
LegalizerHelper::lowerAddSubSatToMinMax(MachineInstr &MI) {
auto [Res, LHS, RHS] = MI.getFirst3Regs();
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
index d908e5f482e2b..0966db9a754d3 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
@@ -151,7 +151,7 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
getActionDefinitionsBuilder(
{G_UADDE, G_UADDO, G_USUBE, G_USUBO}).lower();
- getActionDefinitionsBuilder({G_SADDO, G_SSUBO}).minScalar(0, sXLen).lower();
+ getActionDefinitionsBuilder({G_SADDO,G_SADDE, G_SSUBO}).minScalar(0, sXLen).lower();
// TODO: Use Vector Single-Width Saturating Instructions for vector types.
getActionDefinitionsBuilder(
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir
index 8edc7e4f8b57c..2cf5c3b3c5026 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir
@@ -406,8 +406,9 @@
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
# DEBUG-NEXT: G_SADDE (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
-# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
-# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
+# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
+# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
+# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
# DEBUG-NEXT: G_SSUBO (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-sadde-rv32.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-sadde-rv32.mir
new file mode 100644
index 0000000000000..7729cc6e8c76e
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-sadde-rv32.mir
@@ -0,0 +1,179 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv32 -run-pass=legalizer %s -o - | FileCheck %s
+
+---
+name: sadde_i8
+body: |
+ bb.1:
+ liveins: $x10, $x11, $x12
+
+ ; CHECK-LABEL: name: sadde_i8
+ ; CHECK: liveins: $x10, $x11, $x12
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x12
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[COPY]], [[C]](s32)
+ ; CHECK-NEXT: [[ASHR:%[0-9]+]]:_(s32) = G_ASHR [[SHL]], [[C]](s32)
+ ; CHECK-NEXT: [[SHL1:%[0-9]+]]:_(s32) = G_SHL [[COPY1]], [[C]](s32)
+ ; CHECK-NEXT: [[ASHR1:%[0-9]+]]:_(s32) = G_ASHR [[SHL1]], [[C]](s32)
+ ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[ASHR]], [[ASHR1]]
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY2]], [[C1]]
+ ; CHECK-NEXT: [[ADD1:%[0-9]+]]:_(s32) = G_ADD [[ADD]], [[AND]]
+ ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY [[ADD1]](s32)
+ ; CHECK-NEXT: [[SHL2:%[0-9]+]]:_(s32) = G_SHL [[COPY3]], [[C]](s32)
+ ; CHECK-NEXT: [[ASHR2:%[0-9]+]]:_(s32) = G_ASHR [[SHL2]], [[C]](s32)
+ ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(ne), [[COPY3]](s32), [[ASHR2]]
+ ; CHECK-NEXT: $x10 = COPY [[COPY3]](s32)
+ ; CHECK-NEXT: $x11 = COPY [[ICMP]](s32)
+ ; CHECK-NEXT: PseudoRET implicit $x10, implicit $x11
+ %0:_(s32) = COPY $x10
+ %1:_(s8) = G_TRUNC %0(s32)
+ %2:_(s32) = COPY $x11
+ %3:_(s8) = G_TRUNC %2(s32)
+ %4:_(s32) = COPY $x12
+ %5:_(s1) = G_TRUNC %4(s32)
+ %6:_(s8), %7:_(s1) = G_SADDE %1, %3, %5
+ %8:_(s32) = G_ANYEXT %6(s8)
+ %9:_(s32) = G_ANYEXT %7(s1)
+ $x10 = COPY %8(s32)
+ $x11 = COPY %9(s32)
+ PseudoRET implicit $x10, implicit $x11
+
+...
+---
+name: sadde_i16
+body: |
+ bb.1:
+ liveins: $x10, $x11, $x12
+
+ ; CHECK-LABEL: name: sadde_i16
+ ; CHECK: liveins: $x10, $x11, $x12
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x12
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[COPY]], [[C]](s32)
+ ; CHECK-NEXT: [[ASHR:%[0-9]+]]:_(s32) = G_ASHR [[SHL]], [[C]](s32)
+ ; CHECK-NEXT: [[SHL1:%[0-9]+]]:_(s32) = G_SHL [[COPY1]], [[C]](s32)
+ ; CHECK-NEXT: [[ASHR1:%[0-9]+]]:_(s32) = G_ASHR [[SHL1]], [[C]](s32)
+ ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[ASHR]], [[ASHR1]]
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY2]], [[C1]]
+ ; CHECK-NEXT: [[ADD1:%[0-9]+]]:_(s32) = G_ADD [[ADD]], [[AND]]
+ ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY [[ADD1]](s32)
+ ; CHECK-NEXT: [[SHL2:%[0-9]+]]:_(s32) = G_SHL [[COPY3]], [[C]](s32)
+ ; CHECK-NEXT: [[ASHR2:%[0-9]+]]:_(s32) = G_ASHR [[SHL2]], [[C]](s32)
+ ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(ne), [[COPY3]](s32), [[ASHR2]]
+ ; CHECK-NEXT: $x10 = COPY [[COPY3]](s32)
+ ; CHECK-NEXT: $x11 = COPY [[ICMP]](s32)
+ ; CHECK-NEXT: PseudoRET implicit $x10, implicit $x11
+ %0:_(s32) = COPY $x10
+ %1:_(s16) = G_TRUNC %0(s32)
+ %2:_(s32) = COPY $x11
+ %3:_(s16) = G_TRUNC %2(s32)
+ %4:_(s32) = COPY $x12
+ %5:_(s1) = G_TRUNC %4(s32)
+ %6:_(s16), %7:_(s1) = G_SADDE %1, %3, %5
+ %8:_(s32) = G_ANYEXT %6(s16)
+ %9:_(s32) = G_ANYEXT %7(s1)
+ $x10 = COPY %8(s32)
+ $x11 = COPY %9(s32)
+ PseudoRET implicit $x10, implicit $x11
+
+...
+---
+name: sadde_i32
+body: |
+ bb.1:
+ liveins: $x10, $x11, $x12
+
+ ; CHECK-LABEL: name: sadde_i32
+ ; CHECK: liveins: $x10, $x11, $x12
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x12
+ ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[COPY]], [[COPY1]]
+ ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(slt), [[ADD]](s32), [[COPY]]
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: [[ICMP1:%[0-9]+]]:_(s32) = G_ICMP intpred(slt), [[COPY1]](s32), [[C]]
+ ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(s32) = G_XOR [[ICMP]], [[ICMP1]]
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY2]], [[C1]]
+ ; CHECK-NEXT: [[ADD1:%[0-9]+]]:_(s32) = G_ADD [[ADD]], [[AND]]
+ ; CHECK-NEXT: [[ICMP2:%[0-9]+]]:_(s32) = G_ICMP intpred(slt), [[ADD1]](s32), [[ADD]]
+ ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[ICMP2]], [[COPY2]]
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = G_OR [[XOR]], [[AND1]]
+ ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY [[ADD1]](s32)
+ ; CHECK-NEXT: $x10 = COPY [[COPY3]](s32)
+ ; CHECK-NEXT: $x11 = COPY [[OR]](s32)
+ ; CHECK-NEXT: PseudoRET implicit $x10, implicit $x11
+ %0:_(s32) = COPY $x10
+ %1:_(s32) = COPY $x11
+ %2:_(s32) = COPY $x12
+ %3:_(s1) = G_TRUNC %2(s32)
+ %4:_(s32), %5:_(s1) = G_SADDE %0, %1, %3
+ %6:_(s32) = G_ANYEXT %5(s1)
+ $x10 = COPY %4(s32)
+ $x11 = COPY %6(s32)
+ PseudoRET implicit $x10, implicit $x11
+
+...
+---
+name: sadde_i64
+body: |
+ bb.1:
+ liveins: $x10, $x11, $x12, $x13, $x14
+
+ ; CHECK-LABEL: name: sadde_i64
+ ; CHECK: liveins: $x10, $x11, $x12, $x13, $x14
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x12
+ ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $x13
+ ; CHECK-NEXT: [[COPY4:%[0-9]+]]:_(s32) = COPY $x14
+ ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[COPY]], [[COPY2]]
+ ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(slt), [[ADD]](s32), [[COPY]]
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: [[ICMP1:%[0-9]+]]:_(s32) = G_ICMP intpred(slt), [[COPY2]](s32), [[C]]
+ ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(s32) = G_XOR [[ICMP]], [[ICMP1]]
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY4]], [[C1]]
+ ; CHECK-NEXT: [[ADD1:%[0-9]+]]:_(s32) = G_ADD [[ADD]], [[AND]]
+ ; CHECK-NEXT: [[ICMP2:%[0-9]+]]:_(s32) = G_ICMP intpred(slt), [[ADD1]](s32), [[ADD]]
+ ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[ICMP2]], [[COPY4]]
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = G_OR [[XOR]], [[AND1]]
+ ; CHECK-NEXT: [[COPY5:%[0-9]+]]:_(s32) = COPY [[ADD1]](s32)
+ ; CHECK-NEXT: [[ADD2:%[0-9]+]]:_(s32) = G_ADD [[COPY1]], [[COPY3]]
+ ; CHECK-NEXT: [[ICMP3:%[0-9]+]]:_(s32) = G_ICMP intpred(slt), [[ADD2]](s32), [[COPY1]]
+ ; CHECK-NEXT: [[ICMP4:%[0-9]+]]:_(s32) = G_ICMP intpred(slt), [[COPY3]](s32), [[C]]
+ ; CHECK-NEXT: [[XOR1:%[0-9]+]]:_(s32) = G_XOR [[ICMP3]], [[ICMP4]]
+ ; CHECK-NEXT: [[ADD3:%[0-9]+]]:_(s32) = G_ADD [[ADD2]], [[OR]]
+ ; CHECK-NEXT: [[ICMP5:%[0-9]+]]:_(s32) = G_ICMP intpred(slt), [[ADD3]](s32), [[ADD2]]
+ ; CHECK-NEXT: [[AND2:%[0-9]+]]:_(s32) = G_AND [[ICMP5]], [[OR]]
+ ; CHECK-NEXT: [[OR1:%[0-9]+]]:_(s32) = G_OR [[XOR1]], [[AND2]]
+ ; CHECK-NEXT: [[COPY6:%[0-9]+]]:_(s32) = COPY [[ADD3]](s32)
+ ; CHECK-NEXT: $x10 = COPY [[COPY5]](s32)
+ ; CHECK-NEXT: $x11 = COPY [[COPY6]](s32)
+ ; CHECK-NEXT: $x12 = COPY [[OR1]](s32)
+ ; CHECK-NEXT: PseudoRET implicit $x10, implicit $x11, implicit $x12
+ %0:_(s32) = COPY $x10
+ %1:_(s32) = COPY $x11
+ %2:_(s32) = COPY $x12
+ %3:_(s32) = COPY $x13
+ %4:_(s32) = COPY $x14
+ %5:_(s1) = G_TRUNC %4(s32)
+ %6:_(s32), %7:_(s1) = G_SADDE %0, %2, %5
+ %8:_(s32), %9:_(s1) = G_SADDE %1, %3, %7
+ %10:_(s32) = G_ANYEXT %9(s1)
+ $x10 = COPY %6(s32)
+ $x11 = COPY %8(s32)
+ $x12 = COPY %10(s32)
+
+ PseudoRET implicit $x10, implicit $x11, implicit $x12
+...
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-sadde-rv64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-sadde-rv64.mir
new file mode 100644
index 0000000000000..70b5c144f3871
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-sadde-rv64.mir
@@ -0,0 +1,217 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv64 -run-pass=legalizer %s -o - | FileCheck %s
+
+---
+name: sadde_i8
+body: |
+ bb.1:
+ liveins: $x10, $x11, $x12
+
+ ; CHECK-LABEL: name: sadde_i8
+ ; CHECK: liveins: $x10, $x11, $x12
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x12
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 56
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[COPY]], [[C]](s64)
+ ; CHECK-NEXT: [[ASHR:%[0-9]+]]:_(s64) = G_ASHR [[SHL]], [[C]](s64)
+ ; CHECK-NEXT: [[SHL1:%[0-9]+]]:_(s64) = G_SHL [[COPY1]], [[C]](s64)
+ ; CHECK-NEXT: [[ASHR1:%[0-9]+]]:_(s64) = G_ASHR [[SHL1]], [[C]](s64)
+ ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[ASHR]], [[ASHR1]]
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[COPY2]], [[C1]]
+ ; CHECK-NEXT: [[ADD1:%[0-9]+]]:_(s64) = G_ADD [[ADD]], [[AND]]
+ ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY [[ADD1]](s64)
+ ; CHECK-NEXT: [[SHL2:%[0-9]+]]:_(s64) = G_SHL [[COPY3]], [[C]](s64)
+ ; CHECK-NEXT: [[ASHR2:%[0-9]+]]:_(s64) = G_ASHR [[SHL2]], [[C]](s64)
+ ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s64) = G_ICMP intpred(ne), [[COPY3]](s64), [[ASHR2]]
+ ; CHECK-NEXT: $x10 = COPY [[COPY3]](s64)
+ ; CHECK-NEXT: $x11 = COPY [[ICMP]](s64)
+ ; CHECK-NEXT: PseudoRET implicit $x10, implicit $x11
+ %0:_(s64) = COPY $x10
+ %1:_(s8) = G_TRUNC %0(s64)
+ %2:_(s64) = COPY $x11
+ %3:_(s8) = G_TRUNC %2(s64)
+ %4:_(s64) = COPY $x12
+ %5:_(s1) = G_TRUNC %4(s64)
+ %6:_(s8), %7:_(s1) = G_SADDE %1, %3, %5
+ %8:_(s64) = G_ANYEXT %6(s8)
+ %9:_(s64) = G_ANYEXT %7(s1)
+ $x10 = COPY %8(s64)
+ $x11 = COPY %9(s64)
+ PseudoRET implicit $x10, implicit $x11
+
+...
+---
+name: sadde_i16
+body: |
+ bb.1:
+ liveins: $x10, $x11, $x12
+
+ ; CHECK-LABEL: name: sadde_i16
+ ; CHECK: liveins: $x10, $x11, $x12
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x12
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 48
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[COPY]], [[C]](s64)
+ ; CHECK-NEXT: [[ASHR:%[0-9]+]]:_(s64) = G_ASHR [[SHL]], [[C]](s64)
+ ; CHECK-NEXT: [[SHL1:%[0-9]+]]:_(s64) = G_SHL [[COPY1]], [[C]](s64)
+ ; CHECK-NEXT: [[ASHR1:%[0-9]+]]:_(s64) = G_ASHR [[SHL1]], [[C]](s64)
+ ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[ASHR]], [[ASHR1]]
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[COPY2]], [[C1]]
+ ; CHECK-NEXT: [[ADD1:%[0-9]+]]:_(s64) = G_ADD [[ADD]], [[AND]]
+ ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY [[ADD1]](s64)
+ ; CHECK-NEXT: [[SHL2:%[0-9]+]]:_(s64) = G_SHL [[COPY3]], [[C]](s64)
+ ; CHECK-NEXT: [[ASHR2:%[0-9]+]]:_(s64) = G_ASHR [[SHL2]], [[C]](s64)
+ ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s64) = G_ICMP intpred(ne), [[COPY3]](s64), [[ASHR2]]
+ ; CHECK-NEXT: $x10 = COPY [[COPY3]](s64)
+ ; CHECK-NEXT: $x11 = COPY [[ICMP]](s64)
+ ; CHECK-NEXT: PseudoRET implicit $x10, implicit $x11
+ %0:_(s64) = COPY $x10
+ %1:_(s16) = G_TRUNC %0(s64)
+ %2:_(s64) = COPY $x11
+ %3:_(s16) = G_TRUNC %2(s64)
+ %4:_(s64) = COPY $x12
+ %5:_(s1) = G_TRUNC %4(s64)
+ %6:_(s16), %7:_(s1) = G_SADDE %1, %3, %5
+ %8:_(s64) = G_ANYEXT %6(s16)
+ %9:_(s64) = G_ANYEXT %7(s1)
+ $x10 = COPY %8(s64)
+ $x11 = COPY %9(s64)
+ PseudoRET implicit $x10, implicit $x11
+
+...
+---
+name: sadde_i32
+body: |
+ bb.1:
+ liveins: $x10, $x11, $x12
+
+ ; CHECK-LABEL: name: sadde_i32
+ ; CHECK: liveins: $x10, $x11, $x12
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x12
+ ; CHECK-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY]], 32
+ ; CHECK-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY1]], 32
+ ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[SEXT_INREG]], [[SEXT_INREG1]]
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[COPY2]], [[C]]
+ ; CHECK-NEXT: [[ADD1:%[0-9]+]]:_(s64) = G_ADD [[ADD]], [[AND]]
+ ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY [[ADD1]](s64)
+ ; CHECK-NEXT: [[SEXT_INREG2:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY3]], 32
+ ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s64) = G_ICMP intpred(ne), [[COPY3]](s64), [[SEXT_INREG2]]
+ ; CHECK-NEXT: $x10 = COPY [[COPY3]](s64)
+ ; CHECK-NEXT: $x11 = COPY [[ICMP]](s64)
+ ; CHECK-NEXT: PseudoRET implicit $x10, implicit $x11
+ %0:_(s64) = COPY $x10
+ %1:_(s32) = G_TRUNC %0(s64)
+ %2:_(s64) = COPY $x11
+ %3:_(s32) = G_TRUNC %2(s64)
+ %4:_(s64) = COPY $x12
+ %5:_(s1) = G_TRUNC %4(s64)
+ %6:_(s32), %7:_(s1) = G_SADDE %1, %3, %5
+ %8:_(s64) = G_ANYEXT %6(s32)
+ %9:_(s64) = G_ANYEXT %7(s1)
+ $x10 = COPY %8(s64)
+ $x11 = COPY %9(s64)
+ PseudoRET implicit $x10, implicit $x11
+
+...
+---
+name: sadde_i64
+body: |
+ bb.1:
+ liveins: $x10, $x11, $x12
+
+ ; CHECK-LABEL: name: sadde_i64
+ ; CHECK: liveins: $x10, $x11, $x12
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x12
+ ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[COPY]], [[COPY1]]
+ ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s64) = G_ICMP intpred(slt), [[ADD]](s64), [[COPY]]
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
+ ; CHECK-NEXT: [[ICMP1:%[0-9]+]]:_(s64) = G_ICMP intpred(slt), [[COPY1]](s64), [[C]]
+ ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(s64) = G_XOR [[ICMP]], [[ICMP1]]
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[COPY2]], [[C1]]
+ ; CHECK-NEXT: [[ADD1:%[0-9]+]]:_(s64) = G_ADD [[ADD]], [[AND]]
+ ; CHECK-NEXT: [[ICMP2:%[0-9]+]]:_(s64) = G_ICMP intpred(slt), [[ADD1]](s64), [[ADD]]
+ ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s64) = G_AND [[ICMP2]], [[COPY2]]
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s64) = G_OR [[XOR]], [[AND1]]
+ ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY [[ADD1]](s64)
+ ; CHECK-NEXT: $x10 = COPY [[COPY3]](s64)
+ ; CHECK-NEXT: $x11 = COPY [[OR]](s64)
+ ; CHECK-NEXT: PseudoRET implicit $x10, implicit $x11
+ %0:_(s64) = COPY $x10
+ %1:_(s64) = COPY $x11
+ %2:_(s64) = COPY $x12
+ %3:_(s1) = G_TRUNC %2(s64)
+ %4:_(s64), %5:_(s1) = G_SADDE %0, %1, %3
+ %6:_(s64) = G_ANYEXT %5(s1)
+ $x1...
[truncated]
|
@llvm/pr-subscribers-backend-risc-v Author: woruyu (woruyu) ChangesSummaryTry to implemente Lower G_SADDE in LegalizerHelper::lower Patch is 22.73 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/156865.diff 6 Files Affected:
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
index aef7891af8f93..aa93c884ac76c 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
@@ -510,6 +510,7 @@ class LegalizerHelper {
LLVM_ABI LegalizeResult lowerExtract(MachineInstr &MI);
LLVM_ABI LegalizeResult lowerInsert(MachineInstr &MI);
LLVM_ABI LegalizeResult lowerSADDO_SSUBO(MachineInstr &MI);
+ LLVM_ABI LegalizeResult lowerSADDE(MachineInstr &MI);
LLVM_ABI LegalizeResult lowerAddSubSatToMinMax(MachineInstr &MI);
LLVM_ABI LegalizeResult lowerAddSubSatToAddoSubo(MachineInstr &MI);
LLVM_ABI LegalizeResult lowerShlSat(MachineInstr &MI);
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index 40e6b1bf81bd0..abab4a61ea127 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -4447,6 +4447,8 @@ LegalizerHelper::lower(MachineInstr &MI, unsigned TypeIdx, LLT LowerHintTy) {
case TargetOpcode::G_SADDO:
case TargetOpcode::G_SSUBO:
return lowerSADDO_SSUBO(MI);
+ case TargetOpcode::G_SADDE:
+ return lowerSADDE(MI);
case TargetOpcode::G_UMULH:
case TargetOpcode::G_SMULH:
return lowerSMULH_UMULH(MI);
@@ -9288,6 +9290,40 @@ LegalizerHelper::lowerSADDO_SSUBO(MachineInstr &MI) {
return Legalized;
}
+LegalizerHelper::LegalizeResult LegalizerHelper::lowerSADDE(MachineInstr &MI) {
+ auto [Res, OvOut, LHS, RHS, CarryIn] = MI.getFirst5Regs();
+ const LLT Ty = MRI.getType(Res);
+ const LLT BoolTy = MRI.getType(OvOut);
+
+ Register NewRes = MRI.cloneVirtualRegister(Res);
+
+ // Step 1: tmp = LHS + RHS
+ auto Tmp = MIRBuilder.buildAdd(Ty, LHS, RHS);
+
+ // ov0 = (tmp < lhs) XOR (rhs < 0)
+ auto TmpLtLHS = MIRBuilder.buildICmp(CmpInst::ICMP_SLT, BoolTy, Tmp, LHS);
+ auto Zero = MIRBuilder.buildConstant(Ty, 0);
+ auto RHSLt0 = MIRBuilder.buildICmp(CmpInst::ICMP_SLT, BoolTy, RHS, Zero);
+ auto Ov0 = MIRBuilder.buildXor(BoolTy, TmpLtLHS, RHSLt0);
+
+ // Step 2: sum = tmp + zext(CarryIn)
+ auto CarryInZ = MIRBuilder.buildZExt(Ty, CarryIn);
+ MIRBuilder.buildAdd(NewRes, Tmp, CarryInZ);
+
+ // ov1 = CarryIn & (sum < tmp)
+ auto SumLtTmp = MIRBuilder.buildICmp(CmpInst::ICMP_SLT, BoolTy, NewRes, Tmp);
+ auto Ov1 = MIRBuilder.buildAnd(BoolTy, SumLtTmp, CarryIn);
+
+ // ov = ov0 | ov1
+ auto Ov = MIRBuilder.buildOr(BoolTy, Ov0, Ov1);
+
+ MIRBuilder.buildCopy(OvOut, Ov);
+ MIRBuilder.buildCopy(Res, NewRes);
+
+ MI.eraseFromParent();
+ return Legalized;
+}
+
LegalizerHelper::LegalizeResult
LegalizerHelper::lowerAddSubSatToMinMax(MachineInstr &MI) {
auto [Res, LHS, RHS] = MI.getFirst3Regs();
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
index d908e5f482e2b..0966db9a754d3 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
@@ -151,7 +151,7 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
getActionDefinitionsBuilder(
{G_UADDE, G_UADDO, G_USUBE, G_USUBO}).lower();
- getActionDefinitionsBuilder({G_SADDO, G_SSUBO}).minScalar(0, sXLen).lower();
+ getActionDefinitionsBuilder({G_SADDO,G_SADDE, G_SSUBO}).minScalar(0, sXLen).lower();
// TODO: Use Vector Single-Width Saturating Instructions for vector types.
getActionDefinitionsBuilder(
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir
index 8edc7e4f8b57c..2cf5c3b3c5026 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir
@@ -406,8 +406,9 @@
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
# DEBUG-NEXT: G_SADDE (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
-# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
-# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
+# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
+# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
+# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
# DEBUG-NEXT: G_SSUBO (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-sadde-rv32.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-sadde-rv32.mir
new file mode 100644
index 0000000000000..7729cc6e8c76e
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-sadde-rv32.mir
@@ -0,0 +1,179 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv32 -run-pass=legalizer %s -o - | FileCheck %s
+
+---
+name: sadde_i8
+body: |
+ bb.1:
+ liveins: $x10, $x11, $x12
+
+ ; CHECK-LABEL: name: sadde_i8
+ ; CHECK: liveins: $x10, $x11, $x12
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x12
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[COPY]], [[C]](s32)
+ ; CHECK-NEXT: [[ASHR:%[0-9]+]]:_(s32) = G_ASHR [[SHL]], [[C]](s32)
+ ; CHECK-NEXT: [[SHL1:%[0-9]+]]:_(s32) = G_SHL [[COPY1]], [[C]](s32)
+ ; CHECK-NEXT: [[ASHR1:%[0-9]+]]:_(s32) = G_ASHR [[SHL1]], [[C]](s32)
+ ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[ASHR]], [[ASHR1]]
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY2]], [[C1]]
+ ; CHECK-NEXT: [[ADD1:%[0-9]+]]:_(s32) = G_ADD [[ADD]], [[AND]]
+ ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY [[ADD1]](s32)
+ ; CHECK-NEXT: [[SHL2:%[0-9]+]]:_(s32) = G_SHL [[COPY3]], [[C]](s32)
+ ; CHECK-NEXT: [[ASHR2:%[0-9]+]]:_(s32) = G_ASHR [[SHL2]], [[C]](s32)
+ ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(ne), [[COPY3]](s32), [[ASHR2]]
+ ; CHECK-NEXT: $x10 = COPY [[COPY3]](s32)
+ ; CHECK-NEXT: $x11 = COPY [[ICMP]](s32)
+ ; CHECK-NEXT: PseudoRET implicit $x10, implicit $x11
+ %0:_(s32) = COPY $x10
+ %1:_(s8) = G_TRUNC %0(s32)
+ %2:_(s32) = COPY $x11
+ %3:_(s8) = G_TRUNC %2(s32)
+ %4:_(s32) = COPY $x12
+ %5:_(s1) = G_TRUNC %4(s32)
+ %6:_(s8), %7:_(s1) = G_SADDE %1, %3, %5
+ %8:_(s32) = G_ANYEXT %6(s8)
+ %9:_(s32) = G_ANYEXT %7(s1)
+ $x10 = COPY %8(s32)
+ $x11 = COPY %9(s32)
+ PseudoRET implicit $x10, implicit $x11
+
+...
+---
+name: sadde_i16
+body: |
+ bb.1:
+ liveins: $x10, $x11, $x12
+
+ ; CHECK-LABEL: name: sadde_i16
+ ; CHECK: liveins: $x10, $x11, $x12
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x12
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[COPY]], [[C]](s32)
+ ; CHECK-NEXT: [[ASHR:%[0-9]+]]:_(s32) = G_ASHR [[SHL]], [[C]](s32)
+ ; CHECK-NEXT: [[SHL1:%[0-9]+]]:_(s32) = G_SHL [[COPY1]], [[C]](s32)
+ ; CHECK-NEXT: [[ASHR1:%[0-9]+]]:_(s32) = G_ASHR [[SHL1]], [[C]](s32)
+ ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[ASHR]], [[ASHR1]]
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY2]], [[C1]]
+ ; CHECK-NEXT: [[ADD1:%[0-9]+]]:_(s32) = G_ADD [[ADD]], [[AND]]
+ ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY [[ADD1]](s32)
+ ; CHECK-NEXT: [[SHL2:%[0-9]+]]:_(s32) = G_SHL [[COPY3]], [[C]](s32)
+ ; CHECK-NEXT: [[ASHR2:%[0-9]+]]:_(s32) = G_ASHR [[SHL2]], [[C]](s32)
+ ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(ne), [[COPY3]](s32), [[ASHR2]]
+ ; CHECK-NEXT: $x10 = COPY [[COPY3]](s32)
+ ; CHECK-NEXT: $x11 = COPY [[ICMP]](s32)
+ ; CHECK-NEXT: PseudoRET implicit $x10, implicit $x11
+ %0:_(s32) = COPY $x10
+ %1:_(s16) = G_TRUNC %0(s32)
+ %2:_(s32) = COPY $x11
+ %3:_(s16) = G_TRUNC %2(s32)
+ %4:_(s32) = COPY $x12
+ %5:_(s1) = G_TRUNC %4(s32)
+ %6:_(s16), %7:_(s1) = G_SADDE %1, %3, %5
+ %8:_(s32) = G_ANYEXT %6(s16)
+ %9:_(s32) = G_ANYEXT %7(s1)
+ $x10 = COPY %8(s32)
+ $x11 = COPY %9(s32)
+ PseudoRET implicit $x10, implicit $x11
+
+...
+---
+name: sadde_i32
+body: |
+ bb.1:
+ liveins: $x10, $x11, $x12
+
+ ; CHECK-LABEL: name: sadde_i32
+ ; CHECK: liveins: $x10, $x11, $x12
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x12
+ ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[COPY]], [[COPY1]]
+ ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(slt), [[ADD]](s32), [[COPY]]
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: [[ICMP1:%[0-9]+]]:_(s32) = G_ICMP intpred(slt), [[COPY1]](s32), [[C]]
+ ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(s32) = G_XOR [[ICMP]], [[ICMP1]]
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY2]], [[C1]]
+ ; CHECK-NEXT: [[ADD1:%[0-9]+]]:_(s32) = G_ADD [[ADD]], [[AND]]
+ ; CHECK-NEXT: [[ICMP2:%[0-9]+]]:_(s32) = G_ICMP intpred(slt), [[ADD1]](s32), [[ADD]]
+ ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[ICMP2]], [[COPY2]]
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = G_OR [[XOR]], [[AND1]]
+ ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY [[ADD1]](s32)
+ ; CHECK-NEXT: $x10 = COPY [[COPY3]](s32)
+ ; CHECK-NEXT: $x11 = COPY [[OR]](s32)
+ ; CHECK-NEXT: PseudoRET implicit $x10, implicit $x11
+ %0:_(s32) = COPY $x10
+ %1:_(s32) = COPY $x11
+ %2:_(s32) = COPY $x12
+ %3:_(s1) = G_TRUNC %2(s32)
+ %4:_(s32), %5:_(s1) = G_SADDE %0, %1, %3
+ %6:_(s32) = G_ANYEXT %5(s1)
+ $x10 = COPY %4(s32)
+ $x11 = COPY %6(s32)
+ PseudoRET implicit $x10, implicit $x11
+
+...
+---
+name: sadde_i64
+body: |
+ bb.1:
+ liveins: $x10, $x11, $x12, $x13, $x14
+
+ ; CHECK-LABEL: name: sadde_i64
+ ; CHECK: liveins: $x10, $x11, $x12, $x13, $x14
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x12
+ ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $x13
+ ; CHECK-NEXT: [[COPY4:%[0-9]+]]:_(s32) = COPY $x14
+ ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[COPY]], [[COPY2]]
+ ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(slt), [[ADD]](s32), [[COPY]]
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: [[ICMP1:%[0-9]+]]:_(s32) = G_ICMP intpred(slt), [[COPY2]](s32), [[C]]
+ ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(s32) = G_XOR [[ICMP]], [[ICMP1]]
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY4]], [[C1]]
+ ; CHECK-NEXT: [[ADD1:%[0-9]+]]:_(s32) = G_ADD [[ADD]], [[AND]]
+ ; CHECK-NEXT: [[ICMP2:%[0-9]+]]:_(s32) = G_ICMP intpred(slt), [[ADD1]](s32), [[ADD]]
+ ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[ICMP2]], [[COPY4]]
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = G_OR [[XOR]], [[AND1]]
+ ; CHECK-NEXT: [[COPY5:%[0-9]+]]:_(s32) = COPY [[ADD1]](s32)
+ ; CHECK-NEXT: [[ADD2:%[0-9]+]]:_(s32) = G_ADD [[COPY1]], [[COPY3]]
+ ; CHECK-NEXT: [[ICMP3:%[0-9]+]]:_(s32) = G_ICMP intpred(slt), [[ADD2]](s32), [[COPY1]]
+ ; CHECK-NEXT: [[ICMP4:%[0-9]+]]:_(s32) = G_ICMP intpred(slt), [[COPY3]](s32), [[C]]
+ ; CHECK-NEXT: [[XOR1:%[0-9]+]]:_(s32) = G_XOR [[ICMP3]], [[ICMP4]]
+ ; CHECK-NEXT: [[ADD3:%[0-9]+]]:_(s32) = G_ADD [[ADD2]], [[OR]]
+ ; CHECK-NEXT: [[ICMP5:%[0-9]+]]:_(s32) = G_ICMP intpred(slt), [[ADD3]](s32), [[ADD2]]
+ ; CHECK-NEXT: [[AND2:%[0-9]+]]:_(s32) = G_AND [[ICMP5]], [[OR]]
+ ; CHECK-NEXT: [[OR1:%[0-9]+]]:_(s32) = G_OR [[XOR1]], [[AND2]]
+ ; CHECK-NEXT: [[COPY6:%[0-9]+]]:_(s32) = COPY [[ADD3]](s32)
+ ; CHECK-NEXT: $x10 = COPY [[COPY5]](s32)
+ ; CHECK-NEXT: $x11 = COPY [[COPY6]](s32)
+ ; CHECK-NEXT: $x12 = COPY [[OR1]](s32)
+ ; CHECK-NEXT: PseudoRET implicit $x10, implicit $x11, implicit $x12
+ %0:_(s32) = COPY $x10
+ %1:_(s32) = COPY $x11
+ %2:_(s32) = COPY $x12
+ %3:_(s32) = COPY $x13
+ %4:_(s32) = COPY $x14
+ %5:_(s1) = G_TRUNC %4(s32)
+ %6:_(s32), %7:_(s1) = G_SADDE %0, %2, %5
+ %8:_(s32), %9:_(s1) = G_SADDE %1, %3, %7
+ %10:_(s32) = G_ANYEXT %9(s1)
+ $x10 = COPY %6(s32)
+ $x11 = COPY %8(s32)
+ $x12 = COPY %10(s32)
+
+ PseudoRET implicit $x10, implicit $x11, implicit $x12
+...
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-sadde-rv64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-sadde-rv64.mir
new file mode 100644
index 0000000000000..70b5c144f3871
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-sadde-rv64.mir
@@ -0,0 +1,217 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv64 -run-pass=legalizer %s -o - | FileCheck %s
+
+---
+name: sadde_i8
+body: |
+ bb.1:
+ liveins: $x10, $x11, $x12
+
+ ; CHECK-LABEL: name: sadde_i8
+ ; CHECK: liveins: $x10, $x11, $x12
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x12
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 56
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[COPY]], [[C]](s64)
+ ; CHECK-NEXT: [[ASHR:%[0-9]+]]:_(s64) = G_ASHR [[SHL]], [[C]](s64)
+ ; CHECK-NEXT: [[SHL1:%[0-9]+]]:_(s64) = G_SHL [[COPY1]], [[C]](s64)
+ ; CHECK-NEXT: [[ASHR1:%[0-9]+]]:_(s64) = G_ASHR [[SHL1]], [[C]](s64)
+ ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[ASHR]], [[ASHR1]]
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[COPY2]], [[C1]]
+ ; CHECK-NEXT: [[ADD1:%[0-9]+]]:_(s64) = G_ADD [[ADD]], [[AND]]
+ ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY [[ADD1]](s64)
+ ; CHECK-NEXT: [[SHL2:%[0-9]+]]:_(s64) = G_SHL [[COPY3]], [[C]](s64)
+ ; CHECK-NEXT: [[ASHR2:%[0-9]+]]:_(s64) = G_ASHR [[SHL2]], [[C]](s64)
+ ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s64) = G_ICMP intpred(ne), [[COPY3]](s64), [[ASHR2]]
+ ; CHECK-NEXT: $x10 = COPY [[COPY3]](s64)
+ ; CHECK-NEXT: $x11 = COPY [[ICMP]](s64)
+ ; CHECK-NEXT: PseudoRET implicit $x10, implicit $x11
+ %0:_(s64) = COPY $x10
+ %1:_(s8) = G_TRUNC %0(s64)
+ %2:_(s64) = COPY $x11
+ %3:_(s8) = G_TRUNC %2(s64)
+ %4:_(s64) = COPY $x12
+ %5:_(s1) = G_TRUNC %4(s64)
+ %6:_(s8), %7:_(s1) = G_SADDE %1, %3, %5
+ %8:_(s64) = G_ANYEXT %6(s8)
+ %9:_(s64) = G_ANYEXT %7(s1)
+ $x10 = COPY %8(s64)
+ $x11 = COPY %9(s64)
+ PseudoRET implicit $x10, implicit $x11
+
+...
+---
+name: sadde_i16
+body: |
+ bb.1:
+ liveins: $x10, $x11, $x12
+
+ ; CHECK-LABEL: name: sadde_i16
+ ; CHECK: liveins: $x10, $x11, $x12
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x12
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 48
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[COPY]], [[C]](s64)
+ ; CHECK-NEXT: [[ASHR:%[0-9]+]]:_(s64) = G_ASHR [[SHL]], [[C]](s64)
+ ; CHECK-NEXT: [[SHL1:%[0-9]+]]:_(s64) = G_SHL [[COPY1]], [[C]](s64)
+ ; CHECK-NEXT: [[ASHR1:%[0-9]+]]:_(s64) = G_ASHR [[SHL1]], [[C]](s64)
+ ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[ASHR]], [[ASHR1]]
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[COPY2]], [[C1]]
+ ; CHECK-NEXT: [[ADD1:%[0-9]+]]:_(s64) = G_ADD [[ADD]], [[AND]]
+ ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY [[ADD1]](s64)
+ ; CHECK-NEXT: [[SHL2:%[0-9]+]]:_(s64) = G_SHL [[COPY3]], [[C]](s64)
+ ; CHECK-NEXT: [[ASHR2:%[0-9]+]]:_(s64) = G_ASHR [[SHL2]], [[C]](s64)
+ ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s64) = G_ICMP intpred(ne), [[COPY3]](s64), [[ASHR2]]
+ ; CHECK-NEXT: $x10 = COPY [[COPY3]](s64)
+ ; CHECK-NEXT: $x11 = COPY [[ICMP]](s64)
+ ; CHECK-NEXT: PseudoRET implicit $x10, implicit $x11
+ %0:_(s64) = COPY $x10
+ %1:_(s16) = G_TRUNC %0(s64)
+ %2:_(s64) = COPY $x11
+ %3:_(s16) = G_TRUNC %2(s64)
+ %4:_(s64) = COPY $x12
+ %5:_(s1) = G_TRUNC %4(s64)
+ %6:_(s16), %7:_(s1) = G_SADDE %1, %3, %5
+ %8:_(s64) = G_ANYEXT %6(s16)
+ %9:_(s64) = G_ANYEXT %7(s1)
+ $x10 = COPY %8(s64)
+ $x11 = COPY %9(s64)
+ PseudoRET implicit $x10, implicit $x11
+
+...
+---
+name: sadde_i32
+body: |
+ bb.1:
+ liveins: $x10, $x11, $x12
+
+ ; CHECK-LABEL: name: sadde_i32
+ ; CHECK: liveins: $x10, $x11, $x12
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x12
+ ; CHECK-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY]], 32
+ ; CHECK-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY1]], 32
+ ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[SEXT_INREG]], [[SEXT_INREG1]]
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[COPY2]], [[C]]
+ ; CHECK-NEXT: [[ADD1:%[0-9]+]]:_(s64) = G_ADD [[ADD]], [[AND]]
+ ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY [[ADD1]](s64)
+ ; CHECK-NEXT: [[SEXT_INREG2:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY3]], 32
+ ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s64) = G_ICMP intpred(ne), [[COPY3]](s64), [[SEXT_INREG2]]
+ ; CHECK-NEXT: $x10 = COPY [[COPY3]](s64)
+ ; CHECK-NEXT: $x11 = COPY [[ICMP]](s64)
+ ; CHECK-NEXT: PseudoRET implicit $x10, implicit $x11
+ %0:_(s64) = COPY $x10
+ %1:_(s32) = G_TRUNC %0(s64)
+ %2:_(s64) = COPY $x11
+ %3:_(s32) = G_TRUNC %2(s64)
+ %4:_(s64) = COPY $x12
+ %5:_(s1) = G_TRUNC %4(s64)
+ %6:_(s32), %7:_(s1) = G_SADDE %1, %3, %5
+ %8:_(s64) = G_ANYEXT %6(s32)
+ %9:_(s64) = G_ANYEXT %7(s1)
+ $x10 = COPY %8(s64)
+ $x11 = COPY %9(s64)
+ PseudoRET implicit $x10, implicit $x11
+
+...
+---
+name: sadde_i64
+body: |
+ bb.1:
+ liveins: $x10, $x11, $x12
+
+ ; CHECK-LABEL: name: sadde_i64
+ ; CHECK: liveins: $x10, $x11, $x12
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x12
+ ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[COPY]], [[COPY1]]
+ ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s64) = G_ICMP intpred(slt), [[ADD]](s64), [[COPY]]
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
+ ; CHECK-NEXT: [[ICMP1:%[0-9]+]]:_(s64) = G_ICMP intpred(slt), [[COPY1]](s64), [[C]]
+ ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(s64) = G_XOR [[ICMP]], [[ICMP1]]
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[COPY2]], [[C1]]
+ ; CHECK-NEXT: [[ADD1:%[0-9]+]]:_(s64) = G_ADD [[ADD]], [[AND]]
+ ; CHECK-NEXT: [[ICMP2:%[0-9]+]]:_(s64) = G_ICMP intpred(slt), [[ADD1]](s64), [[ADD]]
+ ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s64) = G_AND [[ICMP2]], [[COPY2]]
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s64) = G_OR [[XOR]], [[AND1]]
+ ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY [[ADD1]](s64)
+ ; CHECK-NEXT: $x10 = COPY [[COPY3]](s64)
+ ; CHECK-NEXT: $x11 = COPY [[OR]](s64)
+ ; CHECK-NEXT: PseudoRET implicit $x10, implicit $x11
+ %0:_(s64) = COPY $x10
+ %1:_(s64) = COPY $x11
+ %2:_(s64) = COPY $x12
+ %3:_(s1) = G_TRUNC %2(s64)
+ %4:_(s64), %5:_(s1) = G_SADDE %0, %1, %3
+ %6:_(s64) = G_ANYEXT %5(s1)
+ $x1...
[truncated]
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
2b91d44
to
7a10271
Compare
Summary
Try to implemente Lower G_SADDE in LegalizerHelper::lower