xref: /llvm-project/llvm/unittests/CodeGen/GlobalISel/CSETest.cpp (revision 2946cd701067404b99c39fb29dc9c74bd7193eb3)
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<CSEConfig>());
25   CSEInfo.analyze(*MF);
26   B.setCSEInfo(&CSEInfo);
27   CSEMIRBuilder CSEB(B.getState());
28   CSEB.setInsertPt(*EntryMBB, EntryMBB->begin());
29   unsigned AddReg = MRI->createGenericVirtualRegister(s16);
30   auto MIBAddCopy =
31       CSEB.buildInstr(TargetOpcode::G_ADD, {AddReg}, {MIBInput, MIBInput});
32   ASSERT_EQ(MIBAddCopy->getOpcode(), TargetOpcode::COPY);
33   auto MIBAdd2 =
34       CSEB.buildInstr(TargetOpcode::G_ADD, {s16}, {MIBInput, MIBInput});
35   ASSERT_TRUE(&*MIBAdd == &*MIBAdd2);
36   auto MIBAdd4 =
37       CSEB.buildInstr(TargetOpcode::G_ADD, {s16}, {MIBInput, MIBInput});
38   ASSERT_TRUE(&*MIBAdd == &*MIBAdd4);
39   auto MIBAdd5 =
40       CSEB.buildInstr(TargetOpcode::G_ADD, {s16}, {MIBInput, MIBInput1});
41   ASSERT_TRUE(&*MIBAdd != &*MIBAdd5);
42 
43   // Try building G_CONSTANTS.
44   auto MIBCst = CSEB.buildConstant(s32, 0);
45   auto MIBCst1 = CSEB.buildConstant(s32, 0);
46   ASSERT_TRUE(&*MIBCst == &*MIBCst1);
47   // Try the CFing of BinaryOps.
48   auto MIBCF1 = CSEB.buildInstr(TargetOpcode::G_ADD, {s32}, {MIBCst, MIBCst});
49   ASSERT_TRUE(&*MIBCF1 == &*MIBCst);
50 
51   // Try out building FCONSTANTs.
52   auto MIBFP0 = CSEB.buildFConstant(s32, 1.0);
53   auto MIBFP0_1 = CSEB.buildFConstant(s32, 1.0);
54   ASSERT_TRUE(&*MIBFP0 == &*MIBFP0_1);
55   CSEInfo.print();
56 
57   // Check G_UNMERGE_VALUES
58   auto MIBUnmerge = CSEB.buildUnmerge({s32, s32}, Copies[0]);
59   auto MIBUnmerge2 = CSEB.buildUnmerge({s32, s32}, Copies[0]);
60   ASSERT_TRUE(&*MIBUnmerge == &*MIBUnmerge2);
61 }
62 
63 TEST_F(GISelMITest, TestCSEConstantConfig) {
64   if (!TM)
65     return;
66 
67   LLT s16{LLT::scalar(16)};
68   auto MIBInput = B.buildInstr(TargetOpcode::G_TRUNC, {s16}, {Copies[0]});
69   auto MIBAdd = B.buildInstr(TargetOpcode::G_ADD, {s16}, {MIBInput, MIBInput});
70   auto MIBZero = B.buildConstant(s16, 0);
71   GISelCSEInfo CSEInfo;
72   CSEInfo.setCSEConfig(make_unique<CSEConfigConstantOnly>());
73   CSEInfo.analyze(*MF);
74   B.setCSEInfo(&CSEInfo);
75   CSEMIRBuilder CSEB(B.getState());
76   CSEB.setInsertPt(*EntryMBB, EntryMBB->begin());
77   auto MIBAdd1 =
78       CSEB.buildInstr(TargetOpcode::G_ADD, {s16}, {MIBInput, MIBInput});
79   // We should CSE constants only. Adds should not be CSEd.
80   ASSERT_TRUE(MIBAdd1->getOpcode() != TargetOpcode::COPY);
81   ASSERT_TRUE(&*MIBAdd1 != &*MIBAdd);
82   // We should CSE constant.
83   auto MIBZeroTmp = CSEB.buildConstant(s16, 0);
84   ASSERT_TRUE(&*MIBZero == &*MIBZeroTmp);
85 }
86 } // namespace
87