xref: /llvm-project/llvm/unittests/CodeGen/GlobalISel/CSETest.cpp (revision c938436f7120872d2e2f72272b7adf2913d91783)
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/CSEInfo.h"
11 #include "llvm/CodeGen/GlobalISel/CSEMIRBuilder.h"
12 #include "gtest/gtest.h"
13 
14 namespace {
15 
16 TEST_F(AArch64GISelMITest, TestCSE) {
17   setUp();
18   if (!TM)
19     GTEST_SKIP();
20 
21   LLT s16{LLT::scalar(16)};
22   LLT s32{LLT::scalar(32)};
23   auto MIBInput = B.buildInstr(TargetOpcode::G_TRUNC, {s16}, {Copies[0]});
24   auto MIBInput1 = B.buildInstr(TargetOpcode::G_TRUNC, {s16}, {Copies[1]});
25   auto MIBAdd = B.buildInstr(TargetOpcode::G_ADD, {s16}, {MIBInput, MIBInput});
26   GISelCSEInfo CSEInfo;
27   CSEInfo.setCSEConfig(std::make_unique<CSEConfigFull>());
28   CSEInfo.analyze(*MF);
29   B.setCSEInfo(&CSEInfo);
30   CSEMIRBuilder CSEB(B.getState());
31 
32   CSEB.setInsertPt(B.getMBB(), B.getInsertPt());
33   Register AddReg = MRI->createGenericVirtualRegister(s16);
34   auto MIBAddCopy =
35       CSEB.buildInstr(TargetOpcode::G_ADD, {AddReg}, {MIBInput, MIBInput});
36   EXPECT_EQ(MIBAddCopy->getOpcode(), TargetOpcode::COPY);
37   auto MIBAdd2 =
38       CSEB.buildInstr(TargetOpcode::G_ADD, {s16}, {MIBInput, MIBInput});
39   EXPECT_TRUE(&*MIBAdd == &*MIBAdd2);
40   auto MIBAdd4 =
41       CSEB.buildInstr(TargetOpcode::G_ADD, {s16}, {MIBInput, MIBInput});
42   EXPECT_TRUE(&*MIBAdd == &*MIBAdd4);
43   auto MIBAdd5 =
44       CSEB.buildInstr(TargetOpcode::G_ADD, {s16}, {MIBInput, MIBInput1});
45   EXPECT_TRUE(&*MIBAdd != &*MIBAdd5);
46 
47   // Try building G_CONSTANTS.
48   auto MIBCst = CSEB.buildConstant(s32, 0);
49   auto MIBCst1 = CSEB.buildConstant(s32, 0);
50   EXPECT_TRUE(&*MIBCst == &*MIBCst1);
51   // Try the CFing of BinaryOps.
52   auto MIBCF1 = CSEB.buildInstr(TargetOpcode::G_ADD, {s32}, {MIBCst, MIBCst});
53   EXPECT_TRUE(&*MIBCF1 == &*MIBCst);
54 
55   // Try out building FCONSTANTs.
56   auto MIBFP0 = CSEB.buildFConstant(s32, 1.0);
57   auto MIBFP0_1 = CSEB.buildFConstant(s32, 1.0);
58   EXPECT_TRUE(&*MIBFP0 == &*MIBFP0_1);
59   CSEInfo.print();
60 
61   // Make sure buildConstant with a vector type doesn't crash, and the elements
62   // CSE.
63   auto Splat0 = CSEB.buildConstant(LLT::fixed_vector(2, s32), 0);
64   EXPECT_EQ(TargetOpcode::G_BUILD_VECTOR, Splat0->getOpcode());
65   EXPECT_EQ(Splat0.getReg(1), Splat0.getReg(2));
66   EXPECT_EQ(&*MIBCst, MRI->getVRegDef(Splat0.getReg(1)));
67 
68   auto FSplat = CSEB.buildFConstant(LLT::fixed_vector(2, s32), 1.0);
69   EXPECT_EQ(TargetOpcode::G_BUILD_VECTOR, FSplat->getOpcode());
70   EXPECT_EQ(FSplat.getReg(1), FSplat.getReg(2));
71   EXPECT_EQ(&*MIBFP0, MRI->getVRegDef(FSplat.getReg(1)));
72 
73   // Check G_UNMERGE_VALUES
74   auto MIBUnmerge = CSEB.buildUnmerge({s32, s32}, Copies[0]);
75   auto MIBUnmerge2 = CSEB.buildUnmerge({s32, s32}, Copies[0]);
76   EXPECT_TRUE(&*MIBUnmerge == &*MIBUnmerge2);
77 
78   // Check G_BUILD_VECTOR
79   Register Reg1 = MRI->createGenericVirtualRegister(s32);
80   Register Reg2 = MRI->createGenericVirtualRegister(s32);
81   auto BuildVec1 =
82       CSEB.buildBuildVector(LLT::fixed_vector(4, 32), {Reg1, Reg2, Reg1, Reg2});
83   auto BuildVec2 =
84       CSEB.buildBuildVector(LLT::fixed_vector(4, 32), {Reg1, Reg2, Reg1, Reg2});
85   EXPECT_EQ(TargetOpcode::G_BUILD_VECTOR, BuildVec1->getOpcode());
86   EXPECT_EQ(TargetOpcode::G_BUILD_VECTOR, BuildVec2->getOpcode());
87   EXPECT_TRUE(&*BuildVec1 == &*BuildVec2);
88 
89   // Check G_BUILD_VECTOR_TRUNC
90   auto BuildVecTrunc1 = CSEB.buildBuildVectorTrunc(LLT::fixed_vector(4, 16),
91                                                    {Reg1, Reg2, Reg1, Reg2});
92   auto BuildVecTrunc2 = CSEB.buildBuildVectorTrunc(LLT::fixed_vector(4, 16),
93                                                    {Reg1, Reg2, Reg1, Reg2});
94   EXPECT_EQ(TargetOpcode::G_BUILD_VECTOR_TRUNC, BuildVecTrunc1->getOpcode());
95   EXPECT_EQ(TargetOpcode::G_BUILD_VECTOR_TRUNC, BuildVecTrunc2->getOpcode());
96   EXPECT_TRUE(&*BuildVecTrunc1 == &*BuildVecTrunc2);
97 
98   // Check G_IMPLICIT_DEF
99   auto Undef0 = CSEB.buildUndef(s32);
100   auto Undef1 = CSEB.buildUndef(s32);
101   EXPECT_EQ(&*Undef0, &*Undef1);
102 
103   // If the observer is installed to the MF, CSE can also
104   // track new instructions built without the CSEBuilder and
105   // the newly built instructions are available for CSEing next
106   // time a build call is made through the CSEMIRBuilder.
107   // Additionally, the CSE implementation lazily hashes instructions
108   // (every build call) to give chance for the instruction to be fully
109   // built (say using .addUse().addDef().. so on).
110   GISelObserverWrapper WrapperObserver(&CSEInfo);
111   RAIIMFObsDelInstaller Installer(*MF, WrapperObserver);
112   MachineIRBuilder RegularBuilder(*MF);
113   RegularBuilder.setInsertPt(*EntryMBB, EntryMBB->begin());
114   auto NonCSEFMul = RegularBuilder.buildInstr(TargetOpcode::G_AND)
115                         .addDef(MRI->createGenericVirtualRegister(s32))
116                         .addUse(Copies[0])
117                         .addUse(Copies[1]);
118   auto CSEFMul =
119       CSEB.buildInstr(TargetOpcode::G_AND, {s32}, {Copies[0], Copies[1]});
120   EXPECT_EQ(&*CSEFMul, &*NonCSEFMul);
121 
122   auto ExtractMIB = CSEB.buildInstr(TargetOpcode::G_EXTRACT, {s16},
123                                     {Copies[0], static_cast<uint64_t>(0)});
124   auto ExtractMIB1 = CSEB.buildInstr(TargetOpcode::G_EXTRACT, {s16},
125                                      {Copies[0], static_cast<uint64_t>(0)});
126   auto ExtractMIB2 = CSEB.buildInstr(TargetOpcode::G_EXTRACT, {s16},
127                                      {Copies[0], static_cast<uint64_t>(1)});
128   EXPECT_EQ(&*ExtractMIB, &*ExtractMIB1);
129   EXPECT_NE(&*ExtractMIB, &*ExtractMIB2);
130 
131 
132   auto SextInRegMIB = CSEB.buildSExtInReg(s16, Copies[0], 0);
133   auto SextInRegMIB1 = CSEB.buildSExtInReg(s16, Copies[0], 0);
134   auto SextInRegMIB2 = CSEB.buildSExtInReg(s16, Copies[0], 1);
135   EXPECT_EQ(&*SextInRegMIB, &*SextInRegMIB1);
136   EXPECT_NE(&*SextInRegMIB, &*SextInRegMIB2);
137 }
138 
139 TEST_F(AArch64GISelMITest, TestCSEConstantConfig) {
140   setUp();
141   if (!TM)
142     GTEST_SKIP();
143 
144   LLT s16{LLT::scalar(16)};
145   auto MIBInput = B.buildInstr(TargetOpcode::G_TRUNC, {s16}, {Copies[0]});
146   auto MIBAdd = B.buildInstr(TargetOpcode::G_ADD, {s16}, {MIBInput, MIBInput});
147   auto MIBZero = B.buildConstant(s16, 0);
148   GISelCSEInfo CSEInfo;
149   CSEInfo.setCSEConfig(std::make_unique<CSEConfigConstantOnly>());
150   CSEInfo.analyze(*MF);
151   B.setCSEInfo(&CSEInfo);
152   CSEMIRBuilder CSEB(B.getState());
153   CSEB.setInsertPt(*EntryMBB, EntryMBB->begin());
154   auto MIBAdd1 =
155       CSEB.buildInstr(TargetOpcode::G_ADD, {s16}, {MIBInput, MIBInput});
156   // We should CSE constants only. Adds should not be CSEd.
157   EXPECT_TRUE(MIBAdd1->getOpcode() != TargetOpcode::COPY);
158   EXPECT_TRUE(&*MIBAdd1 != &*MIBAdd);
159   // We should CSE constant.
160   auto MIBZeroTmp = CSEB.buildConstant(s16, 0);
161   EXPECT_TRUE(&*MIBZero == &*MIBZeroTmp);
162 
163   // Check G_IMPLICIT_DEF
164   auto Undef0 = CSEB.buildUndef(s16);
165   auto Undef1 = CSEB.buildUndef(s16);
166   EXPECT_EQ(&*Undef0, &*Undef1);
167 }
168 
169 TEST_F(AArch64GISelMITest, TestCSEImmediateNextCSE) {
170   setUp();
171   if (!TM)
172     GTEST_SKIP();
173 
174   LLT s32{LLT::scalar(32)};
175   // We want to check that when the CSE hit is on the next instruction, i.e. at
176   // the current insert pt, that the insertion point is moved ahead of the
177   // instruction.
178 
179   GISelCSEInfo CSEInfo;
180   CSEInfo.setCSEConfig(std::make_unique<CSEConfigConstantOnly>());
181   CSEInfo.analyze(*MF);
182   B.setCSEInfo(&CSEInfo);
183   CSEMIRBuilder CSEB(B.getState());
184   CSEB.buildConstant(s32, 0);
185   auto MIBCst2 = CSEB.buildConstant(s32, 2);
186 
187   // Move the insert point before the second constant.
188   CSEB.setInsertPt(CSEB.getMBB(), --CSEB.getInsertPt());
189   auto MIBCst3 = CSEB.buildConstant(s32, 2);
190   EXPECT_TRUE(&*MIBCst2 == &*MIBCst3);
191   EXPECT_TRUE(CSEB.getInsertPt() == CSEB.getMBB().end());
192 }
193 
194 TEST_F(AArch64GISelMITest, TestConstantFoldCTL) {
195   setUp();
196   if (!TM)
197     GTEST_SKIP();
198 
199   LLT s32 = LLT::scalar(32);
200 
201   GISelCSEInfo CSEInfo;
202   CSEInfo.setCSEConfig(std::make_unique<CSEConfigConstantOnly>());
203   CSEInfo.analyze(*MF);
204   B.setCSEInfo(&CSEInfo);
205   CSEMIRBuilder CSEB(B.getState());
206   auto Cst8 = CSEB.buildConstant(s32, 8);
207   auto *CtlzDef = &*CSEB.buildCTLZ(s32, Cst8);
208   EXPECT_TRUE(CtlzDef->getOpcode() == TargetOpcode::G_CONSTANT);
209   EXPECT_TRUE(CtlzDef->getOperand(1).getCImm()->getZExtValue() == 28);
210 
211   // Test vector.
212   auto Cst16 = CSEB.buildConstant(s32, 16);
213   auto Cst32 = CSEB.buildConstant(s32, 32);
214   auto Cst64 = CSEB.buildConstant(s32, 64);
215   LLT VecTy = LLT::fixed_vector(4, s32);
216   auto BV = CSEB.buildBuildVector(VecTy, {Cst8.getReg(0), Cst16.getReg(0),
217                                           Cst32.getReg(0), Cst64.getReg(0)});
218   CSEB.buildCTLZ(VecTy, BV);
219 
220   auto CheckStr = R"(
221   ; CHECK: [[CST8:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
222   ; CHECK: [[CST28:%[0-9]+]]:_(s32) = G_CONSTANT i32 28
223   ; CHECK: [[CST16:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
224   ; CHECK: [[CST32:%[0-9]+]]:_(s32) = G_CONSTANT i32 32
225   ; CHECK: [[CST64:%[0-9]+]]:_(s32) = G_CONSTANT i32 64
226   ; CHECK: [[BV1:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[CST8]]:_(s32), [[CST16]]:_(s32), [[CST32]]:_(s32), [[CST64]]:_(s32)
227   ; CHECK: [[CST27:%[0-9]+]]:_(s32) = G_CONSTANT i32 27
228   ; CHECK: [[CST26:%[0-9]+]]:_(s32) = G_CONSTANT i32 26
229   ; CHECK: [[CST25:%[0-9]+]]:_(s32) = G_CONSTANT i32 25
230   ; CHECK: [[BV2:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[CST28]]:_(s32), [[CST27]]:_(s32), [[CST26]]:_(s32), [[CST25]]:_(s32)
231   )";
232 
233   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
234 }
235 
236 TEST_F(AArch64GISelMITest, TestConstantFoldCTT) {
237   setUp();
238   if (!TM)
239     GTEST_SKIP();
240 
241   LLT s32 = LLT::scalar(32);
242 
243   GISelCSEInfo CSEInfo;
244   CSEInfo.setCSEConfig(std::make_unique<CSEConfigConstantOnly>());
245   CSEInfo.analyze(*MF);
246   B.setCSEInfo(&CSEInfo);
247   CSEMIRBuilder CSEB(B.getState());
248   auto Cst8 = CSEB.buildConstant(s32, 8);
249   auto *CttzDef = &*CSEB.buildCTTZ(s32, Cst8);
250   EXPECT_TRUE(CttzDef->getOpcode() == TargetOpcode::G_CONSTANT);
251   EXPECT_TRUE(CttzDef->getOperand(1).getCImm()->getZExtValue() == 3);
252 
253   // Test vector.
254   auto Cst16 = CSEB.buildConstant(s32, 16);
255   auto Cst32 = CSEB.buildConstant(s32, 32);
256   auto Cst64 = CSEB.buildConstant(s32, 64);
257   LLT VecTy = LLT::fixed_vector(4, s32);
258   auto BV = CSEB.buildBuildVector(VecTy, {Cst8.getReg(0), Cst16.getReg(0),
259                                           Cst32.getReg(0), Cst64.getReg(0)});
260   CSEB.buildCTTZ(VecTy, BV);
261 
262   auto CheckStr = R"(
263   ; CHECK: [[CST8:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
264   ; CHECK: [[CST3:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
265   ; CHECK: [[CST16:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
266   ; CHECK: [[CST32:%[0-9]+]]:_(s32) = G_CONSTANT i32 32
267   ; CHECK: [[CST64:%[0-9]+]]:_(s32) = G_CONSTANT i32 64
268   ; CHECK: [[BV1:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[CST8]]:_(s32), [[CST16]]:_(s32), [[CST32]]:_(s32), [[CST64]]:_(s32)
269   ; CHECK: [[CST27:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
270   ; CHECK: [[CST26:%[0-9]+]]:_(s32) = G_CONSTANT i32 5
271   ; CHECK: [[CST25:%[0-9]+]]:_(s32) = G_CONSTANT i32 6
272   ; CHECK: [[BV2:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[CST3]]:_(s32), [[CST27]]:_(s32), [[CST26]]:_(s32), [[CST25]]:_(s32)
273   )";
274 
275   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
276 }
277 
278 TEST_F(AArch64GISelMITest, TestConstantFoldICMP) {
279   setUp();
280   if (!TM)
281     GTEST_SKIP();
282 
283   LLT s32 = LLT::scalar(32);
284   LLT s1 = LLT::scalar(1);
285 
286   GISelCSEInfo CSEInfo;
287   CSEInfo.setCSEConfig(std::make_unique<CSEConfigConstantOnly>());
288   CSEInfo.analyze(*MF);
289   B.setCSEInfo(&CSEInfo);
290   CSEMIRBuilder CSEB(B.getState());
291 
292   auto One = CSEB.buildConstant(s32, 1);
293   auto Two = CSEB.buildConstant(s32, 2);
294   auto MinusOne = CSEB.buildConstant(s32, -1);
295   auto MinusTwo = CSEB.buildConstant(s32, -2);
296 
297   // ICMP_EQ
298   {
299     auto I = CSEB.buildICmp(CmpInst::Predicate::ICMP_EQ, s1, One, One);
300     EXPECT_TRUE(I->getOpcode() == TargetOpcode::G_CONSTANT);
301     EXPECT_TRUE(I->getOperand(1).getCImm()->getZExtValue());
302   }
303 
304   // ICMP_NE
305   {
306     auto I = CSEB.buildICmp(CmpInst::Predicate::ICMP_NE, s1, One, Two);
307     EXPECT_TRUE(I->getOpcode() == TargetOpcode::G_CONSTANT);
308     EXPECT_TRUE(I->getOperand(1).getCImm()->getZExtValue());
309   }
310 
311   // ICMP_UGT
312   {
313     auto I = CSEB.buildICmp(CmpInst::Predicate::ICMP_UGT, s1, Two, One);
314     EXPECT_TRUE(I->getOpcode() == TargetOpcode::G_CONSTANT);
315     EXPECT_TRUE(I->getOperand(1).getCImm()->getZExtValue());
316   }
317 
318   // ICMP_UGE
319   {
320     auto I = CSEB.buildICmp(CmpInst::Predicate::ICMP_UGE, s1, One, One);
321     EXPECT_TRUE(I->getOpcode() == TargetOpcode::G_CONSTANT);
322     EXPECT_TRUE(I->getOperand(1).getCImm()->getZExtValue());
323   }
324 
325   // ICMP_ULT
326   {
327     auto I = CSEB.buildICmp(CmpInst::Predicate::ICMP_ULT, s1, One, Two);
328     EXPECT_TRUE(I->getOpcode() == TargetOpcode::G_CONSTANT);
329     EXPECT_TRUE(I->getOperand(1).getCImm()->getZExtValue());
330   }
331 
332   // ICMP_ULE
333   {
334     auto I = CSEB.buildICmp(CmpInst::Predicate::ICMP_ULE, s1, Two, Two);
335     EXPECT_TRUE(I->getOpcode() == TargetOpcode::G_CONSTANT);
336     EXPECT_TRUE(I->getOperand(1).getCImm()->getZExtValue());
337   }
338 
339   // ICMP_SGT
340   {
341     auto I =
342         CSEB.buildICmp(CmpInst::Predicate::ICMP_SGT, s1, MinusOne, MinusTwo);
343     EXPECT_TRUE(I->getOpcode() == TargetOpcode::G_CONSTANT);
344     EXPECT_TRUE(I->getOperand(1).getCImm()->getZExtValue());
345   }
346 
347   // ICMP_SGE
348   {
349     auto I =
350         CSEB.buildICmp(CmpInst::Predicate::ICMP_SGE, s1, MinusOne, MinusOne);
351     EXPECT_TRUE(I->getOpcode() == TargetOpcode::G_CONSTANT);
352     EXPECT_TRUE(I->getOperand(1).getCImm()->getZExtValue());
353   }
354 
355   // ICMP_SLT
356   {
357     auto I =
358         CSEB.buildICmp(CmpInst::Predicate::ICMP_SLT, s1, MinusTwo, MinusOne);
359     EXPECT_TRUE(I->getOpcode() == TargetOpcode::G_CONSTANT);
360     EXPECT_TRUE(I->getOperand(1).getCImm()->getZExtValue());
361   }
362 
363   // ICMP_SLE
364   {
365     auto I =
366         CSEB.buildICmp(CmpInst::Predicate::ICMP_SLE, s1, MinusTwo, MinusOne);
367     EXPECT_TRUE(I->getOpcode() == TargetOpcode::G_CONSTANT);
368     EXPECT_TRUE(I->getOperand(1).getCImm()->getZExtValue());
369   }
370 
371   LLT VecTy = LLT::fixed_vector(2, s32);
372   LLT DstTy = LLT::fixed_vector(2, s1);
373   auto Three = CSEB.buildConstant(s32, 3);
374   auto MinusThree = CSEB.buildConstant(s32, -3);
375   auto OneOne = CSEB.buildBuildVector(VecTy, {One.getReg(0), One.getReg(0)});
376   auto OneTwo = CSEB.buildBuildVector(VecTy, {One.getReg(0), Two.getReg(0)});
377   auto TwoThree =
378       CSEB.buildBuildVector(VecTy, {Two.getReg(0), Three.getReg(0)});
379   auto MinusOneOne =
380       CSEB.buildBuildVector(VecTy, {MinusOne.getReg(0), MinusOne.getReg(0)});
381   auto MinusOneTwo =
382       CSEB.buildBuildVector(VecTy, {MinusOne.getReg(0), MinusTwo.getReg(0)});
383   auto MinusTwoThree =
384       CSEB.buildBuildVector(VecTy, {MinusTwo.getReg(0), MinusThree.getReg(0)});
385 
386   // ICMP_EQ
387   CSEB.buildICmp(CmpInst::Predicate::ICMP_EQ, DstTy, OneOne, OneOne);
388 
389   // ICMP_NE
390   CSEB.buildICmp(CmpInst::Predicate::ICMP_NE, DstTy, OneOne, OneTwo);
391 
392   // ICMP_UGT
393   CSEB.buildICmp(CmpInst::Predicate::ICMP_UGT, DstTy, TwoThree, OneTwo);
394 
395   // ICMP_UGE
396   CSEB.buildICmp(CmpInst::Predicate::ICMP_UGE, DstTy, OneTwo, OneOne);
397 
398   // ICMP_ULT
399   CSEB.buildICmp(CmpInst::Predicate::ICMP_ULT, DstTy, OneOne, OneTwo);
400 
401   // ICMP_ULE
402   CSEB.buildICmp(CmpInst::Predicate::ICMP_ULE, DstTy, OneTwo, OneOne);
403 
404   // ICMP_SGT
405   CSEB.buildICmp(CmpInst::Predicate::ICMP_SGT, DstTy, MinusOneTwo,
406                  MinusTwoThree);
407 
408   // ICMP_SGE
409   CSEB.buildICmp(CmpInst::Predicate::ICMP_SGE, DstTy, MinusOneTwo, MinusOneOne);
410 
411   // ICMP_SLT
412   CSEB.buildICmp(CmpInst::Predicate::ICMP_SLT, DstTy, MinusTwoThree,
413                  MinusOneTwo);
414 
415   // ICMP_SLE
416   CSEB.buildICmp(CmpInst::Predicate::ICMP_SLE, DstTy, MinusOneTwo, MinusOneOne);
417 
418   auto CheckStr = R"(
419   ; CHECK: [[One:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
420   ; CHECK: [[Two:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
421   ; CHECK: [[MinusOne:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
422   ; CHECK: [[MinusTwo:%[0-9]+]]:_(s32) = G_CONSTANT i32 -2
423   ; CHECK: [[True:%[0-9]+]]:_(s1) = G_CONSTANT i1 true
424   ; CHECK: [[Three:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
425   ; CHECK: [[MinusThree:%[0-9]+]]:_(s32) = G_CONSTANT i32 -3
426   ; CHECK: {{%[0-9]+}}:_(<2 x s32>) = G_BUILD_VECTOR [[One]]:_(s32), [[One]]:_(s32)
427   ; CHECK: {{%[0-9]+}}:_(<2 x s32>) = G_BUILD_VECTOR [[One]]:_(s32), [[Two]]:_(s32)
428   ; CHECK: {{%[0-9]+}}:_(<2 x s32>) = G_BUILD_VECTOR [[Two]]:_(s32), [[Three]]:_(s32)
429   ; CHECK: {{%[0-9]+}}:_(<2 x s32>) = G_BUILD_VECTOR [[MinusOne]]:_(s32), [[MinusOne]]:_(s32)
430   ; CHECK: {{%[0-9]+}}:_(<2 x s32>) = G_BUILD_VECTOR [[MinusOne]]:_(s32), [[MinusTwo]]:_(s32)
431   ; CHECK: {{%[0-9]+}}:_(<2 x s32>) = G_BUILD_VECTOR [[MinusTwo]]:_(s32), [[MinusThree]]:_(s32)
432   ; CHECK: {{%[0-9]+}}:_(<2 x s1>) = G_BUILD_VECTOR [[True]]:_(s1), [[True]]:_(s1)
433   ; CHECK: [[False:%[0-9]+]]:_(s1) = G_CONSTANT i1 false
434   ; CHECK: {{%[0-9]+}}:_(<2 x s1>) = G_BUILD_VECTOR [[False]]:_(s1), [[True]]:_(s1)
435   ; CHECK: {{%[0-9]+}}:_(<2 x s1>) = G_BUILD_VECTOR [[True]]:_(s1), [[True]]:_(s1)
436   ; CHECK: {{%[0-9]+}}:_(<2 x s1>) = G_BUILD_VECTOR [[True]]:_(s1), [[True]]:_(s1)
437   ; CHECK: {{%[0-9]+}}:_(<2 x s1>) = G_BUILD_VECTOR [[False]]:_(s1), [[True]]:_(s1)
438   ; CHECK: {{%[0-9]+}}:_(<2 x s1>) = G_BUILD_VECTOR [[True]]:_(s1), [[False]]:_(s1)
439   ; CHECK: {{%[0-9]+}}:_(<2 x s1>) = G_BUILD_VECTOR [[True]]:_(s1), [[True]]:_(s1)
440   ; CHECK: {{%[0-9]+}}:_(<2 x s1>) = G_BUILD_VECTOR [[True]]:_(s1), [[False]]:_(s1)
441   ; CHECK: {{%[0-9]+}}:_(<2 x s1>) = G_BUILD_VECTOR [[True]]:_(s1), [[True]]:_(s1)
442   ; CHECK: {{%[0-9]+}}:_(<2 x s1>) = G_BUILD_VECTOR [[True]]:_(s1), [[True]]:_(s1)
443   )";
444 
445   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
446 }
447 
448 } // namespace
449