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/CSEMIRBuilder.h" 11 12 namespace { 13 14 TEST_F(GISelMITest, TestCSE) { 15 setUp(); 16 if (!TM) 17 return; 18 19 LLT s16{LLT::scalar(16)}; 20 LLT s32{LLT::scalar(32)}; 21 auto MIBInput = B.buildInstr(TargetOpcode::G_TRUNC, {s16}, {Copies[0]}); 22 auto MIBInput1 = B.buildInstr(TargetOpcode::G_TRUNC, {s16}, {Copies[1]}); 23 auto MIBAdd = B.buildInstr(TargetOpcode::G_ADD, {s16}, {MIBInput, MIBInput}); 24 GISelCSEInfo CSEInfo; 25 CSEInfo.setCSEConfig(std::make_unique<CSEConfigFull>()); 26 CSEInfo.analyze(*MF); 27 B.setCSEInfo(&CSEInfo); 28 CSEMIRBuilder CSEB(B.getState()); 29 30 CSEB.setInsertPt(*EntryMBB, EntryMBB->begin()); 31 unsigned AddReg = MRI->createGenericVirtualRegister(s16); 32 auto MIBAddCopy = 33 CSEB.buildInstr(TargetOpcode::G_ADD, {AddReg}, {MIBInput, MIBInput}); 34 EXPECT_EQ(MIBAddCopy->getOpcode(), TargetOpcode::COPY); 35 auto MIBAdd2 = 36 CSEB.buildInstr(TargetOpcode::G_ADD, {s16}, {MIBInput, MIBInput}); 37 EXPECT_TRUE(&*MIBAdd == &*MIBAdd2); 38 auto MIBAdd4 = 39 CSEB.buildInstr(TargetOpcode::G_ADD, {s16}, {MIBInput, MIBInput}); 40 EXPECT_TRUE(&*MIBAdd == &*MIBAdd4); 41 auto MIBAdd5 = 42 CSEB.buildInstr(TargetOpcode::G_ADD, {s16}, {MIBInput, MIBInput1}); 43 EXPECT_TRUE(&*MIBAdd != &*MIBAdd5); 44 45 // Try building G_CONSTANTS. 46 auto MIBCst = CSEB.buildConstant(s32, 0); 47 auto MIBCst1 = CSEB.buildConstant(s32, 0); 48 EXPECT_TRUE(&*MIBCst == &*MIBCst1); 49 // Try the CFing of BinaryOps. 50 auto MIBCF1 = CSEB.buildInstr(TargetOpcode::G_ADD, {s32}, {MIBCst, MIBCst}); 51 EXPECT_TRUE(&*MIBCF1 == &*MIBCst); 52 53 // Try out building FCONSTANTs. 54 auto MIBFP0 = CSEB.buildFConstant(s32, 1.0); 55 auto MIBFP0_1 = CSEB.buildFConstant(s32, 1.0); 56 EXPECT_TRUE(&*MIBFP0 == &*MIBFP0_1); 57 CSEInfo.print(); 58 59 // Make sure buildConstant with a vector type doesn't crash, and the elements 60 // CSE. 61 auto Splat0 = CSEB.buildConstant(LLT::vector(2, s32), 0); 62 EXPECT_EQ(TargetOpcode::G_BUILD_VECTOR, Splat0->getOpcode()); 63 EXPECT_EQ(Splat0.getReg(1), Splat0.getReg(2)); 64 EXPECT_EQ(&*MIBCst, MRI->getVRegDef(Splat0.getReg(1))); 65 66 auto FSplat = CSEB.buildFConstant(LLT::vector(2, s32), 1.0); 67 EXPECT_EQ(TargetOpcode::G_BUILD_VECTOR, FSplat->getOpcode()); 68 EXPECT_EQ(FSplat.getReg(1), FSplat.getReg(2)); 69 EXPECT_EQ(&*MIBFP0, MRI->getVRegDef(FSplat.getReg(1))); 70 71 // Check G_UNMERGE_VALUES 72 auto MIBUnmerge = CSEB.buildUnmerge({s32, s32}, Copies[0]); 73 auto MIBUnmerge2 = CSEB.buildUnmerge({s32, s32}, Copies[0]); 74 EXPECT_TRUE(&*MIBUnmerge == &*MIBUnmerge2); 75 76 // Check G_IMPLICIT_DEF 77 auto Undef0 = CSEB.buildUndef(s32); 78 auto Undef1 = CSEB.buildUndef(s32); 79 EXPECT_EQ(&*Undef0, &*Undef1); 80 } 81 82 TEST_F(GISelMITest, TestCSEConstantConfig) { 83 setUp(); 84 if (!TM) 85 return; 86 87 LLT s16{LLT::scalar(16)}; 88 auto MIBInput = B.buildInstr(TargetOpcode::G_TRUNC, {s16}, {Copies[0]}); 89 auto MIBAdd = B.buildInstr(TargetOpcode::G_ADD, {s16}, {MIBInput, MIBInput}); 90 auto MIBZero = B.buildConstant(s16, 0); 91 GISelCSEInfo CSEInfo; 92 CSEInfo.setCSEConfig(std::make_unique<CSEConfigConstantOnly>()); 93 CSEInfo.analyze(*MF); 94 B.setCSEInfo(&CSEInfo); 95 CSEMIRBuilder CSEB(B.getState()); 96 CSEB.setInsertPt(*EntryMBB, EntryMBB->begin()); 97 auto MIBAdd1 = 98 CSEB.buildInstr(TargetOpcode::G_ADD, {s16}, {MIBInput, MIBInput}); 99 // We should CSE constants only. Adds should not be CSEd. 100 EXPECT_TRUE(MIBAdd1->getOpcode() != TargetOpcode::COPY); 101 EXPECT_TRUE(&*MIBAdd1 != &*MIBAdd); 102 // We should CSE constant. 103 auto MIBZeroTmp = CSEB.buildConstant(s16, 0); 104 EXPECT_TRUE(&*MIBZero == &*MIBZeroTmp); 105 106 // Check G_IMPLICIT_DEF 107 auto Undef0 = CSEB.buildUndef(s16); 108 auto Undef1 = CSEB.buildUndef(s16); 109 EXPECT_EQ(&*Undef0, &*Undef1); 110 } 111 } // namespace 112