brintos

brintos / llvm-project-archived public Read only

0
0
Text · 23.2 KiB · e19e655 Raw
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