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
) {
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
});
25 CSEInfo
.setCSEConfig(make_unique
<CSEConfigFull
>());
27 B
.setCSEInfo(&CSEInfo
);
28 CSEMIRBuilder
CSEB(B
.getState());
30 CSEB
.setInsertPt(*EntryMBB
, EntryMBB
->begin());
31 unsigned AddReg
= MRI
->createGenericVirtualRegister(s16
);
33 CSEB
.buildInstr(TargetOpcode::G_ADD
, {AddReg
}, {MIBInput
, MIBInput
});
34 EXPECT_EQ(MIBAddCopy
->getOpcode(), TargetOpcode::COPY
);
36 CSEB
.buildInstr(TargetOpcode::G_ADD
, {s16
}, {MIBInput
, MIBInput
});
37 EXPECT_TRUE(&*MIBAdd
== &*MIBAdd2
);
39 CSEB
.buildInstr(TargetOpcode::G_ADD
, {s16
}, {MIBInput
, MIBInput
});
40 EXPECT_TRUE(&*MIBAdd
== &*MIBAdd4
);
42 CSEB
.buildInstr(TargetOpcode::G_ADD
, {s16
}, {MIBInput
, MIBInput1
});
43 EXPECT_TRUE(&*MIBAdd
!= &*MIBAdd5
);
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
);
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
);
59 // Make sure buildConstant with a vector type doesn't crash, and the elements
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()));
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()));
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
);
77 TEST_F(GISelMITest
, TestCSEConstantConfig
) {
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);
87 CSEInfo
.setCSEConfig(make_unique
<CSEConfigConstantOnly
>());
89 B
.setCSEInfo(&CSEInfo
);
90 CSEMIRBuilder
CSEB(B
.getState());
91 CSEB
.setInsertPt(*EntryMBB
, EntryMBB
->begin());
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
);