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