1 //===- CSETest.cpp -----------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "GISelMITest.h"
10 #include "llvm/CodeGen/GlobalISel/CSEMIRBuilder.h"
14 TEST_F(GISelMITest
, TestCSE
) {
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
});
24 CSEInfo
.setCSEConfig(make_unique
<CSEConfigFull
>());
26 B
.setCSEInfo(&CSEInfo
);
27 CSEMIRBuilder
CSEB(B
.getState());
29 CSEB
.setInsertPt(*EntryMBB
, EntryMBB
->begin());
30 unsigned AddReg
= MRI
->createGenericVirtualRegister(s16
);
32 CSEB
.buildInstr(TargetOpcode::G_ADD
, {AddReg
}, {MIBInput
, MIBInput
});
33 EXPECT_EQ(MIBAddCopy
->getOpcode(), TargetOpcode::COPY
);
35 CSEB
.buildInstr(TargetOpcode::G_ADD
, {s16
}, {MIBInput
, MIBInput
});
36 EXPECT_TRUE(&*MIBAdd
== &*MIBAdd2
);
38 CSEB
.buildInstr(TargetOpcode::G_ADD
, {s16
}, {MIBInput
, MIBInput
});
39 EXPECT_TRUE(&*MIBAdd
== &*MIBAdd4
);
41 CSEB
.buildInstr(TargetOpcode::G_ADD
, {s16
}, {MIBInput
, MIBInput1
});
42 EXPECT_TRUE(&*MIBAdd
!= &*MIBAdd5
);
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
);
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
);
58 // Make sure buildConstant with a vector type doesn't crash, and the elements
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()));
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()));
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
);
76 TEST_F(GISelMITest
, TestCSEConstantConfig
) {
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);
85 CSEInfo
.setCSEConfig(make_unique
<CSEConfigConstantOnly
>());
87 B
.setCSEInfo(&CSEInfo
);
88 CSEMIRBuilder
CSEB(B
.getState());
89 CSEB
.setInsertPt(*EntryMBB
, EntryMBB
->begin());
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
);