1 //===- CSETest.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/CSEInfo.h" 11 #include "llvm/CodeGen/GlobalISel/CSEMIRBuilder.h" 12 #include "gtest/gtest.h" 13 14 namespace { 15 16 TEST_F(AArch64GISelMITest, TestCSE) { 17 setUp(); 18 if (!TM) 19 GTEST_SKIP(); 20 21 LLT s16{LLT::scalar(16)}; 22 LLT s32{LLT::scalar(32)}; 23 auto MIBInput = B.buildInstr(TargetOpcode::G_TRUNC, {s16}, {Copies[0]}); 24 auto MIBInput1 = B.buildInstr(TargetOpcode::G_TRUNC, {s16}, {Copies[1]}); 25 auto MIBAdd = B.buildInstr(TargetOpcode::G_ADD, {s16}, {MIBInput, MIBInput}); 26 GISelCSEInfo CSEInfo; 27 CSEInfo.setCSEConfig(std::make_unique<CSEConfigFull>()); 28 CSEInfo.analyze(*MF); 29 B.setCSEInfo(&CSEInfo); 30 CSEMIRBuilder CSEB(B.getState()); 31 32 CSEB.setInsertPt(B.getMBB(), B.getInsertPt()); 33 Register AddReg = MRI->createGenericVirtualRegister(s16); 34 auto MIBAddCopy = 35 CSEB.buildInstr(TargetOpcode::G_ADD, {AddReg}, {MIBInput, MIBInput}); 36 EXPECT_EQ(MIBAddCopy->getOpcode(), TargetOpcode::COPY); 37 auto MIBAdd2 = 38 CSEB.buildInstr(TargetOpcode::G_ADD, {s16}, {MIBInput, MIBInput}); 39 EXPECT_TRUE(&*MIBAdd == &*MIBAdd2); 40 auto MIBAdd4 = 41 CSEB.buildInstr(TargetOpcode::G_ADD, {s16}, {MIBInput, MIBInput}); 42 EXPECT_TRUE(&*MIBAdd == &*MIBAdd4); 43 auto MIBAdd5 = 44 CSEB.buildInstr(TargetOpcode::G_ADD, {s16}, {MIBInput, MIBInput1}); 45 EXPECT_TRUE(&*MIBAdd != &*MIBAdd5); 46 47 // Try building G_CONSTANTS. 48 auto MIBCst = CSEB.buildConstant(s32, 0); 49 auto MIBCst1 = CSEB.buildConstant(s32, 0); 50 EXPECT_TRUE(&*MIBCst == &*MIBCst1); 51 // Try the CFing of BinaryOps. 52 auto MIBCF1 = CSEB.buildInstr(TargetOpcode::G_ADD, {s32}, {MIBCst, MIBCst}); 53 EXPECT_TRUE(&*MIBCF1 == &*MIBCst); 54 55 // Try out building FCONSTANTs. 56 auto MIBFP0 = CSEB.buildFConstant(s32, 1.0); 57 auto MIBFP0_1 = CSEB.buildFConstant(s32, 1.0); 58 EXPECT_TRUE(&*MIBFP0 == &*MIBFP0_1); 59 CSEInfo.print(); 60 61 // Make sure buildConstant with a vector type doesn't crash, and the elements 62 // CSE. 63 auto Splat0 = CSEB.buildConstant(LLT::fixed_vector(2, s32), 0); 64 EXPECT_EQ(TargetOpcode::G_BUILD_VECTOR, Splat0->getOpcode()); 65 EXPECT_EQ(Splat0.getReg(1), Splat0.getReg(2)); 66 EXPECT_EQ(&*MIBCst, MRI->getVRegDef(Splat0.getReg(1))); 67 68 auto FSplat = CSEB.buildFConstant(LLT::fixed_vector(2, s32), 1.0); 69 EXPECT_EQ(TargetOpcode::G_BUILD_VECTOR, FSplat->getOpcode()); 70 EXPECT_EQ(FSplat.getReg(1), FSplat.getReg(2)); 71 EXPECT_EQ(&*MIBFP0, MRI->getVRegDef(FSplat.getReg(1))); 72 73 // Check G_UNMERGE_VALUES 74 auto MIBUnmerge = CSEB.buildUnmerge({s32, s32}, Copies[0]); 75 auto MIBUnmerge2 = CSEB.buildUnmerge({s32, s32}, Copies[0]); 76 EXPECT_TRUE(&*MIBUnmerge == &*MIBUnmerge2); 77 78 // Check G_BUILD_VECTOR 79 Register Reg1 = MRI->createGenericVirtualRegister(s32); 80 Register Reg2 = MRI->createGenericVirtualRegister(s32); 81 auto BuildVec1 = 82 CSEB.buildBuildVector(LLT::fixed_vector(4, 32), {Reg1, Reg2, Reg1, Reg2}); 83 auto BuildVec2 = 84 CSEB.buildBuildVector(LLT::fixed_vector(4, 32), {Reg1, Reg2, Reg1, Reg2}); 85 EXPECT_EQ(TargetOpcode::G_BUILD_VECTOR, BuildVec1->getOpcode()); 86 EXPECT_EQ(TargetOpcode::G_BUILD_VECTOR, BuildVec2->getOpcode()); 87 EXPECT_TRUE(&*BuildVec1 == &*BuildVec2); 88 89 // Check G_BUILD_VECTOR_TRUNC 90 auto BuildVecTrunc1 = CSEB.buildBuildVectorTrunc(LLT::fixed_vector(4, 16), 91 {Reg1, Reg2, Reg1, Reg2}); 92 auto BuildVecTrunc2 = CSEB.buildBuildVectorTrunc(LLT::fixed_vector(4, 16), 93 {Reg1, Reg2, Reg1, Reg2}); 94 EXPECT_EQ(TargetOpcode::G_BUILD_VECTOR_TRUNC, BuildVecTrunc1->getOpcode()); 95 EXPECT_EQ(TargetOpcode::G_BUILD_VECTOR_TRUNC, BuildVecTrunc2->getOpcode()); 96 EXPECT_TRUE(&*BuildVecTrunc1 == &*BuildVecTrunc2); 97 98 // Check G_IMPLICIT_DEF 99 auto Undef0 = CSEB.buildUndef(s32); 100 auto Undef1 = CSEB.buildUndef(s32); 101 EXPECT_EQ(&*Undef0, &*Undef1); 102 103 // If the observer is installed to the MF, CSE can also 104 // track new instructions built without the CSEBuilder and 105 // the newly built instructions are available for CSEing next 106 // time a build call is made through the CSEMIRBuilder. 107 // Additionally, the CSE implementation lazily hashes instructions 108 // (every build call) to give chance for the instruction to be fully 109 // built (say using .addUse().addDef().. so on). 110 GISelObserverWrapper WrapperObserver(&CSEInfo); 111 RAIIMFObsDelInstaller Installer(*MF, WrapperObserver); 112 MachineIRBuilder RegularBuilder(*MF); 113 RegularBuilder.setInsertPt(*EntryMBB, EntryMBB->begin()); 114 auto NonCSEFMul = RegularBuilder.buildInstr(TargetOpcode::G_AND) 115 .addDef(MRI->createGenericVirtualRegister(s32)) 116 .addUse(Copies[0]) 117 .addUse(Copies[1]); 118 auto CSEFMul = 119 CSEB.buildInstr(TargetOpcode::G_AND, {s32}, {Copies[0], Copies[1]}); 120 EXPECT_EQ(&*CSEFMul, &*NonCSEFMul); 121 122 auto ExtractMIB = CSEB.buildInstr(TargetOpcode::G_EXTRACT, {s16}, 123 {Copies[0], static_cast<uint64_t>(0)}); 124 auto ExtractMIB1 = CSEB.buildInstr(TargetOpcode::G_EXTRACT, {s16}, 125 {Copies[0], static_cast<uint64_t>(0)}); 126 auto ExtractMIB2 = CSEB.buildInstr(TargetOpcode::G_EXTRACT, {s16}, 127 {Copies[0], static_cast<uint64_t>(1)}); 128 EXPECT_EQ(&*ExtractMIB, &*ExtractMIB1); 129 EXPECT_NE(&*ExtractMIB, &*ExtractMIB2); 130 131 132 auto SextInRegMIB = CSEB.buildSExtInReg(s16, Copies[0], 0); 133 auto SextInRegMIB1 = CSEB.buildSExtInReg(s16, Copies[0], 0); 134 auto SextInRegMIB2 = CSEB.buildSExtInReg(s16, Copies[0], 1); 135 EXPECT_EQ(&*SextInRegMIB, &*SextInRegMIB1); 136 EXPECT_NE(&*SextInRegMIB, &*SextInRegMIB2); 137 } 138 139 TEST_F(AArch64GISelMITest, TestCSEConstantConfig) { 140 setUp(); 141 if (!TM) 142 GTEST_SKIP(); 143 144 LLT s16{LLT::scalar(16)}; 145 auto MIBInput = B.buildInstr(TargetOpcode::G_TRUNC, {s16}, {Copies[0]}); 146 auto MIBAdd = B.buildInstr(TargetOpcode::G_ADD, {s16}, {MIBInput, MIBInput}); 147 auto MIBZero = B.buildConstant(s16, 0); 148 GISelCSEInfo CSEInfo; 149 CSEInfo.setCSEConfig(std::make_unique<CSEConfigConstantOnly>()); 150 CSEInfo.analyze(*MF); 151 B.setCSEInfo(&CSEInfo); 152 CSEMIRBuilder CSEB(B.getState()); 153 CSEB.setInsertPt(*EntryMBB, EntryMBB->begin()); 154 auto MIBAdd1 = 155 CSEB.buildInstr(TargetOpcode::G_ADD, {s16}, {MIBInput, MIBInput}); 156 // We should CSE constants only. Adds should not be CSEd. 157 EXPECT_TRUE(MIBAdd1->getOpcode() != TargetOpcode::COPY); 158 EXPECT_TRUE(&*MIBAdd1 != &*MIBAdd); 159 // We should CSE constant. 160 auto MIBZeroTmp = CSEB.buildConstant(s16, 0); 161 EXPECT_TRUE(&*MIBZero == &*MIBZeroTmp); 162 163 // Check G_IMPLICIT_DEF 164 auto Undef0 = CSEB.buildUndef(s16); 165 auto Undef1 = CSEB.buildUndef(s16); 166 EXPECT_EQ(&*Undef0, &*Undef1); 167 } 168 169 TEST_F(AArch64GISelMITest, TestCSEImmediateNextCSE) { 170 setUp(); 171 if (!TM) 172 GTEST_SKIP(); 173 174 LLT s32{LLT::scalar(32)}; 175 // We want to check that when the CSE hit is on the next instruction, i.e. at 176 // the current insert pt, that the insertion point is moved ahead of the 177 // instruction. 178 179 GISelCSEInfo CSEInfo; 180 CSEInfo.setCSEConfig(std::make_unique<CSEConfigConstantOnly>()); 181 CSEInfo.analyze(*MF); 182 B.setCSEInfo(&CSEInfo); 183 CSEMIRBuilder CSEB(B.getState()); 184 CSEB.buildConstant(s32, 0); 185 auto MIBCst2 = CSEB.buildConstant(s32, 2); 186 187 // Move the insert point before the second constant. 188 CSEB.setInsertPt(CSEB.getMBB(), --CSEB.getInsertPt()); 189 auto MIBCst3 = CSEB.buildConstant(s32, 2); 190 EXPECT_TRUE(&*MIBCst2 == &*MIBCst3); 191 EXPECT_TRUE(CSEB.getInsertPt() == CSEB.getMBB().end()); 192 } 193 194 TEST_F(AArch64GISelMITest, TestConstantFoldCTL) { 195 setUp(); 196 if (!TM) 197 GTEST_SKIP(); 198 199 LLT s32 = LLT::scalar(32); 200 201 GISelCSEInfo CSEInfo; 202 CSEInfo.setCSEConfig(std::make_unique<CSEConfigConstantOnly>()); 203 CSEInfo.analyze(*MF); 204 B.setCSEInfo(&CSEInfo); 205 CSEMIRBuilder CSEB(B.getState()); 206 auto Cst8 = CSEB.buildConstant(s32, 8); 207 auto *CtlzDef = &*CSEB.buildCTLZ(s32, Cst8); 208 EXPECT_TRUE(CtlzDef->getOpcode() == TargetOpcode::G_CONSTANT); 209 EXPECT_TRUE(CtlzDef->getOperand(1).getCImm()->getZExtValue() == 28); 210 211 // Test vector. 212 auto Cst16 = CSEB.buildConstant(s32, 16); 213 auto Cst32 = CSEB.buildConstant(s32, 32); 214 auto Cst64 = CSEB.buildConstant(s32, 64); 215 LLT VecTy = LLT::fixed_vector(4, s32); 216 auto BV = CSEB.buildBuildVector(VecTy, {Cst8.getReg(0), Cst16.getReg(0), 217 Cst32.getReg(0), Cst64.getReg(0)}); 218 CSEB.buildCTLZ(VecTy, BV); 219 220 auto CheckStr = R"( 221 ; CHECK: [[CST8:%[0-9]+]]:_(s32) = G_CONSTANT i32 8 222 ; CHECK: [[CST28:%[0-9]+]]:_(s32) = G_CONSTANT i32 28 223 ; CHECK: [[CST16:%[0-9]+]]:_(s32) = G_CONSTANT i32 16 224 ; CHECK: [[CST32:%[0-9]+]]:_(s32) = G_CONSTANT i32 32 225 ; CHECK: [[CST64:%[0-9]+]]:_(s32) = G_CONSTANT i32 64 226 ; CHECK: [[BV1:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[CST8]]:_(s32), [[CST16]]:_(s32), [[CST32]]:_(s32), [[CST64]]:_(s32) 227 ; CHECK: [[CST27:%[0-9]+]]:_(s32) = G_CONSTANT i32 27 228 ; CHECK: [[CST26:%[0-9]+]]:_(s32) = G_CONSTANT i32 26 229 ; CHECK: [[CST25:%[0-9]+]]:_(s32) = G_CONSTANT i32 25 230 ; CHECK: [[BV2:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[CST28]]:_(s32), [[CST27]]:_(s32), [[CST26]]:_(s32), [[CST25]]:_(s32) 231 )"; 232 233 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 234 } 235 236 TEST_F(AArch64GISelMITest, TestConstantFoldCTT) { 237 setUp(); 238 if (!TM) 239 GTEST_SKIP(); 240 241 LLT s32 = LLT::scalar(32); 242 243 GISelCSEInfo CSEInfo; 244 CSEInfo.setCSEConfig(std::make_unique<CSEConfigConstantOnly>()); 245 CSEInfo.analyze(*MF); 246 B.setCSEInfo(&CSEInfo); 247 CSEMIRBuilder CSEB(B.getState()); 248 auto Cst8 = CSEB.buildConstant(s32, 8); 249 auto *CttzDef = &*CSEB.buildCTTZ(s32, Cst8); 250 EXPECT_TRUE(CttzDef->getOpcode() == TargetOpcode::G_CONSTANT); 251 EXPECT_TRUE(CttzDef->getOperand(1).getCImm()->getZExtValue() == 3); 252 253 // Test vector. 254 auto Cst16 = CSEB.buildConstant(s32, 16); 255 auto Cst32 = CSEB.buildConstant(s32, 32); 256 auto Cst64 = CSEB.buildConstant(s32, 64); 257 LLT VecTy = LLT::fixed_vector(4, s32); 258 auto BV = CSEB.buildBuildVector(VecTy, {Cst8.getReg(0), Cst16.getReg(0), 259 Cst32.getReg(0), Cst64.getReg(0)}); 260 CSEB.buildCTTZ(VecTy, BV); 261 262 auto CheckStr = R"( 263 ; CHECK: [[CST8:%[0-9]+]]:_(s32) = G_CONSTANT i32 8 264 ; CHECK: [[CST3:%[0-9]+]]:_(s32) = G_CONSTANT i32 3 265 ; CHECK: [[CST16:%[0-9]+]]:_(s32) = G_CONSTANT i32 16 266 ; CHECK: [[CST32:%[0-9]+]]:_(s32) = G_CONSTANT i32 32 267 ; CHECK: [[CST64:%[0-9]+]]:_(s32) = G_CONSTANT i32 64 268 ; CHECK: [[BV1:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[CST8]]:_(s32), [[CST16]]:_(s32), [[CST32]]:_(s32), [[CST64]]:_(s32) 269 ; CHECK: [[CST27:%[0-9]+]]:_(s32) = G_CONSTANT i32 4 270 ; CHECK: [[CST26:%[0-9]+]]:_(s32) = G_CONSTANT i32 5 271 ; CHECK: [[CST25:%[0-9]+]]:_(s32) = G_CONSTANT i32 6 272 ; CHECK: [[BV2:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[CST3]]:_(s32), [[CST27]]:_(s32), [[CST26]]:_(s32), [[CST25]]:_(s32) 273 )"; 274 275 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 276 } 277 278 TEST_F(AArch64GISelMITest, TestConstantFoldICMP) { 279 setUp(); 280 if (!TM) 281 GTEST_SKIP(); 282 283 LLT s32 = LLT::scalar(32); 284 LLT s1 = LLT::scalar(1); 285 286 GISelCSEInfo CSEInfo; 287 CSEInfo.setCSEConfig(std::make_unique<CSEConfigConstantOnly>()); 288 CSEInfo.analyze(*MF); 289 B.setCSEInfo(&CSEInfo); 290 CSEMIRBuilder CSEB(B.getState()); 291 292 auto One = CSEB.buildConstant(s32, 1); 293 auto Two = CSEB.buildConstant(s32, 2); 294 auto MinusOne = CSEB.buildConstant(s32, -1); 295 auto MinusTwo = CSEB.buildConstant(s32, -2); 296 297 // ICMP_EQ 298 { 299 auto I = CSEB.buildICmp(CmpInst::Predicate::ICMP_EQ, s1, One, One); 300 EXPECT_TRUE(I->getOpcode() == TargetOpcode::G_CONSTANT); 301 EXPECT_TRUE(I->getOperand(1).getCImm()->getZExtValue()); 302 } 303 304 // ICMP_NE 305 { 306 auto I = CSEB.buildICmp(CmpInst::Predicate::ICMP_NE, s1, One, Two); 307 EXPECT_TRUE(I->getOpcode() == TargetOpcode::G_CONSTANT); 308 EXPECT_TRUE(I->getOperand(1).getCImm()->getZExtValue()); 309 } 310 311 // ICMP_UGT 312 { 313 auto I = CSEB.buildICmp(CmpInst::Predicate::ICMP_UGT, s1, Two, One); 314 EXPECT_TRUE(I->getOpcode() == TargetOpcode::G_CONSTANT); 315 EXPECT_TRUE(I->getOperand(1).getCImm()->getZExtValue()); 316 } 317 318 // ICMP_UGE 319 { 320 auto I = CSEB.buildICmp(CmpInst::Predicate::ICMP_UGE, s1, One, One); 321 EXPECT_TRUE(I->getOpcode() == TargetOpcode::G_CONSTANT); 322 EXPECT_TRUE(I->getOperand(1).getCImm()->getZExtValue()); 323 } 324 325 // ICMP_ULT 326 { 327 auto I = CSEB.buildICmp(CmpInst::Predicate::ICMP_ULT, s1, One, Two); 328 EXPECT_TRUE(I->getOpcode() == TargetOpcode::G_CONSTANT); 329 EXPECT_TRUE(I->getOperand(1).getCImm()->getZExtValue()); 330 } 331 332 // ICMP_ULE 333 { 334 auto I = CSEB.buildICmp(CmpInst::Predicate::ICMP_ULE, s1, Two, Two); 335 EXPECT_TRUE(I->getOpcode() == TargetOpcode::G_CONSTANT); 336 EXPECT_TRUE(I->getOperand(1).getCImm()->getZExtValue()); 337 } 338 339 // ICMP_SGT 340 { 341 auto I = 342 CSEB.buildICmp(CmpInst::Predicate::ICMP_SGT, s1, MinusOne, MinusTwo); 343 EXPECT_TRUE(I->getOpcode() == TargetOpcode::G_CONSTANT); 344 EXPECT_TRUE(I->getOperand(1).getCImm()->getZExtValue()); 345 } 346 347 // ICMP_SGE 348 { 349 auto I = 350 CSEB.buildICmp(CmpInst::Predicate::ICMP_SGE, s1, MinusOne, MinusOne); 351 EXPECT_TRUE(I->getOpcode() == TargetOpcode::G_CONSTANT); 352 EXPECT_TRUE(I->getOperand(1).getCImm()->getZExtValue()); 353 } 354 355 // ICMP_SLT 356 { 357 auto I = 358 CSEB.buildICmp(CmpInst::Predicate::ICMP_SLT, s1, MinusTwo, MinusOne); 359 EXPECT_TRUE(I->getOpcode() == TargetOpcode::G_CONSTANT); 360 EXPECT_TRUE(I->getOperand(1).getCImm()->getZExtValue()); 361 } 362 363 // ICMP_SLE 364 { 365 auto I = 366 CSEB.buildICmp(CmpInst::Predicate::ICMP_SLE, s1, MinusTwo, MinusOne); 367 EXPECT_TRUE(I->getOpcode() == TargetOpcode::G_CONSTANT); 368 EXPECT_TRUE(I->getOperand(1).getCImm()->getZExtValue()); 369 } 370 371 LLT VecTy = LLT::fixed_vector(2, s32); 372 LLT DstTy = LLT::fixed_vector(2, s1); 373 auto Three = CSEB.buildConstant(s32, 3); 374 auto MinusThree = CSEB.buildConstant(s32, -3); 375 auto OneOne = CSEB.buildBuildVector(VecTy, {One.getReg(0), One.getReg(0)}); 376 auto OneTwo = CSEB.buildBuildVector(VecTy, {One.getReg(0), Two.getReg(0)}); 377 auto TwoThree = 378 CSEB.buildBuildVector(VecTy, {Two.getReg(0), Three.getReg(0)}); 379 auto MinusOneOne = 380 CSEB.buildBuildVector(VecTy, {MinusOne.getReg(0), MinusOne.getReg(0)}); 381 auto MinusOneTwo = 382 CSEB.buildBuildVector(VecTy, {MinusOne.getReg(0), MinusTwo.getReg(0)}); 383 auto MinusTwoThree = 384 CSEB.buildBuildVector(VecTy, {MinusTwo.getReg(0), MinusThree.getReg(0)}); 385 386 // ICMP_EQ 387 CSEB.buildICmp(CmpInst::Predicate::ICMP_EQ, DstTy, OneOne, OneOne); 388 389 // ICMP_NE 390 CSEB.buildICmp(CmpInst::Predicate::ICMP_NE, DstTy, OneOne, OneTwo); 391 392 // ICMP_UGT 393 CSEB.buildICmp(CmpInst::Predicate::ICMP_UGT, DstTy, TwoThree, OneTwo); 394 395 // ICMP_UGE 396 CSEB.buildICmp(CmpInst::Predicate::ICMP_UGE, DstTy, OneTwo, OneOne); 397 398 // ICMP_ULT 399 CSEB.buildICmp(CmpInst::Predicate::ICMP_ULT, DstTy, OneOne, OneTwo); 400 401 // ICMP_ULE 402 CSEB.buildICmp(CmpInst::Predicate::ICMP_ULE, DstTy, OneTwo, OneOne); 403 404 // ICMP_SGT 405 CSEB.buildICmp(CmpInst::Predicate::ICMP_SGT, DstTy, MinusOneTwo, 406 MinusTwoThree); 407 408 // ICMP_SGE 409 CSEB.buildICmp(CmpInst::Predicate::ICMP_SGE, DstTy, MinusOneTwo, MinusOneOne); 410 411 // ICMP_SLT 412 CSEB.buildICmp(CmpInst::Predicate::ICMP_SLT, DstTy, MinusTwoThree, 413 MinusOneTwo); 414 415 // ICMP_SLE 416 CSEB.buildICmp(CmpInst::Predicate::ICMP_SLE, DstTy, MinusOneTwo, MinusOneOne); 417 418 auto CheckStr = R"( 419 ; CHECK: [[One:%[0-9]+]]:_(s32) = G_CONSTANT i32 1 420 ; CHECK: [[Two:%[0-9]+]]:_(s32) = G_CONSTANT i32 2 421 ; CHECK: [[MinusOne:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1 422 ; CHECK: [[MinusTwo:%[0-9]+]]:_(s32) = G_CONSTANT i32 -2 423 ; CHECK: [[True:%[0-9]+]]:_(s1) = G_CONSTANT i1 true 424 ; CHECK: [[Three:%[0-9]+]]:_(s32) = G_CONSTANT i32 3 425 ; CHECK: [[MinusThree:%[0-9]+]]:_(s32) = G_CONSTANT i32 -3 426 ; CHECK: {{%[0-9]+}}:_(<2 x s32>) = G_BUILD_VECTOR [[One]]:_(s32), [[One]]:_(s32) 427 ; CHECK: {{%[0-9]+}}:_(<2 x s32>) = G_BUILD_VECTOR [[One]]:_(s32), [[Two]]:_(s32) 428 ; CHECK: {{%[0-9]+}}:_(<2 x s32>) = G_BUILD_VECTOR [[Two]]:_(s32), [[Three]]:_(s32) 429 ; CHECK: {{%[0-9]+}}:_(<2 x s32>) = G_BUILD_VECTOR [[MinusOne]]:_(s32), [[MinusOne]]:_(s32) 430 ; CHECK: {{%[0-9]+}}:_(<2 x s32>) = G_BUILD_VECTOR [[MinusOne]]:_(s32), [[MinusTwo]]:_(s32) 431 ; CHECK: {{%[0-9]+}}:_(<2 x s32>) = G_BUILD_VECTOR [[MinusTwo]]:_(s32), [[MinusThree]]:_(s32) 432 ; CHECK: {{%[0-9]+}}:_(<2 x s1>) = G_BUILD_VECTOR [[True]]:_(s1), [[True]]:_(s1) 433 ; CHECK: [[False:%[0-9]+]]:_(s1) = G_CONSTANT i1 false 434 ; CHECK: {{%[0-9]+}}:_(<2 x s1>) = G_BUILD_VECTOR [[False]]:_(s1), [[True]]:_(s1) 435 ; CHECK: {{%[0-9]+}}:_(<2 x s1>) = G_BUILD_VECTOR [[True]]:_(s1), [[True]]:_(s1) 436 ; CHECK: {{%[0-9]+}}:_(<2 x s1>) = G_BUILD_VECTOR [[True]]:_(s1), [[True]]:_(s1) 437 ; CHECK: {{%[0-9]+}}:_(<2 x s1>) = G_BUILD_VECTOR [[False]]:_(s1), [[True]]:_(s1) 438 ; CHECK: {{%[0-9]+}}:_(<2 x s1>) = G_BUILD_VECTOR [[True]]:_(s1), [[False]]:_(s1) 439 ; CHECK: {{%[0-9]+}}:_(<2 x s1>) = G_BUILD_VECTOR [[True]]:_(s1), [[True]]:_(s1) 440 ; CHECK: {{%[0-9]+}}:_(<2 x s1>) = G_BUILD_VECTOR [[True]]:_(s1), [[False]]:_(s1) 441 ; CHECK: {{%[0-9]+}}:_(<2 x s1>) = G_BUILD_VECTOR [[True]]:_(s1), [[True]]:_(s1) 442 ; CHECK: {{%[0-9]+}}:_(<2 x s1>) = G_BUILD_VECTOR [[True]]:_(s1), [[True]]:_(s1) 443 )"; 444 445 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; 446 } 447 448 } // namespace 449