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 Optional<APInt> FoldGAddInt = 84 ConstantFoldBinOp(TargetOpcode::G_ADD, MIBCst1.getReg(0), 85 MIBCst2.getReg(0), *MRI); 86 EXPECT_TRUE(FoldGAddInt.has_value()); 87 EXPECT_EQ(25ULL, FoldGAddInt->getLimitedValue()); 88 Optional<APInt> FoldGAddMix = 89 ConstantFoldBinOp(TargetOpcode::G_ADD, MIBCst1.getReg(0), 90 MIBFCst2.getReg(0), *MRI); 91 EXPECT_TRUE(FoldGAddMix.has_value()); 92 EXPECT_EQ(1073741840ULL, FoldGAddMix->getLimitedValue()); 93 94 // Test G_AND folding Integer + Mixed Int-Float cases 95 Optional<APInt> FoldGAndInt = 96 ConstantFoldBinOp(TargetOpcode::G_AND, MIBCst1.getReg(0), 97 MIBCst2.getReg(0), *MRI); 98 EXPECT_TRUE(FoldGAndInt.has_value()); 99 EXPECT_EQ(0ULL, FoldGAndInt->getLimitedValue()); 100 Optional<APInt> FoldGAndMix = 101 ConstantFoldBinOp(TargetOpcode::G_AND, MIBCst2.getReg(0), 102 MIBFCst1.getReg(0), *MRI); 103 EXPECT_TRUE(FoldGAndMix.has_value()); 104 EXPECT_EQ(1ULL, FoldGAndMix->getLimitedValue()); 105 106 // Test G_ASHR folding Integer + Mixed cases 107 Optional<APInt> FoldGAShrInt = 108 ConstantFoldBinOp(TargetOpcode::G_ASHR, MIBCst1.getReg(0), 109 MIBCst2.getReg(0), *MRI); 110 EXPECT_TRUE(FoldGAShrInt.has_value()); 111 EXPECT_EQ(0ULL, FoldGAShrInt->getLimitedValue()); 112 Optional<APInt> FoldGAShrMix = 113 ConstantFoldBinOp(TargetOpcode::G_ASHR, MIBFCst2.getReg(0), 114 MIBCst2.getReg(0), *MRI); 115 EXPECT_TRUE(FoldGAShrMix.has_value()); 116 EXPECT_EQ(2097152ULL, FoldGAShrMix->getLimitedValue()); 117 118 // Test G_LSHR folding Integer + Mixed Int-Float cases 119 Optional<APInt> FoldGLShrInt = 120 ConstantFoldBinOp(TargetOpcode::G_LSHR, MIBCst1.getReg(0), 121 MIBCst2.getReg(0), *MRI); 122 EXPECT_TRUE(FoldGLShrInt.has_value()); 123 EXPECT_EQ(0ULL, FoldGLShrInt->getLimitedValue()); 124 Optional<APInt> FoldGLShrMix = 125 ConstantFoldBinOp(TargetOpcode::G_LSHR, MIBFCst1.getReg(0), 126 MIBCst2.getReg(0), *MRI); 127 EXPECT_TRUE(FoldGLShrMix.has_value()); 128 EXPECT_EQ(2080768ULL, FoldGLShrMix->getLimitedValue()); 129 130 // Test G_MUL folding Integer + Mixed Int-Float cases 131 Optional<APInt> FoldGMulInt = 132 ConstantFoldBinOp(TargetOpcode::G_MUL, MIBCst1.getReg(0), 133 MIBCst2.getReg(0), *MRI); 134 EXPECT_TRUE(FoldGMulInt.has_value()); 135 EXPECT_EQ(144ULL, FoldGMulInt->getLimitedValue()); 136 Optional<APInt> FoldGMulMix = 137 ConstantFoldBinOp(TargetOpcode::G_MUL, MIBCst1.getReg(0), 138 MIBFCst2.getReg(0), *MRI); 139 EXPECT_TRUE(FoldGMulMix.has_value()); 140 EXPECT_EQ(0ULL, FoldGMulMix->getLimitedValue()); 141 142 // Test G_OR folding Integer + Mixed Int-Float cases 143 Optional<APInt> FoldGOrInt = 144 ConstantFoldBinOp(TargetOpcode::G_OR, MIBCst1.getReg(0), 145 MIBCst2.getReg(0), *MRI); 146 EXPECT_TRUE(FoldGOrInt.has_value()); 147 EXPECT_EQ(25ULL, FoldGOrInt->getLimitedValue()); 148 Optional<APInt> FoldGOrMix = 149 ConstantFoldBinOp(TargetOpcode::G_OR, MIBCst1.getReg(0), 150 MIBFCst2.getReg(0), *MRI); 151 EXPECT_TRUE(FoldGOrMix.has_value()); 152 EXPECT_EQ(1073741840ULL, FoldGOrMix->getLimitedValue()); 153 154 // Test G_SHL folding Integer + Mixed Int-Float cases 155 Optional<APInt> FoldGShlInt = 156 ConstantFoldBinOp(TargetOpcode::G_SHL, MIBCst1.getReg(0), 157 MIBCst2.getReg(0), *MRI); 158 EXPECT_TRUE(FoldGShlInt.has_value()); 159 EXPECT_EQ(8192ULL, FoldGShlInt->getLimitedValue()); 160 Optional<APInt> FoldGShlMix = 161 ConstantFoldBinOp(TargetOpcode::G_SHL, MIBCst1.getReg(0), 162 MIBFCst2.getReg(0), *MRI); 163 EXPECT_TRUE(FoldGShlMix.has_value()); 164 EXPECT_EQ(0ULL, FoldGShlMix->getLimitedValue()); 165 166 // Test G_SUB folding Integer + Mixed Int-Float cases 167 Optional<APInt> FoldGSubInt = 168 ConstantFoldBinOp(TargetOpcode::G_SUB, MIBCst1.getReg(0), 169 MIBCst2.getReg(0), *MRI); 170 EXPECT_TRUE(FoldGSubInt.has_value()); 171 EXPECT_EQ(7ULL, FoldGSubInt->getLimitedValue()); 172 Optional<APInt> FoldGSubMix = 173 ConstantFoldBinOp(TargetOpcode::G_SUB, MIBCst1.getReg(0), 174 MIBFCst2.getReg(0), *MRI); 175 EXPECT_TRUE(FoldGSubMix.has_value()); 176 EXPECT_EQ(3221225488ULL, FoldGSubMix->getLimitedValue()); 177 178 // Test G_XOR folding Integer + Mixed Int-Float cases 179 Optional<APInt> FoldGXorInt = 180 ConstantFoldBinOp(TargetOpcode::G_XOR, MIBCst1.getReg(0), 181 MIBCst2.getReg(0), *MRI); 182 EXPECT_TRUE(FoldGXorInt.has_value()); 183 EXPECT_EQ(25ULL, FoldGXorInt->getLimitedValue()); 184 Optional<APInt> FoldGXorMix = 185 ConstantFoldBinOp(TargetOpcode::G_XOR, MIBCst1.getReg(0), 186 MIBFCst2.getReg(0), *MRI); 187 EXPECT_TRUE(FoldGXorMix.has_value()); 188 EXPECT_EQ(1073741840ULL, FoldGXorMix->getLimitedValue()); 189 190 // Test G_UDIV folding Integer + Mixed Int-Float cases 191 Optional<APInt> FoldGUdivInt = 192 ConstantFoldBinOp(TargetOpcode::G_UDIV, MIBCst1.getReg(0), 193 MIBCst2.getReg(0), *MRI); 194 EXPECT_TRUE(FoldGUdivInt.has_value()); 195 EXPECT_EQ(1ULL, FoldGUdivInt->getLimitedValue()); 196 Optional<APInt> FoldGUdivMix = 197 ConstantFoldBinOp(TargetOpcode::G_UDIV, MIBCst1.getReg(0), 198 MIBFCst2.getReg(0), *MRI); 199 EXPECT_TRUE(FoldGUdivMix.has_value()); 200 EXPECT_EQ(0ULL, FoldGUdivMix->getLimitedValue()); 201 202 // Test G_SDIV folding Integer + Mixed Int-Float cases 203 Optional<APInt> FoldGSdivInt = 204 ConstantFoldBinOp(TargetOpcode::G_SDIV, MIBCst1.getReg(0), 205 MIBCst2.getReg(0), *MRI); 206 EXPECT_TRUE(FoldGSdivInt.has_value()); 207 EXPECT_EQ(1ULL, FoldGSdivInt->getLimitedValue()); 208 Optional<APInt> FoldGSdivMix = 209 ConstantFoldBinOp(TargetOpcode::G_SDIV, MIBCst1.getReg(0), 210 MIBFCst2.getReg(0), *MRI); 211 EXPECT_TRUE(FoldGSdivMix.has_value()); 212 EXPECT_EQ(0ULL, FoldGSdivMix->getLimitedValue()); 213 214 // Test G_UREM folding Integer + Mixed Int-Float cases 215 Optional<APInt> FoldGUremInt = 216 ConstantFoldBinOp(TargetOpcode::G_UDIV, MIBCst1.getReg(0), 217 MIBCst2.getReg(0), *MRI); 218 EXPECT_TRUE(FoldGUremInt.has_value()); 219 EXPECT_EQ(1ULL, FoldGUremInt->getLimitedValue()); 220 Optional<APInt> FoldGUremMix = 221 ConstantFoldBinOp(TargetOpcode::G_UDIV, MIBCst1.getReg(0), 222 MIBFCst2.getReg(0), *MRI); 223 EXPECT_TRUE(FoldGUremMix.has_value()); 224 EXPECT_EQ(0ULL, FoldGUremMix->getLimitedValue()); 225 226 // Test G_SREM folding Integer + Mixed Int-Float cases 227 Optional<APInt> FoldGSremInt = 228 ConstantFoldBinOp(TargetOpcode::G_SREM, MIBCst1.getReg(0), 229 MIBCst2.getReg(0), *MRI); 230 EXPECT_TRUE(FoldGSremInt.has_value()); 231 EXPECT_EQ(7ULL, FoldGSremInt->getLimitedValue()); 232 Optional<APInt> FoldGSremMix = 233 ConstantFoldBinOp(TargetOpcode::G_SREM, MIBCst1.getReg(0), 234 MIBFCst2.getReg(0), *MRI); 235 EXPECT_TRUE(FoldGSremMix.has_value()); 236 EXPECT_EQ(16ULL, FoldGSremMix->getLimitedValue()); 237 } 238 239 } // namespace 240