1 //===- ConstantFoldingTest.cpp -------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "GISelMITest.h" 10 #include "llvm/CodeGen/GlobalISel/CSEMIRBuilder.h" 11 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" 12 #include "llvm/CodeGen/GlobalISel/Utils.h" 13 #include "llvm/CodeGen/MachineFunction.h" 14 #include "gtest/gtest.h" 15 16 using namespace llvm; 17 18 namespace { 19 20 TEST_F(AArch64GISelMITest, FoldWithBuilder) { 21 setUp(); 22 if (!TM) 23 return; 24 // Try to use the FoldableInstructionsBuilder to build binary ops. 25 CSEMIRBuilder CFB(B.getState()); 26 LLT s32 = LLT::scalar(32); 27 int64_t Cst; 28 auto MIBCAdd = 29 CFB.buildAdd(s32, CFB.buildConstant(s32, 0), CFB.buildConstant(s32, 1)); 30 // This should be a constant now. 31 bool match = mi_match(MIBCAdd.getReg(0), *MRI, m_ICst(Cst)); 32 EXPECT_TRUE(match); 33 EXPECT_EQ(Cst, 1); 34 auto MIBCAdd1 = 35 CFB.buildInstr(TargetOpcode::G_ADD, {s32}, 36 {CFB.buildConstant(s32, 0), CFB.buildConstant(s32, 1)}); 37 // This should be a constant now. 38 match = mi_match(MIBCAdd1.getReg(0), *MRI, m_ICst(Cst)); 39 EXPECT_TRUE(match); 40 EXPECT_EQ(Cst, 1); 41 42 // Try one of the other constructors of MachineIRBuilder to make sure it's 43 // compatible. 44 CSEMIRBuilder CFB1(*MF); 45 CFB1.setInsertPt(*EntryMBB, EntryMBB->end()); 46 auto MIBCSub = 47 CFB1.buildInstr(TargetOpcode::G_SUB, {s32}, 48 {CFB1.buildConstant(s32, 1), CFB1.buildConstant(s32, 1)}); 49 // This should be a constant now. 50 match = mi_match(MIBCSub.getReg(0), *MRI, m_ICst(Cst)); 51 EXPECT_TRUE(match); 52 EXPECT_EQ(Cst, 0); 53 54 auto MIBCSext1 = 55 CFB1.buildInstr(TargetOpcode::G_SEXT_INREG, {s32}, 56 {CFB1.buildConstant(s32, 0x01), uint64_t(8)}); 57 // This should be a constant now. 58 match = mi_match(MIBCSext1.getReg(0), *MRI, m_ICst(Cst)); 59 EXPECT_TRUE(match); 60 EXPECT_EQ(1, Cst); 61 62 auto MIBCSext2 = 63 CFB1.buildInstr(TargetOpcode::G_SEXT_INREG, {s32}, 64 {CFB1.buildConstant(s32, 0x80), uint64_t(8)}); 65 // This should be a constant now. 66 match = mi_match(MIBCSext2.getReg(0), *MRI, m_ICst(Cst)); 67 EXPECT_TRUE(match); 68 EXPECT_EQ(-0x80, Cst); 69 } 70 71 TEST_F(AArch64GISelMITest, FoldBinOp) { 72 setUp(); 73 if (!TM) 74 return; 75 76 LLT s32{LLT::scalar(32)}; 77 auto MIBCst1 = B.buildConstant(s32, 16); 78 auto MIBCst2 = B.buildConstant(s32, 9); 79 auto MIBFCst1 = B.buildFConstant(s32, 1.0000001); 80 auto MIBFCst2 = B.buildFConstant(s32, 2.0); 81 82 // Test G_ADD folding Integer + Mixed Int-Float cases 83 std::optional<APInt> FoldGAddInt = ConstantFoldBinOp( 84 TargetOpcode::G_ADD, MIBCst1.getReg(0), MIBCst2.getReg(0), *MRI); 85 EXPECT_TRUE(FoldGAddInt.has_value()); 86 EXPECT_EQ(25ULL, FoldGAddInt.value().getLimitedValue()); 87 std::optional<APInt> FoldGAddMix = ConstantFoldBinOp( 88 TargetOpcode::G_ADD, MIBCst1.getReg(0), MIBFCst2.getReg(0), *MRI); 89 EXPECT_TRUE(FoldGAddMix.has_value()); 90 EXPECT_EQ(1073741840ULL, FoldGAddMix.value().getLimitedValue()); 91 92 // Test G_AND folding Integer + Mixed Int-Float cases 93 std::optional<APInt> FoldGAndInt = ConstantFoldBinOp( 94 TargetOpcode::G_AND, MIBCst1.getReg(0), MIBCst2.getReg(0), *MRI); 95 EXPECT_TRUE(FoldGAndInt.has_value()); 96 EXPECT_EQ(0ULL, FoldGAndInt.value().getLimitedValue()); 97 std::optional<APInt> FoldGAndMix = ConstantFoldBinOp( 98 TargetOpcode::G_AND, MIBCst2.getReg(0), MIBFCst1.getReg(0), *MRI); 99 EXPECT_TRUE(FoldGAndMix.has_value()); 100 EXPECT_EQ(1ULL, FoldGAndMix.value().getLimitedValue()); 101 102 // Test G_ASHR folding Integer + Mixed cases 103 std::optional<APInt> FoldGAShrInt = ConstantFoldBinOp( 104 TargetOpcode::G_ASHR, MIBCst1.getReg(0), MIBCst2.getReg(0), *MRI); 105 EXPECT_TRUE(FoldGAShrInt.has_value()); 106 EXPECT_EQ(0ULL, FoldGAShrInt.value().getLimitedValue()); 107 std::optional<APInt> FoldGAShrMix = ConstantFoldBinOp( 108 TargetOpcode::G_ASHR, MIBFCst2.getReg(0), MIBCst2.getReg(0), *MRI); 109 EXPECT_TRUE(FoldGAShrMix.has_value()); 110 EXPECT_EQ(2097152ULL, FoldGAShrMix.value().getLimitedValue()); 111 112 // Test G_LSHR folding Integer + Mixed Int-Float cases 113 std::optional<APInt> FoldGLShrInt = ConstantFoldBinOp( 114 TargetOpcode::G_LSHR, MIBCst1.getReg(0), MIBCst2.getReg(0), *MRI); 115 EXPECT_TRUE(FoldGLShrInt.has_value()); 116 EXPECT_EQ(0ULL, FoldGLShrInt.value().getLimitedValue()); 117 std::optional<APInt> FoldGLShrMix = ConstantFoldBinOp( 118 TargetOpcode::G_LSHR, MIBFCst1.getReg(0), MIBCst2.getReg(0), *MRI); 119 EXPECT_TRUE(FoldGLShrMix.has_value()); 120 EXPECT_EQ(2080768ULL, FoldGLShrMix.value().getLimitedValue()); 121 122 // Test G_MUL folding Integer + Mixed Int-Float cases 123 std::optional<APInt> FoldGMulInt = ConstantFoldBinOp( 124 TargetOpcode::G_MUL, MIBCst1.getReg(0), MIBCst2.getReg(0), *MRI); 125 EXPECT_TRUE(FoldGMulInt.has_value()); 126 EXPECT_EQ(144ULL, FoldGMulInt.value().getLimitedValue()); 127 std::optional<APInt> FoldGMulMix = ConstantFoldBinOp( 128 TargetOpcode::G_MUL, MIBCst1.getReg(0), MIBFCst2.getReg(0), *MRI); 129 EXPECT_TRUE(FoldGMulMix.has_value()); 130 EXPECT_EQ(0ULL, FoldGMulMix.value().getLimitedValue()); 131 132 // Test G_OR folding Integer + Mixed Int-Float cases 133 std::optional<APInt> FoldGOrInt = ConstantFoldBinOp( 134 TargetOpcode::G_OR, MIBCst1.getReg(0), MIBCst2.getReg(0), *MRI); 135 EXPECT_TRUE(FoldGOrInt.has_value()); 136 EXPECT_EQ(25ULL, FoldGOrInt.value().getLimitedValue()); 137 std::optional<APInt> FoldGOrMix = ConstantFoldBinOp( 138 TargetOpcode::G_OR, MIBCst1.getReg(0), MIBFCst2.getReg(0), *MRI); 139 EXPECT_TRUE(FoldGOrMix.has_value()); 140 EXPECT_EQ(1073741840ULL, FoldGOrMix.value().getLimitedValue()); 141 142 // Test G_SHL folding Integer + Mixed Int-Float cases 143 std::optional<APInt> FoldGShlInt = ConstantFoldBinOp( 144 TargetOpcode::G_SHL, MIBCst1.getReg(0), MIBCst2.getReg(0), *MRI); 145 EXPECT_TRUE(FoldGShlInt.has_value()); 146 EXPECT_EQ(8192ULL, FoldGShlInt.value().getLimitedValue()); 147 std::optional<APInt> FoldGShlMix = ConstantFoldBinOp( 148 TargetOpcode::G_SHL, MIBCst1.getReg(0), MIBFCst2.getReg(0), *MRI); 149 EXPECT_TRUE(FoldGShlMix.has_value()); 150 EXPECT_EQ(0ULL, FoldGShlMix.value().getLimitedValue()); 151 152 // Test G_SUB folding Integer + Mixed Int-Float cases 153 std::optional<APInt> FoldGSubInt = ConstantFoldBinOp( 154 TargetOpcode::G_SUB, MIBCst1.getReg(0), MIBCst2.getReg(0), *MRI); 155 EXPECT_TRUE(FoldGSubInt.has_value()); 156 EXPECT_EQ(7ULL, FoldGSubInt.value().getLimitedValue()); 157 std::optional<APInt> FoldGSubMix = ConstantFoldBinOp( 158 TargetOpcode::G_SUB, MIBCst1.getReg(0), MIBFCst2.getReg(0), *MRI); 159 EXPECT_TRUE(FoldGSubMix.has_value()); 160 EXPECT_EQ(3221225488ULL, FoldGSubMix.value().getLimitedValue()); 161 162 // Test G_XOR folding Integer + Mixed Int-Float cases 163 std::optional<APInt> FoldGXorInt = ConstantFoldBinOp( 164 TargetOpcode::G_XOR, MIBCst1.getReg(0), MIBCst2.getReg(0), *MRI); 165 EXPECT_TRUE(FoldGXorInt.has_value()); 166 EXPECT_EQ(25ULL, FoldGXorInt.value().getLimitedValue()); 167 std::optional<APInt> FoldGXorMix = ConstantFoldBinOp( 168 TargetOpcode::G_XOR, MIBCst1.getReg(0), MIBFCst2.getReg(0), *MRI); 169 EXPECT_TRUE(FoldGXorMix.has_value()); 170 EXPECT_EQ(1073741840ULL, FoldGXorMix.value().getLimitedValue()); 171 172 // Test G_UDIV folding Integer + Mixed Int-Float cases 173 std::optional<APInt> FoldGUdivInt = ConstantFoldBinOp( 174 TargetOpcode::G_UDIV, MIBCst1.getReg(0), MIBCst2.getReg(0), *MRI); 175 EXPECT_TRUE(FoldGUdivInt.has_value()); 176 EXPECT_EQ(1ULL, FoldGUdivInt.value().getLimitedValue()); 177 std::optional<APInt> FoldGUdivMix = ConstantFoldBinOp( 178 TargetOpcode::G_UDIV, MIBCst1.getReg(0), MIBFCst2.getReg(0), *MRI); 179 EXPECT_TRUE(FoldGUdivMix.has_value()); 180 EXPECT_EQ(0ULL, FoldGUdivMix.value().getLimitedValue()); 181 182 // Test G_SDIV folding Integer + Mixed Int-Float cases 183 std::optional<APInt> FoldGSdivInt = ConstantFoldBinOp( 184 TargetOpcode::G_SDIV, MIBCst1.getReg(0), MIBCst2.getReg(0), *MRI); 185 EXPECT_TRUE(FoldGSdivInt.has_value()); 186 EXPECT_EQ(1ULL, FoldGSdivInt.value().getLimitedValue()); 187 std::optional<APInt> FoldGSdivMix = ConstantFoldBinOp( 188 TargetOpcode::G_SDIV, MIBCst1.getReg(0), MIBFCst2.getReg(0), *MRI); 189 EXPECT_TRUE(FoldGSdivMix.has_value()); 190 EXPECT_EQ(0ULL, FoldGSdivMix.value().getLimitedValue()); 191 192 // Test G_UREM folding Integer + Mixed Int-Float cases 193 std::optional<APInt> FoldGUremInt = ConstantFoldBinOp( 194 TargetOpcode::G_UDIV, MIBCst1.getReg(0), MIBCst2.getReg(0), *MRI); 195 EXPECT_TRUE(FoldGUremInt.has_value()); 196 EXPECT_EQ(1ULL, FoldGUremInt.value().getLimitedValue()); 197 std::optional<APInt> FoldGUremMix = ConstantFoldBinOp( 198 TargetOpcode::G_UDIV, MIBCst1.getReg(0), MIBFCst2.getReg(0), *MRI); 199 EXPECT_TRUE(FoldGUremMix.has_value()); 200 EXPECT_EQ(0ULL, FoldGUremMix.value().getLimitedValue()); 201 202 // Test G_SREM folding Integer + Mixed Int-Float cases 203 std::optional<APInt> FoldGSremInt = ConstantFoldBinOp( 204 TargetOpcode::G_SREM, MIBCst1.getReg(0), MIBCst2.getReg(0), *MRI); 205 EXPECT_TRUE(FoldGSremInt.has_value()); 206 EXPECT_EQ(7ULL, FoldGSremInt.value().getLimitedValue()); 207 std::optional<APInt> FoldGSremMix = ConstantFoldBinOp( 208 TargetOpcode::G_SREM, MIBCst1.getReg(0), MIBFCst2.getReg(0), *MRI); 209 EXPECT_TRUE(FoldGSremMix.has_value()); 210 EXPECT_EQ(16ULL, FoldGSremMix.value().getLimitedValue()); 211 } 212 213 } // namespace 214