626 lines · cpp
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-exception6//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 14namespace {15 16TEST_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 elements62 // 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_VALUES74 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_FADD79 {80 auto MIBFAdd = CSEB.buildFAdd(s32, Copies[0], Copies[1]);81 auto MIBFAdd2 = CSEB.buildFAdd(s32, Copies[0], Copies[1]);82 EXPECT_TRUE(&*MIBFAdd == &*MIBFAdd2);83 84 auto MIBFAdd3 =85 CSEB.buildFAdd(s32, Copies[0], Copies[1], MachineInstr::FmNsz);86 EXPECT_FALSE(&*MIBFAdd == &*MIBFAdd3);87 88 MIBFAdd2->setFlag(MachineInstr::FmNsz);89 MIBFAdd2->clearFlag(MachineInstr::FmNsz);90 EXPECT_TRUE(&*MIBFAdd == &*MIBFAdd2);91 }92 93 // Check G_FSUB94 {95 auto MIBFSub = CSEB.buildFSub(s32, Copies[0], Copies[1]);96 auto MIBFSub2 = CSEB.buildFSub(s32, Copies[0], Copies[1]);97 EXPECT_TRUE(&*MIBFSub == &*MIBFSub2);98 99 auto MIBFSub3 =100 CSEB.buildFSub(s32, Copies[0], Copies[1], MachineInstr::FmNoNans);101 EXPECT_FALSE(&*MIBFSub == &*MIBFSub3);102 103 MIBFSub2->setFlag(MachineInstr::FmNoNans);104 MIBFSub2->clearFlag(MachineInstr::FmNoNans);105 EXPECT_TRUE(&*MIBFSub == &*MIBFSub2);106 }107 108 // Check G_FMUL109 {110 auto MIBFMul = CSEB.buildFMul(s32, Copies[0], Copies[1]);111 auto MIBFMul2 = CSEB.buildFMul(s32, Copies[0], Copies[1]);112 EXPECT_TRUE(&*MIBFMul == &*MIBFMul2);113 114 auto MIBFMul3 =115 CSEB.buildFMul(s32, Copies[0], Copies[1], MachineInstr::FmNoNans);116 EXPECT_FALSE(&*MIBFMul == &*MIBFMul3);117 118 MIBFMul2->setFlag(MachineInstr::FmNoNans);119 MIBFMul2->clearFlag(MachineInstr::FmNoNans);120 EXPECT_TRUE(&*MIBFMul == &*MIBFMul2);121 }122 123 // Check G_FDIV124 {125 auto MIBFDiv = CSEB.buildFDiv(s32, Copies[0], Copies[1]);126 auto MIBFDiv2 = CSEB.buildFDiv(s32, Copies[0], Copies[1]);127 EXPECT_TRUE(&*MIBFDiv == &*MIBFDiv2);128 129 auto MIBFDiv3 =130 CSEB.buildFDiv(s32, Copies[0], Copies[1], MachineInstr::FmNoNans);131 EXPECT_FALSE(&*MIBFDiv == &*MIBFDiv3);132 133 MIBFDiv2->setFlag(MachineInstr::FmNoNans);134 MIBFDiv2->clearFlag(MachineInstr::FmNoNans);135 EXPECT_TRUE(&*MIBFDiv == &*MIBFDiv2);136 }137 138 // Check G_FABS139 {140 auto MIBFAbs = CSEB.buildFAbs(s32, Copies[0]);141 auto MIBFAbs2 = CSEB.buildFAbs(s32, Copies[0]);142 EXPECT_TRUE(&*MIBFAbs == &*MIBFAbs2);143 144 auto MIBFAbs3 = CSEB.buildFAbs(s32, Copies[0], MachineInstr::FmNsz);145 EXPECT_FALSE(&*MIBFAbs == &*MIBFAbs3);146 147 MIBFAbs2->setFlag(MachineInstr::FmNsz);148 MIBFAbs2->clearFlag(MachineInstr::FmNsz);149 EXPECT_TRUE(&*MIBFAbs == &*MIBFAbs2);150 }151 152 // Check G_FMINNUM/F_MAXNUM:153 {154 auto MIBFMinNum = CSEB.buildFMinNum(s32, Copies[0], Copies[1]);155 auto MIBFMinNum2 = CSEB.buildFMinNum(s32, Copies[0], Copies[1]);156 EXPECT_TRUE(&*MIBFMinNum == &*MIBFMinNum2);157 158 auto MIBFMinNum3 =159 CSEB.buildFMinNum(s32, Copies[0], Copies[1], MachineInstr::FmNsz);160 EXPECT_FALSE(&*MIBFMinNum == &*MIBFMinNum3);161 162 MIBFMinNum2->setFlag(MachineInstr::FmNsz);163 MIBFMinNum2->clearFlag(MachineInstr::FmNsz);164 EXPECT_TRUE(&*MIBFMinNum == &*MIBFMinNum2);165 }166 167 {168 auto MIBFMaxNum = CSEB.buildFMaxNum(s32, Copies[0], Copies[1]);169 auto MIBFMaxNum2 = CSEB.buildFMaxNum(s32, Copies[0], Copies[1]);170 EXPECT_TRUE(&*MIBFMaxNum == &*MIBFMaxNum2);171 172 auto MIBFMaxNum3 =173 CSEB.buildFMaxNum(s32, Copies[0], Copies[1], MachineInstr::FmNsz);174 EXPECT_FALSE(&*MIBFMaxNum == &*MIBFMaxNum3);175 176 MIBFMaxNum2->setFlag(MachineInstr::FmNsz);177 MIBFMaxNum2->clearFlag(MachineInstr::FmNsz);178 EXPECT_TRUE(&*MIBFMaxNum == &*MIBFMaxNum2);179 }180 181 // Check G_FMINNUM_IEEE/F_MAXNUM_IEEE:182 {183 auto MIBFMinNumIEEE = CSEB.buildFMinNumIEEE(s32, Copies[0], Copies[1]);184 auto MIBFMinNumIEEE2 = CSEB.buildFMinNumIEEE(s32, Copies[0], Copies[1]);185 EXPECT_TRUE(&*MIBFMinNumIEEE == &*MIBFMinNumIEEE2);186 187 auto MIBFMinNumIEEE3 =188 CSEB.buildFMinNumIEEE(s32, Copies[0], Copies[1], MachineInstr::FmNsz);189 EXPECT_FALSE(&*MIBFMinNumIEEE == &*MIBFMinNumIEEE3);190 191 MIBFMinNumIEEE2->setFlag(MachineInstr::FmNsz);192 MIBFMinNumIEEE2->clearFlag(MachineInstr::FmNsz);193 EXPECT_TRUE(&*MIBFMinNumIEEE == &*MIBFMinNumIEEE2);194 }195 196 {197 auto MIBFMaxNumIEEE = CSEB.buildFMaxNumIEEE(s32, Copies[0], Copies[1]);198 auto MIBFMaxNumIEEE2 = CSEB.buildFMaxNumIEEE(s32, Copies[0], Copies[1]);199 EXPECT_TRUE(&*MIBFMaxNumIEEE == &*MIBFMaxNumIEEE2);200 201 auto MIBFMaxNumIEEE3 =202 CSEB.buildFMaxNumIEEE(s32, Copies[0], Copies[1], MachineInstr::FmNsz);203 EXPECT_FALSE(&*MIBFMaxNumIEEE == &*MIBFMaxNumIEEE3);204 205 MIBFMaxNumIEEE2->setFlag(MachineInstr::FmNsz);206 MIBFMaxNumIEEE2->clearFlag(MachineInstr::FmNsz);207 EXPECT_TRUE(&*MIBFMaxNumIEEE == &*MIBFMaxNumIEEE2);208 }209 210 // Check G_BUILD_VECTOR211 Register Reg1 = MRI->createGenericVirtualRegister(s32);212 Register Reg2 = MRI->createGenericVirtualRegister(s32);213 auto BuildVec1 =214 CSEB.buildBuildVector(LLT::fixed_vector(4, 32), {Reg1, Reg2, Reg1, Reg2});215 auto BuildVec2 =216 CSEB.buildBuildVector(LLT::fixed_vector(4, 32), {Reg1, Reg2, Reg1, Reg2});217 EXPECT_EQ(TargetOpcode::G_BUILD_VECTOR, BuildVec1->getOpcode());218 EXPECT_EQ(TargetOpcode::G_BUILD_VECTOR, BuildVec2->getOpcode());219 EXPECT_TRUE(&*BuildVec1 == &*BuildVec2);220 221 // Check G_BUILD_VECTOR_TRUNC222 auto BuildVecTrunc1 = CSEB.buildBuildVectorTrunc(LLT::fixed_vector(4, 16),223 {Reg1, Reg2, Reg1, Reg2});224 auto BuildVecTrunc2 = CSEB.buildBuildVectorTrunc(LLT::fixed_vector(4, 16),225 {Reg1, Reg2, Reg1, Reg2});226 EXPECT_EQ(TargetOpcode::G_BUILD_VECTOR_TRUNC, BuildVecTrunc1->getOpcode());227 EXPECT_EQ(TargetOpcode::G_BUILD_VECTOR_TRUNC, BuildVecTrunc2->getOpcode());228 EXPECT_TRUE(&*BuildVecTrunc1 == &*BuildVecTrunc2);229 230 // Check G_IMPLICIT_DEF231 auto Undef0 = CSEB.buildUndef(s32);232 auto Undef1 = CSEB.buildUndef(s32);233 EXPECT_EQ(&*Undef0, &*Undef1);234 235 // If the observer is installed to the MF, CSE can also236 // track new instructions built without the CSEBuilder and237 // the newly built instructions are available for CSEing next238 // time a build call is made through the CSEMIRBuilder.239 // Additionally, the CSE implementation lazily hashes instructions240 // (every build call) to give chance for the instruction to be fully241 // built (say using .addUse().addDef().. so on).242 GISelObserverWrapper WrapperObserver(&CSEInfo);243 RAIIMFObsDelInstaller Installer(*MF, WrapperObserver);244 MachineIRBuilder RegularBuilder(*MF);245 RegularBuilder.setInsertPt(*EntryMBB, EntryMBB->begin());246 auto NonCSEFMul = RegularBuilder.buildInstr(TargetOpcode::G_AND)247 .addDef(MRI->createGenericVirtualRegister(s32))248 .addUse(Copies[0])249 .addUse(Copies[1]);250 auto CSEFMul =251 CSEB.buildInstr(TargetOpcode::G_AND, {s32}, {Copies[0], Copies[1]});252 EXPECT_EQ(&*CSEFMul, &*NonCSEFMul);253 254 auto ExtractMIB = CSEB.buildInstr(TargetOpcode::G_EXTRACT, {s16},255 {Copies[0], static_cast<uint64_t>(0)});256 auto ExtractMIB1 = CSEB.buildInstr(TargetOpcode::G_EXTRACT, {s16},257 {Copies[0], static_cast<uint64_t>(0)});258 auto ExtractMIB2 = CSEB.buildInstr(TargetOpcode::G_EXTRACT, {s16},259 {Copies[0], static_cast<uint64_t>(1)});260 EXPECT_EQ(&*ExtractMIB, &*ExtractMIB1);261 EXPECT_NE(&*ExtractMIB, &*ExtractMIB2);262 263 264 auto SextInRegMIB = CSEB.buildSExtInReg(s16, Copies[0], 0);265 auto SextInRegMIB1 = CSEB.buildSExtInReg(s16, Copies[0], 0);266 auto SextInRegMIB2 = CSEB.buildSExtInReg(s16, Copies[0], 1);267 EXPECT_EQ(&*SextInRegMIB, &*SextInRegMIB1);268 EXPECT_NE(&*SextInRegMIB, &*SextInRegMIB2);269}270 271TEST_F(AArch64GISelMITest, TestCSEConstantConfig) {272 setUp();273 if (!TM)274 GTEST_SKIP();275 276 LLT s16{LLT::scalar(16)};277 auto MIBInput = B.buildInstr(TargetOpcode::G_TRUNC, {s16}, {Copies[0]});278 auto MIBAdd = B.buildInstr(TargetOpcode::G_ADD, {s16}, {MIBInput, MIBInput});279 auto MIBZero = B.buildConstant(s16, 0);280 GISelCSEInfo CSEInfo;281 CSEInfo.setCSEConfig(std::make_unique<CSEConfigConstantOnly>());282 CSEInfo.analyze(*MF);283 B.setCSEInfo(&CSEInfo);284 CSEMIRBuilder CSEB(B.getState());285 CSEB.setInsertPt(*EntryMBB, EntryMBB->begin());286 auto MIBAdd1 =287 CSEB.buildInstr(TargetOpcode::G_ADD, {s16}, {MIBInput, MIBInput});288 // We should CSE constants only. Adds should not be CSEd.289 EXPECT_TRUE(MIBAdd1->getOpcode() != TargetOpcode::COPY);290 EXPECT_TRUE(&*MIBAdd1 != &*MIBAdd);291 // We should CSE constant.292 auto MIBZeroTmp = CSEB.buildConstant(s16, 0);293 EXPECT_TRUE(&*MIBZero == &*MIBZeroTmp);294 295 // Check G_IMPLICIT_DEF296 auto Undef0 = CSEB.buildUndef(s16);297 auto Undef1 = CSEB.buildUndef(s16);298 EXPECT_EQ(&*Undef0, &*Undef1);299}300 301TEST_F(AArch64GISelMITest, TestCSEImmediateNextCSE) {302 setUp();303 if (!TM)304 GTEST_SKIP();305 306 LLT s32{LLT::scalar(32)};307 // We want to check that when the CSE hit is on the next instruction, i.e. at308 // the current insert pt, that the insertion point is moved ahead of the309 // instruction.310 311 GISelCSEInfo CSEInfo;312 CSEInfo.setCSEConfig(std::make_unique<CSEConfigConstantOnly>());313 CSEInfo.analyze(*MF);314 B.setCSEInfo(&CSEInfo);315 CSEMIRBuilder CSEB(B.getState());316 CSEB.buildConstant(s32, 0);317 auto MIBCst2 = CSEB.buildConstant(s32, 2);318 319 // Move the insert point before the second constant.320 CSEB.setInsertPt(CSEB.getMBB(), --CSEB.getInsertPt());321 auto MIBCst3 = CSEB.buildConstant(s32, 2);322 EXPECT_TRUE(&*MIBCst2 == &*MIBCst3);323 EXPECT_TRUE(CSEB.getInsertPt() == CSEB.getMBB().end());324}325 326TEST_F(AArch64GISelMITest, TestConstantFoldCTL) {327 setUp();328 if (!TM)329 GTEST_SKIP();330 331 LLT s32 = LLT::scalar(32);332 333 GISelCSEInfo CSEInfo;334 CSEInfo.setCSEConfig(std::make_unique<CSEConfigConstantOnly>());335 CSEInfo.analyze(*MF);336 B.setCSEInfo(&CSEInfo);337 CSEMIRBuilder CSEB(B.getState());338 auto Cst8 = CSEB.buildConstant(s32, 8);339 auto *CtlzDef = &*CSEB.buildCTLZ(s32, Cst8);340 EXPECT_TRUE(CtlzDef->getOpcode() == TargetOpcode::G_CONSTANT);341 EXPECT_TRUE(CtlzDef->getOperand(1).getCImm()->getZExtValue() == 28);342 343 // Test vector.344 auto Cst16 = CSEB.buildConstant(s32, 16);345 auto Cst32 = CSEB.buildConstant(s32, 32);346 auto Cst64 = CSEB.buildConstant(s32, 64);347 LLT VecTy = LLT::fixed_vector(4, s32);348 auto BV = CSEB.buildBuildVector(VecTy, {Cst8.getReg(0), Cst16.getReg(0),349 Cst32.getReg(0), Cst64.getReg(0)});350 CSEB.buildCTLZ(VecTy, BV);351 352 auto CheckStr = R"(353 ; CHECK: [[CST8:%[0-9]+]]:_(s32) = G_CONSTANT i32 8354 ; CHECK: [[CST28:%[0-9]+]]:_(s32) = G_CONSTANT i32 28355 ; CHECK: [[CST16:%[0-9]+]]:_(s32) = G_CONSTANT i32 16356 ; CHECK: [[CST32:%[0-9]+]]:_(s32) = G_CONSTANT i32 32357 ; CHECK: [[CST64:%[0-9]+]]:_(s32) = G_CONSTANT i32 64358 ; CHECK: [[BV1:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[CST8]]:_(s32), [[CST16]]:_(s32), [[CST32]]:_(s32), [[CST64]]:_(s32)359 ; CHECK: [[CST27:%[0-9]+]]:_(s32) = G_CONSTANT i32 27360 ; CHECK: [[CST26:%[0-9]+]]:_(s32) = G_CONSTANT i32 26361 ; CHECK: [[CST25:%[0-9]+]]:_(s32) = G_CONSTANT i32 25362 ; CHECK: [[BV2:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[CST28]]:_(s32), [[CST27]]:_(s32), [[CST26]]:_(s32), [[CST25]]:_(s32)363 )";364 365 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;366}367 368TEST_F(AArch64GISelMITest, TestConstantFoldCTT) {369 setUp();370 if (!TM)371 GTEST_SKIP();372 373 LLT s32 = LLT::scalar(32);374 375 GISelCSEInfo CSEInfo;376 CSEInfo.setCSEConfig(std::make_unique<CSEConfigConstantOnly>());377 CSEInfo.analyze(*MF);378 B.setCSEInfo(&CSEInfo);379 CSEMIRBuilder CSEB(B.getState());380 auto Cst8 = CSEB.buildConstant(s32, 8);381 auto *CttzDef = &*CSEB.buildCTTZ(s32, Cst8);382 EXPECT_TRUE(CttzDef->getOpcode() == TargetOpcode::G_CONSTANT);383 EXPECT_TRUE(CttzDef->getOperand(1).getCImm()->getZExtValue() == 3);384 385 // Test vector.386 auto Cst16 = CSEB.buildConstant(s32, 16);387 auto Cst32 = CSEB.buildConstant(s32, 32);388 auto Cst64 = CSEB.buildConstant(s32, 64);389 LLT VecTy = LLT::fixed_vector(4, s32);390 auto BV = CSEB.buildBuildVector(VecTy, {Cst8.getReg(0), Cst16.getReg(0),391 Cst32.getReg(0), Cst64.getReg(0)});392 CSEB.buildCTTZ(VecTy, BV);393 394 auto CheckStr = R"(395 ; CHECK: [[CST8:%[0-9]+]]:_(s32) = G_CONSTANT i32 8396 ; CHECK: [[CST3:%[0-9]+]]:_(s32) = G_CONSTANT i32 3397 ; CHECK: [[CST16:%[0-9]+]]:_(s32) = G_CONSTANT i32 16398 ; CHECK: [[CST32:%[0-9]+]]:_(s32) = G_CONSTANT i32 32399 ; CHECK: [[CST64:%[0-9]+]]:_(s32) = G_CONSTANT i32 64400 ; CHECK: [[BV1:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[CST8]]:_(s32), [[CST16]]:_(s32), [[CST32]]:_(s32), [[CST64]]:_(s32)401 ; CHECK: [[CST27:%[0-9]+]]:_(s32) = G_CONSTANT i32 4402 ; CHECK: [[CST26:%[0-9]+]]:_(s32) = G_CONSTANT i32 5403 ; CHECK: [[CST25:%[0-9]+]]:_(s32) = G_CONSTANT i32 6404 ; CHECK: [[BV2:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[CST3]]:_(s32), [[CST27]]:_(s32), [[CST26]]:_(s32), [[CST25]]:_(s32)405 )";406 407 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;408}409 410TEST_F(AArch64GISelMITest, TestConstantFoldICMP) {411 setUp();412 if (!TM)413 GTEST_SKIP();414 415 LLT s32 = LLT::scalar(32);416 LLT s1 = LLT::scalar(1);417 418 GISelCSEInfo CSEInfo;419 CSEInfo.setCSEConfig(std::make_unique<CSEConfigConstantOnly>());420 CSEInfo.analyze(*MF);421 B.setCSEInfo(&CSEInfo);422 CSEMIRBuilder CSEB(B.getState());423 424 auto One = CSEB.buildConstant(s32, 1);425 auto Two = CSEB.buildConstant(s32, 2);426 auto MinusOne = CSEB.buildConstant(s32, -1);427 auto MinusTwo = CSEB.buildConstant(s32, -2);428 429 // ICMP_EQ430 {431 auto I = CSEB.buildICmp(CmpInst::Predicate::ICMP_EQ, s1, One, One);432 EXPECT_TRUE(I->getOpcode() == TargetOpcode::G_CONSTANT);433 EXPECT_TRUE(I->getOperand(1).getCImm()->getZExtValue());434 }435 436 // ICMP_NE437 {438 auto I = CSEB.buildICmp(CmpInst::Predicate::ICMP_NE, s1, One, Two);439 EXPECT_TRUE(I->getOpcode() == TargetOpcode::G_CONSTANT);440 EXPECT_TRUE(I->getOperand(1).getCImm()->getZExtValue());441 }442 443 // ICMP_UGT444 {445 auto I = CSEB.buildICmp(CmpInst::Predicate::ICMP_UGT, s1, Two, One);446 EXPECT_TRUE(I->getOpcode() == TargetOpcode::G_CONSTANT);447 EXPECT_TRUE(I->getOperand(1).getCImm()->getZExtValue());448 }449 450 // ICMP_UGE451 {452 auto I = CSEB.buildICmp(CmpInst::Predicate::ICMP_UGE, s1, One, One);453 EXPECT_TRUE(I->getOpcode() == TargetOpcode::G_CONSTANT);454 EXPECT_TRUE(I->getOperand(1).getCImm()->getZExtValue());455 }456 457 // ICMP_ULT458 {459 auto I = CSEB.buildICmp(CmpInst::Predicate::ICMP_ULT, s1, One, Two);460 EXPECT_TRUE(I->getOpcode() == TargetOpcode::G_CONSTANT);461 EXPECT_TRUE(I->getOperand(1).getCImm()->getZExtValue());462 }463 464 // ICMP_ULE465 {466 auto I = CSEB.buildICmp(CmpInst::Predicate::ICMP_ULE, s1, Two, Two);467 EXPECT_TRUE(I->getOpcode() == TargetOpcode::G_CONSTANT);468 EXPECT_TRUE(I->getOperand(1).getCImm()->getZExtValue());469 }470 471 // ICMP_SGT472 {473 auto I =474 CSEB.buildICmp(CmpInst::Predicate::ICMP_SGT, s1, MinusOne, MinusTwo);475 EXPECT_TRUE(I->getOpcode() == TargetOpcode::G_CONSTANT);476 EXPECT_TRUE(I->getOperand(1).getCImm()->getZExtValue());477 }478 479 // ICMP_SGE480 {481 auto I =482 CSEB.buildICmp(CmpInst::Predicate::ICMP_SGE, s1, MinusOne, MinusOne);483 EXPECT_TRUE(I->getOpcode() == TargetOpcode::G_CONSTANT);484 EXPECT_TRUE(I->getOperand(1).getCImm()->getZExtValue());485 }486 487 // ICMP_SLT488 {489 auto I =490 CSEB.buildICmp(CmpInst::Predicate::ICMP_SLT, s1, MinusTwo, MinusOne);491 EXPECT_TRUE(I->getOpcode() == TargetOpcode::G_CONSTANT);492 EXPECT_TRUE(I->getOperand(1).getCImm()->getZExtValue());493 }494 495 // ICMP_SLE496 {497 auto I =498 CSEB.buildICmp(CmpInst::Predicate::ICMP_SLE, s1, MinusTwo, MinusOne);499 EXPECT_TRUE(I->getOpcode() == TargetOpcode::G_CONSTANT);500 EXPECT_TRUE(I->getOperand(1).getCImm()->getZExtValue());501 }502 503 {504 auto I = CSEB.buildICmp(CmpInst::Predicate::ICMP_EQ, s32, One, One);505 EXPECT_TRUE(I->getOpcode() == TargetOpcode::G_CONSTANT);506 EXPECT_EQ(I->getOperand(1).getCImm()->getZExtValue(), 1U);507 }508 509 {510 auto I = CSEB.buildICmp(CmpInst::Predicate::ICMP_EQ, s32, One, Two);511 EXPECT_TRUE(I->getOpcode() == TargetOpcode::G_CONSTANT);512 EXPECT_EQ(I->getOperand(1).getCImm()->getZExtValue(), 0U);513 }514 515 LLT VecTy = LLT::fixed_vector(2, s32);516 LLT DstTy = LLT::fixed_vector(2, s1);517 auto Three = CSEB.buildConstant(s32, 3);518 auto MinusThree = CSEB.buildConstant(s32, -3);519 auto OneOne = CSEB.buildBuildVector(VecTy, {One.getReg(0), One.getReg(0)});520 auto OneTwo = CSEB.buildBuildVector(VecTy, {One.getReg(0), Two.getReg(0)});521 auto TwoThree =522 CSEB.buildBuildVector(VecTy, {Two.getReg(0), Three.getReg(0)});523 auto OneThree =524 CSEB.buildBuildVector(VecTy, {One.getReg(0), Three.getReg(0)});525 auto MinusOneOne =526 CSEB.buildBuildVector(VecTy, {MinusOne.getReg(0), MinusOne.getReg(0)});527 auto MinusOneTwo =528 CSEB.buildBuildVector(VecTy, {MinusOne.getReg(0), MinusTwo.getReg(0)});529 auto MinusTwoThree =530 CSEB.buildBuildVector(VecTy, {MinusTwo.getReg(0), MinusThree.getReg(0)});531 532 // ICMP_EQ533 CSEB.buildICmp(CmpInst::Predicate::ICMP_EQ, DstTy, OneOne, OneOne);534 535 // ICMP_NE536 CSEB.buildICmp(CmpInst::Predicate::ICMP_NE, DstTy, OneOne, OneTwo);537 538 // ICMP_UGT539 CSEB.buildICmp(CmpInst::Predicate::ICMP_UGT, DstTy, TwoThree, OneTwo);540 541 // ICMP_UGE542 CSEB.buildICmp(CmpInst::Predicate::ICMP_UGE, DstTy, OneTwo, OneOne);543 544 // ICMP_ULT545 CSEB.buildICmp(CmpInst::Predicate::ICMP_ULT, DstTy, OneOne, OneTwo);546 547 // ICMP_ULE548 CSEB.buildICmp(CmpInst::Predicate::ICMP_ULE, DstTy, OneTwo, OneOne);549 550 // ICMP_SGT551 CSEB.buildICmp(CmpInst::Predicate::ICMP_SGT, DstTy, MinusOneTwo,552 MinusTwoThree);553 554 // ICMP_SGE555 CSEB.buildICmp(CmpInst::Predicate::ICMP_SGE, DstTy, MinusOneTwo, MinusOneOne);556 557 // ICMP_SLT558 CSEB.buildICmp(CmpInst::Predicate::ICMP_SLT, DstTy, MinusTwoThree,559 MinusOneTwo);560 561 // ICMP_SLE562 CSEB.buildICmp(CmpInst::Predicate::ICMP_SLE, DstTy, MinusOneTwo, MinusOneOne);563 564 {565 auto I =566 CSEB.buildICmp(CmpInst::Predicate::ICMP_EQ, VecTy, OneOne, TwoThree);567 EXPECT_TRUE(I->getOpcode() == TargetOpcode::G_BUILD_VECTOR);568 const APInt HiCst = *getIConstantVRegVal(I->getOperand(1).getReg(), *MRI);569 const APInt LoCst = *getIConstantVRegVal(I->getOperand(2).getReg(), *MRI);570 EXPECT_EQ(HiCst.getSExtValue(), 0);571 EXPECT_EQ(LoCst.getSExtValue(), 0);572 }573 574 {575 auto I =576 CSEB.buildICmp(CmpInst::Predicate::ICMP_EQ, VecTy, OneThree, TwoThree);577 EXPECT_TRUE(I->getOpcode() == TargetOpcode::G_BUILD_VECTOR);578 const APInt HiCst = *getIConstantVRegVal(I->getOperand(1).getReg(), *MRI);579 const APInt LoCst = *getIConstantVRegVal(I->getOperand(2).getReg(), *MRI);580 EXPECT_EQ(HiCst.getSExtValue(), 0);581 EXPECT_EQ(LoCst.getSExtValue(), -1);582 }583 584 {585 auto I =586 CSEB.buildICmp(CmpInst::Predicate::ICMP_EQ, VecTy, TwoThree, TwoThree);587 EXPECT_TRUE(I->getOpcode() == TargetOpcode::G_BUILD_VECTOR);588 const APInt HiCst = *getIConstantVRegVal(I->getOperand(1).getReg(), *MRI);589 const APInt LoCst = *getIConstantVRegVal(I->getOperand(2).getReg(), *MRI);590 EXPECT_EQ(HiCst.getSExtValue(), -1);591 EXPECT_EQ(LoCst.getSExtValue(), -1);592 }593 594 auto CheckStr = R"(595 ; CHECK: [[One:%[0-9]+]]:_(s32) = G_CONSTANT i32 1596 ; CHECK: [[Two:%[0-9]+]]:_(s32) = G_CONSTANT i32 2597 ; CHECK: [[MinusOne:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1598 ; CHECK: [[MinusTwo:%[0-9]+]]:_(s32) = G_CONSTANT i32 -2599 ; CHECK: [[True:%[0-9]+]]:_(s1) = G_CONSTANT i1 true600 ; CHECK: [[Three:%[0-9]+]]:_(s32) = G_CONSTANT i32 3601 ; CHECK: [[MinusThree:%[0-9]+]]:_(s32) = G_CONSTANT i32 -3602 ; CHECK: {{%[0-9]+}}:_(<2 x s32>) = G_BUILD_VECTOR [[One]]:_(s32), [[One]]:_(s32)603 ; CHECK: {{%[0-9]+}}:_(<2 x s32>) = G_BUILD_VECTOR [[One]]:_(s32), [[Two]]:_(s32)604 ; CHECK: {{%[0-9]+}}:_(<2 x s32>) = G_BUILD_VECTOR [[Two]]:_(s32), [[Three]]:_(s32)605 ; CHECK: {{%[0-9]+}}:_(<2 x s32>) = G_BUILD_VECTOR [[One]]:_(s32), [[Three]]:_(s32)606 ; CHECK: {{%[0-9]+}}:_(<2 x s32>) = G_BUILD_VECTOR [[MinusOne]]:_(s32), [[MinusOne]]:_(s32)607 ; CHECK: {{%[0-9]+}}:_(<2 x s32>) = G_BUILD_VECTOR [[MinusOne]]:_(s32), [[MinusTwo]]:_(s32)608 ; CHECK: {{%[0-9]+}}:_(<2 x s32>) = G_BUILD_VECTOR [[MinusTwo]]:_(s32), [[MinusThree]]:_(s32)609 ; CHECK: {{%[0-9]+}}:_(<2 x s1>) = G_BUILD_VECTOR [[True]]:_(s1), [[True]]:_(s1)610 ; CHECK: [[False:%[0-9]+]]:_(s1) = G_CONSTANT i1 false611 ; CHECK: {{%[0-9]+}}:_(<2 x s1>) = G_BUILD_VECTOR [[False]]:_(s1), [[True]]:_(s1)612 ; CHECK: {{%[0-9]+}}:_(<2 x s1>) = G_BUILD_VECTOR [[True]]:_(s1), [[True]]:_(s1)613 ; CHECK: {{%[0-9]+}}:_(<2 x s1>) = G_BUILD_VECTOR [[True]]:_(s1), [[True]]:_(s1)614 ; CHECK: {{%[0-9]+}}:_(<2 x s1>) = G_BUILD_VECTOR [[False]]:_(s1), [[True]]:_(s1)615 ; CHECK: {{%[0-9]+}}:_(<2 x s1>) = G_BUILD_VECTOR [[True]]:_(s1), [[False]]:_(s1)616 ; CHECK: {{%[0-9]+}}:_(<2 x s1>) = G_BUILD_VECTOR [[True]]:_(s1), [[True]]:_(s1)617 ; CHECK: {{%[0-9]+}}:_(<2 x s1>) = G_BUILD_VECTOR [[True]]:_(s1), [[False]]:_(s1)618 ; CHECK: {{%[0-9]+}}:_(<2 x s1>) = G_BUILD_VECTOR [[True]]:_(s1), [[True]]:_(s1)619 ; CHECK: {{%[0-9]+}}:_(<2 x s1>) = G_BUILD_VECTOR [[True]]:_(s1), [[True]]:_(s1)620 )";621 622 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;623}624 625} // namespace626