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
TEST_F(GISelMITest,TestCSE)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->getOperand(1).getReg(), Splat0->getOperand(2).getReg());
64 EXPECT_EQ(&*MIBCst, MRI->getVRegDef(Splat0->getOperand(1).getReg()));
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->getOperand(1).getReg(), FSplat->getOperand(2).getReg());
69 EXPECT_EQ(&*MIBFP0, MRI->getVRegDef(FSplat->getOperand(1).getReg()));
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
TEST_F(GISelMITest,TestCSEConstantConfig)77 TEST_F(GISelMITest, TestCSEConstantConfig) {
78 setUp();
79 if (!TM)
80 return;
81
82 LLT s16{LLT::scalar(16)};
83 auto MIBInput = B.buildInstr(TargetOpcode::G_TRUNC, {s16}, {Copies[0]});
84 auto MIBAdd = B.buildInstr(TargetOpcode::G_ADD, {s16}, {MIBInput, MIBInput});
85 auto MIBZero = B.buildConstant(s16, 0);
86 GISelCSEInfo CSEInfo;
87 CSEInfo.setCSEConfig(std::make_unique<CSEConfigConstantOnly>());
88 CSEInfo.analyze(*MF);
89 B.setCSEInfo(&CSEInfo);
90 CSEMIRBuilder CSEB(B.getState());
91 CSEB.setInsertPt(*EntryMBB, EntryMBB->begin());
92 auto MIBAdd1 =
93 CSEB.buildInstr(TargetOpcode::G_ADD, {s16}, {MIBInput, MIBInput});
94 // We should CSE constants only. Adds should not be CSEd.
95 EXPECT_TRUE(MIBAdd1->getOpcode() != TargetOpcode::COPY);
96 EXPECT_TRUE(&*MIBAdd1 != &*MIBAdd);
97 // We should CSE constant.
98 auto MIBZeroTmp = CSEB.buildConstant(s16, 0);
99 EXPECT_TRUE(&*MIBZero == &*MIBZeroTmp);
100 }
101 } // namespace
102