[llvm] r340892 - [GISel]: Add legalization support for Widening UADDO/USUBO
Aditya Nandakumar via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 28 20:17:08 PDT 2018
Author: aditya_nandakumar
Date: Tue Aug 28 20:17:08 2018
New Revision: 340892
URL: http://llvm.org/viewvc/llvm-project?rev=340892&view=rev
Log:
[GISel]: Add legalization support for Widening UADDO/USUBO
https://reviews.llvm.org/D51384
Added code in LegalizerHelper to widen UADDO/USUBO along with unit
tests.
Reviewed by volkan.
Modified:
llvm/trunk/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
llvm/trunk/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp
Modified: llvm/trunk/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/LegalizerHelper.cpp?rev=340892&r1=340891&r2=340892&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/LegalizerHelper.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/LegalizerHelper.cpp Tue Aug 28 20:17:08 2018
@@ -619,6 +619,32 @@ LegalizerHelper::widenScalar(MachineInst
switch (MI.getOpcode()) {
default:
return UnableToLegalize;
+ case TargetOpcode::G_UADDO:
+ case TargetOpcode::G_USUBO: {
+ if (TypeIdx == 1)
+ return UnableToLegalize; // TODO
+ auto LHSZext = MIRBuilder.buildInstr(TargetOpcode::G_ZEXT, WideTy,
+ MI.getOperand(2).getReg());
+ auto RHSZext = MIRBuilder.buildInstr(TargetOpcode::G_ZEXT, WideTy,
+ MI.getOperand(3).getReg());
+ unsigned Opcode = MI.getOpcode() == TargetOpcode::G_UADDO
+ ? TargetOpcode::G_ADD
+ : TargetOpcode::G_SUB;
+ // Do the arithmetic in the larger type.
+ auto NewOp = MIRBuilder.buildInstr(Opcode, WideTy, LHSZext, RHSZext);
+ LLT OrigTy = MRI.getType(MI.getOperand(0).getReg());
+ APInt Mask = APInt::getAllOnesValue(OrigTy.getSizeInBits());
+ auto AndOp = MIRBuilder.buildInstr(
+ TargetOpcode::G_AND, WideTy, NewOp,
+ MIRBuilder.buildConstant(WideTy, Mask.getZExtValue()));
+ // There is no overflow if the AndOp is the same as NewOp.
+ MIRBuilder.buildICmp(CmpInst::ICMP_NE, MI.getOperand(1).getReg(), NewOp,
+ AndOp);
+ // Now trunc the NewOp to the original result.
+ MIRBuilder.buildTrunc(MI.getOperand(0).getReg(), NewOp);
+ MI.eraseFromParent();
+ return Legalized;
+ }
case TargetOpcode::G_CTTZ:
case TargetOpcode::G_CTTZ_ZERO_UNDEF:
case TargetOpcode::G_CTLZ:
Modified: llvm/trunk/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp?rev=340892&r1=340891&r2=340892&view=diff
==============================================================================
--- llvm/trunk/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp (original)
+++ llvm/trunk/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp Tue Aug 28 20:17:08 2018
@@ -342,4 +342,79 @@ TEST_F(LegalizerHelperTest, WidenBitCoun
// Check
ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
}
+// UADDO widening.
+TEST_F(LegalizerHelperTest, WidenUADDO) {
+ if (!TM)
+ return;
+
+ // Declare your legalization info
+ DefineLegalizerInfo(A,
+ { getActionDefinitionsBuilder(G_ADD).legalFor({s16}); });
+ // Build
+ // Trunc it to s8.
+ LLT s8{LLT::scalar(8)};
+ LLT s16{LLT::scalar(16)};
+ auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
+ unsigned CarryReg = MRI->createGenericVirtualRegister(LLT::scalar(1));
+ auto MIBUAddO = B.buildInstr(TargetOpcode::G_UADDO, s8)
+ .addDef(CarryReg)
+ .addUse(MIBTrunc->getOperand(0).getReg())
+ .addUse(MIBTrunc->getOperand(0).getReg());
+ AInfo Info(MF->getSubtarget());
+ LegalizerHelper Helper(*MF, Info);
+ ASSERT_TRUE(Helper.widenScalar(*MIBUAddO, 0, s16) ==
+ LegalizerHelper::LegalizeResult::Legalized);
+
+ auto CheckStr = R"(
+ CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
+ CHECK: [[LHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
+ CHECK: [[RHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
+ CHECK: [[ADD:%[0-9]+]]:_(s16) = G_ADD [[LHS]]:_, [[RHS]]:_
+ CHECK: [[CST:%[0-9]+]]:_(s16) = G_CONSTANT i16 255
+ CHECK: [[AND:%[0-9]+]]:_(s16) = G_AND [[ADD]]:_, [[CST]]:_
+ CHECK: G_ICMP intpred(ne), [[ADD]]:_(s16), [[AND]]:_
+ CHECK: G_TRUNC [[ADD]]
+ )";
+
+ // Check
+ ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
+}
+
+// USUBO widening.
+TEST_F(LegalizerHelperTest, WidenUSUBO) {
+ if (!TM)
+ return;
+
+ // Declare your legalization info
+ DefineLegalizerInfo(A,
+ { getActionDefinitionsBuilder(G_SUB).legalFor({s16}); });
+ // Build
+ // Trunc it to s8.
+ LLT s8{LLT::scalar(8)};
+ LLT s16{LLT::scalar(16)};
+ auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
+ unsigned CarryReg = MRI->createGenericVirtualRegister(LLT::scalar(1));
+ auto MIBUSUBO = B.buildInstr(TargetOpcode::G_USUBO, s8)
+ .addDef(CarryReg)
+ .addUse(MIBTrunc->getOperand(0).getReg())
+ .addUse(MIBTrunc->getOperand(0).getReg());
+ AInfo Info(MF->getSubtarget());
+ LegalizerHelper Helper(*MF, Info);
+ ASSERT_TRUE(Helper.widenScalar(*MIBUSUBO, 0, s16) ==
+ LegalizerHelper::LegalizeResult::Legalized);
+
+ auto CheckStr = R"(
+ CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
+ CHECK: [[LHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
+ CHECK: [[RHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
+ CHECK: [[SUB:%[0-9]+]]:_(s16) = G_SUB [[LHS]]:_, [[RHS]]:_
+ CHECK: [[CST:%[0-9]+]]:_(s16) = G_CONSTANT i16 255
+ CHECK: [[AND:%[0-9]+]]:_(s16) = G_AND [[SUB]]:_, [[CST]]:_
+ CHECK: G_ICMP intpred(ne), [[SUB]]:_(s16), [[AND]]:_
+ CHECK: G_TRUNC [[SUB]]
+ )";
+
+ // Check
+ ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
+}
} // namespace
More information about the llvm-commits
mailing list