Index: llvm/include/llvm/CodeGen/GlobalISel/Utils.h =================================================================== --- llvm/include/llvm/CodeGen/GlobalISel/Utils.h +++ llvm/include/llvm/CodeGen/GlobalISel/Utils.h @@ -129,6 +129,10 @@ bool LookThroughInstrs = true); const ConstantFP* getConstantFPVRegVal(unsigned VReg, const MachineRegisterInfo &MRI); +/// Return the bit representation of a constant of any type +/// (G_CONSTANT or G_FCONSTANT). +Optional getAnyConstantVRegVal(unsigned VReg, + const MachineRegisterInfo &MRI); /// See if Reg is defined by an single def instruction that is /// Opcode. Also try to do trivial folding if it's a COPY with Index: llvm/lib/CodeGen/GlobalISel/Utils.cpp =================================================================== --- llvm/lib/CodeGen/GlobalISel/Utils.cpp +++ llvm/lib/CodeGen/GlobalISel/Utils.cpp @@ -316,15 +316,29 @@ return APF; } +Optional llvm::getAnyConstantVRegVal(unsigned VReg, + const MachineRegisterInfo &MRI) { + const ConstantFP *FPVal = getConstantFPVRegVal(VReg, MRI); + if (FPVal && + (&FPVal->getValueAPF().getSemantics() == &APFloat::IEEEdouble() || + &FPVal->getValueAPF().getSemantics() == &APFloat::IEEEsingle() || + &FPVal->getValueAPF().getSemantics() == &APFloat::IEEEhalf())) { + return FPVal->getValueAPF().bitcastToAPInt(); + } + Optional IntVal = getConstantVRegVal(VReg, MRI); + if (IntVal) + return APInt(MRI.getType(VReg).getSizeInBits(), *IntVal, true); + return None; +} + Optional llvm::ConstantFoldBinOp(unsigned Opcode, const unsigned Op1, const unsigned Op2, const MachineRegisterInfo &MRI) { - auto MaybeOp1Cst = getConstantVRegVal(Op1, MRI); - auto MaybeOp2Cst = getConstantVRegVal(Op2, MRI); + auto MaybeOp1Cst = getAnyConstantVRegVal(Op1, MRI); + auto MaybeOp2Cst = getAnyConstantVRegVal(Op2, MRI); if (MaybeOp1Cst && MaybeOp2Cst) { - LLT Ty = MRI.getType(Op1); - APInt C1(Ty.getSizeInBits(), *MaybeOp1Cst, true); - APInt C2(Ty.getSizeInBits(), *MaybeOp2Cst, true); + auto &C1 = *MaybeOp1Cst; + auto &C2 = *MaybeOp2Cst; switch (Opcode) { default: break; Index: llvm/unittests/CodeGen/GlobalISel/ConstantFoldingTest.cpp =================================================================== --- llvm/unittests/CodeGen/GlobalISel/ConstantFoldingTest.cpp +++ llvm/unittests/CodeGen/GlobalISel/ConstantFoldingTest.cpp @@ -68,4 +68,172 @@ EXPECT_EQ(-0x80, Cst); } +TEST_F(GISelMITest, FoldBinOp) { + setUp(); + if (!TM) + return; + + LLT s32{LLT::scalar(32)}; + auto MIBCst1 = B.buildConstant(s32, 16); + auto MIBCst2 = B.buildConstant(s32, 9); + auto MIBFCst1 = B.buildFConstant(s32, 1.0000001); + auto MIBFCst2 = B.buildFConstant(s32, 2.0); + + // Test G_ADD folding Integer + Mixed Int-Float cases + Optional FoldGAddInt = ConstantFoldBinOp(TargetOpcode::G_ADD, MIBCst1->getOperand(0).getReg(), + MIBCst2->getOperand(0).getReg(), + MRI); + EXPECT_TRUE(FoldGAddInt.hasValue()); + EXPECT_EQ(25ULL, FoldGAddInt.getValue().getLimitedValue()); + Optional FoldGAddMix = ConstantFoldBinOp(TargetOpcode::G_ADD, MIBCst1->getOperand(0).getReg(), + MIBFCst2->getOperand(0).getReg(), + MRI); + EXPECT_TRUE(FoldGAddMix.hasValue()); + EXPECT_EQ(1073741840ULL, FoldGAddMix.getValue().getLimitedValue()); + + // Test G_AND folding Integer + Mixed Int-Float cases + Optional FoldGAndInt = ConstantFoldBinOp(TargetOpcode::G_AND, MIBCst1->getOperand(0).getReg(), + MIBCst2->getOperand(0).getReg(), + MRI); + EXPECT_TRUE(FoldGAndInt.hasValue()); + EXPECT_EQ(0ULL, FoldGAndInt.getValue().getLimitedValue()); + Optional FoldGAndMix = ConstantFoldBinOp(TargetOpcode::G_AND, MIBCst2->getOperand(0).getReg(), + MIBFCst1->getOperand(0).getReg(), + MRI); + EXPECT_TRUE(FoldGAndMix.hasValue()); + EXPECT_EQ(1ULL, FoldGAndMix.getValue().getLimitedValue()); + + // Test G_ASHR folding Integer + Mixed cases + Optional FoldGAShrInt = ConstantFoldBinOp(TargetOpcode::G_ASHR, MIBCst1->getOperand(0).getReg(), + MIBCst2->getOperand(0).getReg(), + MRI); + EXPECT_TRUE(FoldGAShrInt.hasValue()); + EXPECT_EQ(0ULL, FoldGAShrInt.getValue().getLimitedValue()); + Optional FoldGAShrMix = ConstantFoldBinOp(TargetOpcode::G_ASHR, MIBFCst2->getOperand(0).getReg(), + MIBCst2->getOperand(0).getReg(), + MRI); + EXPECT_TRUE(FoldGAShrMix.hasValue()); + EXPECT_EQ(2097152ULL, FoldGAShrMix.getValue().getLimitedValue()); + + // Test G_LSHR folding Integer + Mixed Int-Float cases + Optional FoldGLShrInt = ConstantFoldBinOp(TargetOpcode::G_LSHR, MIBCst1->getOperand(0).getReg(), + MIBCst2->getOperand(0).getReg(), + MRI); + EXPECT_TRUE(FoldGLShrInt.hasValue()); + EXPECT_EQ(0ULL, FoldGLShrInt.getValue().getLimitedValue()); + Optional FoldGLShrMix = ConstantFoldBinOp(TargetOpcode::G_LSHR, MIBFCst1->getOperand(0).getReg(), + MIBCst2->getOperand(0).getReg(), + MRI); + EXPECT_TRUE(FoldGLShrMix.hasValue()); + EXPECT_EQ(2080768ULL, FoldGLShrMix.getValue().getLimitedValue()); + + // Test G_MUL folding Integer + Mixed Int-Float cases + Optional FoldGMulInt = ConstantFoldBinOp(TargetOpcode::G_MUL, MIBCst1->getOperand(0).getReg(), + MIBCst2->getOperand(0).getReg(), + MRI); + EXPECT_TRUE(FoldGMulInt.hasValue()); + EXPECT_EQ(144ULL, FoldGMulInt.getValue().getLimitedValue()); + Optional FoldGMulMix = ConstantFoldBinOp(TargetOpcode::G_MUL, MIBCst1->getOperand(0).getReg(), + MIBFCst2->getOperand(0).getReg(), + MRI); + EXPECT_TRUE(FoldGMulMix.hasValue()); + EXPECT_EQ(0ULL, FoldGMulMix.getValue().getLimitedValue()); + + // Test G_OR folding Integer + Mixed Int-Float cases + Optional FoldGOrInt = ConstantFoldBinOp(TargetOpcode::G_OR, MIBCst1->getOperand(0).getReg(), + MIBCst2->getOperand(0).getReg(), + MRI); + EXPECT_TRUE(FoldGOrInt.hasValue()); + EXPECT_EQ(25ULL, FoldGOrInt.getValue().getLimitedValue()); + Optional FoldGOrMix = ConstantFoldBinOp(TargetOpcode::G_OR, MIBCst1->getOperand(0).getReg(), + MIBFCst2->getOperand(0).getReg(), + MRI); + EXPECT_TRUE(FoldGOrMix.hasValue()); + EXPECT_EQ(1073741840ULL, FoldGOrMix.getValue().getLimitedValue()); + + // Test G_SHL folding Integer + Mixed Int-Float cases + Optional FoldGShlInt = ConstantFoldBinOp(TargetOpcode::G_SHL, MIBCst1->getOperand(0).getReg(), + MIBCst2->getOperand(0).getReg(), + MRI); + EXPECT_TRUE(FoldGShlInt.hasValue()); + EXPECT_EQ(8192ULL, FoldGShlInt.getValue().getLimitedValue()); + Optional FoldGShlMix = ConstantFoldBinOp(TargetOpcode::G_SHL, MIBCst1->getOperand(0).getReg(), + MIBFCst2->getOperand(0).getReg(), + MRI); + EXPECT_TRUE(FoldGShlMix.hasValue()); + EXPECT_EQ(0ULL, FoldGShlMix.getValue().getLimitedValue()); + + // Test G_SUB folding Integer + Mixed Int-Float cases + Optional FoldGSubInt = ConstantFoldBinOp(TargetOpcode::G_SUB, MIBCst1->getOperand(0).getReg(), + MIBCst2->getOperand(0).getReg(), + MRI); + EXPECT_TRUE(FoldGSubInt.hasValue()); + EXPECT_EQ(7ULL, FoldGSubInt.getValue().getLimitedValue()); + Optional FoldGSubMix = ConstantFoldBinOp(TargetOpcode::G_SUB, MIBCst1->getOperand(0).getReg(), + MIBFCst2->getOperand(0).getReg(), + MRI); + EXPECT_TRUE(FoldGSubMix.hasValue()); + EXPECT_EQ(3221225488ULL, FoldGSubMix.getValue().getLimitedValue()); + + // Test G_XOR folding Integer + Mixed Int-Float cases + Optional FoldGXorInt = ConstantFoldBinOp(TargetOpcode::G_XOR, MIBCst1->getOperand(0).getReg(), + MIBCst2->getOperand(0).getReg(), + MRI); + EXPECT_TRUE(FoldGXorInt.hasValue()); + EXPECT_EQ(25ULL, FoldGXorInt.getValue().getLimitedValue()); + Optional FoldGXorMix = ConstantFoldBinOp(TargetOpcode::G_XOR, MIBCst1->getOperand(0).getReg(), + MIBFCst2->getOperand(0).getReg(), + MRI); + EXPECT_TRUE(FoldGXorMix.hasValue()); + EXPECT_EQ(1073741840ULL, FoldGXorMix.getValue().getLimitedValue()); + + // Test G_UDIV folding Integer + Mixed Int-Float cases + Optional FoldGUdivInt = ConstantFoldBinOp(TargetOpcode::G_UDIV, MIBCst1->getOperand(0).getReg(), + MIBCst2->getOperand(0).getReg(), + MRI); + EXPECT_TRUE(FoldGUdivInt.hasValue()); + EXPECT_EQ(1ULL, FoldGUdivInt.getValue().getLimitedValue()); + Optional FoldGUdivMix = ConstantFoldBinOp(TargetOpcode::G_UDIV, MIBCst1->getOperand(0).getReg(), + MIBFCst2->getOperand(0).getReg(), + MRI); + EXPECT_TRUE(FoldGUdivMix.hasValue()); + EXPECT_EQ(0ULL, FoldGUdivMix.getValue().getLimitedValue()); + + // Test G_SDIV folding Integer + Mixed Int-Float cases + Optional FoldGSdivInt = ConstantFoldBinOp(TargetOpcode::G_SDIV, MIBCst1->getOperand(0).getReg(), + MIBCst2->getOperand(0).getReg(), + MRI); + EXPECT_TRUE(FoldGSdivInt.hasValue()); + EXPECT_EQ(1ULL, FoldGSdivInt.getValue().getLimitedValue()); + Optional FoldGSdivMix = ConstantFoldBinOp(TargetOpcode::G_SDIV, MIBCst1->getOperand(0).getReg(), + MIBFCst2->getOperand(0).getReg(), + MRI); + EXPECT_TRUE(FoldGSdivMix.hasValue()); + EXPECT_EQ(0ULL, FoldGSdivMix.getValue().getLimitedValue()); + + // Test G_UREM folding Integer + Mixed Int-Float cases + Optional FoldGUremInt = ConstantFoldBinOp(TargetOpcode::G_UDIV, MIBCst1->getOperand(0).getReg(), + MIBCst2->getOperand(0).getReg(), + MRI); + EXPECT_TRUE(FoldGUremInt.hasValue()); + EXPECT_EQ(1ULL, FoldGUremInt.getValue().getLimitedValue()); + Optional FoldGUremMix = ConstantFoldBinOp(TargetOpcode::G_UDIV, MIBCst1->getOperand(0).getReg(), + MIBFCst2->getOperand(0).getReg(), + MRI); + EXPECT_TRUE(FoldGUremMix.hasValue()); + EXPECT_EQ(0ULL, FoldGUremMix.getValue().getLimitedValue()); + + // Test G_SREM folding Integer + Mixed Int-Float cases + Optional FoldGSremInt = ConstantFoldBinOp(TargetOpcode::G_SREM, MIBCst1->getOperand(0).getReg(), + MIBCst2->getOperand(0).getReg(), + MRI); + EXPECT_TRUE(FoldGSremInt.hasValue()); + EXPECT_EQ(7ULL, FoldGSremInt.getValue().getLimitedValue()); + Optional FoldGSremMix = ConstantFoldBinOp(TargetOpcode::G_SREM, MIBCst1->getOperand(0).getReg(), + MIBFCst2->getOperand(0).getReg(), + MRI); + EXPECT_TRUE(FoldGSremMix.hasValue()); + EXPECT_EQ(16ULL, FoldGSremMix.getValue().getLimitedValue()); +} + } // namespace \ No newline at end of file