xref: /llvm-project/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp (revision f75d4f329cc45542cac4eaa375bad84e0535f278)
1 //===- PatternMatchTest.cpp -----------------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "LegalizerHelperTest.h"
11 
12 namespace {
13 
14 class DummyGISelObserver : public GISelChangeObserver {
15 public:
16   void changedInstr(MachineInstr &MI) override {}
17   void createdInstr(MachineInstr &MI) override {}
18   void erasedInstr(MachineInstr &MI) override {}
19 };
20 
21 // Test CTTZ expansion when CTTZ_ZERO_UNDEF is legal or custom,
22 // in which case it becomes CTTZ_ZERO_UNDEF with select.
23 TEST_F(LegalizerHelperTest, LowerBitCountingCTTZ0) {
24   if (!TM)
25     return;
26 
27   // Declare your legalization info
28   DefineLegalizerInfo(
29       A, { getActionDefinitionsBuilder(G_CTTZ_ZERO_UNDEF).legalFor({s64}); });
30   // Build Instr
31   auto MIBCTTZ = B.buildInstr(TargetOpcode::G_CTTZ, LLT::scalar(64), Copies[0]);
32   AInfo Info(MF->getSubtarget());
33   DummyGISelObserver Observer;
34   LegalizerHelper Helper(*MF, Info, Observer);
35   // Perform Legalization
36   ASSERT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) ==
37               LegalizerHelper::LegalizeResult::Legalized);
38 
39   auto CheckStr = R"(
40   CHECK: [[CZU:%[0-9]+]]:_(s64) = G_CTTZ_ZERO_UNDEF %0
41   CHECK: [[ZERO:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
42   CHECK: [[SIXTY4:%[0-9]+]]:_(s64) = G_CONSTANT i64 64
43   CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), %0:_(s64), [[ZERO]]
44   CHECK: [[SEL:%[0-9]+]]:_(s64) = G_SELECT [[CMP]]:_(s1), [[SIXTY4]]:_, [[CZU]]
45   )";
46 
47   // Check
48   ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
49 }
50 
51 // CTTZ expansion in terms of CTLZ
52 TEST_F(LegalizerHelperTest, LowerBitCountingCTTZ1) {
53   if (!TM)
54     return;
55 
56   // Declare your legalization info
57   DefineLegalizerInfo(A,
58                       { getActionDefinitionsBuilder(G_CTLZ).legalFor({s64}); });
59   // Build Instr
60   auto MIBCTTZ = B.buildInstr(TargetOpcode::G_CTTZ, LLT::scalar(64), Copies[0]);
61   AInfo Info(MF->getSubtarget());
62   DummyGISelObserver Observer;
63   LegalizerHelper Helper(*MF, Info, Observer);
64   // Perform Legalization
65   ASSERT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) ==
66               LegalizerHelper::LegalizeResult::Legalized);
67 
68   auto CheckStr = R"(
69   CHECK: [[NEG1:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1
70   CHECK: [[NOT:%[0-9]+]]:_(s64) = G_XOR %0:_, [[NEG1]]
71   CHECK: [[SUB1:%[0-9]+]]:_(s64) = G_ADD %0:_, [[NEG1]]
72   CHECK: [[AND1:%[0-9]+]]:_(s64) = G_AND [[NOT]]:_, [[SUB1]]:_
73   CHECK: [[CST64:%[0-9]+]]:_(s64) = G_CONSTANT i64 64
74   CHECK: [[CTLZ:%[0-9]+]]:_(s64) = G_CTLZ [[AND1]]:_
75   CHECK: G_SUB [[CST64]]:_, [[CTLZ]]:_
76   )";
77 
78   // Check
79   ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
80 }
81 
82 // CTTZ expansion in terms of CTPOP
83 TEST_F(LegalizerHelperTest, LowerBitCountingCTTZ2) {
84   if (!TM)
85     return;
86 
87   // Declare your legalization info
88   DefineLegalizerInfo(
89       A, { getActionDefinitionsBuilder(G_CTPOP).legalFor({s64}); });
90   // Build
91   auto MIBCTTZ = B.buildInstr(TargetOpcode::G_CTTZ, LLT::scalar(64), Copies[0]);
92   AInfo Info(MF->getSubtarget());
93   DummyGISelObserver Observer;
94   LegalizerHelper Helper(*MF, Info, Observer);
95   ASSERT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) ==
96               LegalizerHelper::LegalizeResult::Legalized);
97 
98   auto CheckStr = R"(
99   CHECK: [[NEG1:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1
100   CHECK: [[NOT:%[0-9]+]]:_(s64) = G_XOR %0:_, [[NEG1]]
101   CHECK: [[SUB1:%[0-9]+]]:_(s64) = G_ADD %0:_, [[NEG1]]
102   CHECK: [[AND1:%[0-9]+]]:_(s64) = G_AND [[NOT]]:_, [[SUB1]]:_
103   CHECK: [[POP:%[0-9]+]]:_(s64) = G_CTPOP [[AND1]]
104   )";
105 
106   // Check
107   ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
108 }
109 
110 // CTTZ_ZERO_UNDEF expansion in terms of CTTZ
111 TEST_F(LegalizerHelperTest, LowerBitCountingCTTZ3) {
112   if (!TM)
113     return;
114 
115   // Declare your legalization info
116   DefineLegalizerInfo(A,
117                       { getActionDefinitionsBuilder(G_CTTZ).legalFor({s64}); });
118   // Build
119   auto MIBCTTZ =
120       B.buildInstr(TargetOpcode::G_CTTZ_ZERO_UNDEF, LLT::scalar(64), Copies[0]);
121   AInfo Info(MF->getSubtarget());
122   DummyGISelObserver Observer;
123   LegalizerHelper Helper(*MF, Info, Observer);
124   ASSERT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) ==
125               LegalizerHelper::LegalizeResult::Legalized);
126 
127   auto CheckStr = R"(
128   CHECK: CTTZ
129   )";
130 
131   // Check
132   ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
133 }
134 
135 // CTLZ expansion in terms of CTLZ_ZERO_UNDEF
136 TEST_F(LegalizerHelperTest, LowerBitCountingCTLZ0) {
137   if (!TM)
138     return;
139 
140   // Declare your legalization info
141   DefineLegalizerInfo(
142       A, { getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF).legalFor({s64}); });
143   // Build
144   auto MIBCTLZ = B.buildInstr(TargetOpcode::G_CTLZ, LLT::scalar(64), Copies[0]);
145   AInfo Info(MF->getSubtarget());
146   DummyGISelObserver Observer;
147   LegalizerHelper Helper(*MF, Info, Observer);
148   ASSERT_TRUE(Helper.lower(*MIBCTLZ, 0, LLT::scalar(64)) ==
149               LegalizerHelper::LegalizeResult::Legalized);
150 
151   auto CheckStr = R"(
152   CHECK: [[CZU:%[0-9]+]]:_(s64) = G_CTLZ_ZERO_UNDEF %0
153   CHECK: [[ZERO:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
154   CHECK: [[SIXTY4:%[0-9]+]]:_(s64) = G_CONSTANT i64 64
155   CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), %0:_(s64), [[ZERO]]
156   CHECK: [[SEL:%[0-9]+]]:_(s64) = G_SELECT [[CMP]]:_(s1), [[SIXTY4]]:_, [[CZU]]
157   )";
158 
159   // Check
160   ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
161 }
162 
163 // CTLZ expansion in terms of CTLZ_ZERO_UNDEF if the latter is a libcall
164 TEST_F(LegalizerHelperTest, LowerBitCountingCTLZLibcall) {
165   if (!TM)
166     return;
167 
168   // Declare your legalization info
169   DefineLegalizerInfo(
170       A, { getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF).libcallFor({s64}); });
171   // Build
172   auto MIBCTLZ = B.buildInstr(TargetOpcode::G_CTLZ, LLT::scalar(64), Copies[0]);
173   AInfo Info(MF->getSubtarget());
174   DummyGISelObserver Observer;
175   LegalizerHelper Helper(*MF, Info, Observer);
176   ASSERT_TRUE(Helper.lower(*MIBCTLZ, 0, LLT::scalar(64)) ==
177               LegalizerHelper::LegalizeResult::Legalized);
178 
179   auto CheckStr = R"(
180   CHECK: [[CZU:%[0-9]+]]:_(s64) = G_CTLZ_ZERO_UNDEF %0
181   CHECK: [[ZERO:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
182   CHECK: [[THIRTY2:%[0-9]+]]:_(s64) = G_CONSTANT i64 64
183   CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), %0:_(s64), [[ZERO]]
184   CHECK: [[SEL:%[0-9]+]]:_(s64) = G_SELECT [[CMP]]:_(s1), [[THIRTY2]]:_, [[CZU]]
185   )";
186 
187   // Check
188   ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
189 }
190 
191 // CTLZ expansion
192 TEST_F(LegalizerHelperTest, LowerBitCountingCTLZ1) {
193   if (!TM)
194     return;
195 
196   // Declare your legalization info
197   DefineLegalizerInfo(A,
198                       { getActionDefinitionsBuilder(G_CTPOP).legalFor({s8}); });
199   // Build
200   // Trunc it to s8.
201   LLT s8{LLT::scalar(8)};
202   auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
203   auto MIBCTLZ = B.buildInstr(TargetOpcode::G_CTLZ, s8, MIBTrunc);
204   AInfo Info(MF->getSubtarget());
205   DummyGISelObserver Observer;
206   LegalizerHelper Helper(*MF, Info, Observer);
207   ASSERT_TRUE(Helper.lower(*MIBCTLZ, 0, s8) ==
208               LegalizerHelper::LegalizeResult::Legalized);
209 
210   auto CheckStr = R"(
211   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
212   CHECK: [[Cst1:%[0-9]+]]:_(s8) = G_CONSTANT i8 1
213   CHECK: [[Sh1:%[0-9]+]]:_(s8) = G_LSHR [[Trunc]]:_, [[Cst1]]:_
214   CHECK: [[Or1:%[0-9]+]]:_(s8) = G_OR [[Trunc]]:_, [[Sh1]]:_
215   CHECK: [[Cst2:%[0-9]+]]:_(s8) = G_CONSTANT i8 2
216   CHECK: [[Sh2:%[0-9]+]]:_(s8) = G_LSHR [[Or1]]:_, [[Cst2]]:_
217   CHECK: [[Or2:%[0-9]+]]:_(s8) = G_OR [[Or1]]:_, [[Sh2]]:_
218   CHECK: [[Cst4:%[0-9]+]]:_(s8) = G_CONSTANT i8 4
219   CHECK: [[Sh4:%[0-9]+]]:_(s8) = G_LSHR [[Or2]]:_, [[Cst4]]:_
220   CHECK: [[Or4:%[0-9]+]]:_(s8) = G_OR [[Or2]]:_, [[Sh4]]:_
221   CHECK: [[CTPOP:%[0-9]+]]:_(s8) = G_CTPOP [[Or4]]:_
222   CHECK: [[Len:%[0-9]+]]:_(s8) = G_CONSTANT i8 8
223   CHECK: [[Sub:%[0-9]+]]:_(s8) = G_SUB [[Len]]:_, [[CTPOP]]:_
224   )";
225 
226   // Check
227   ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
228 }
229 
230 // CTLZ widening.
231 TEST_F(LegalizerHelperTest, WidenBitCountingCTLZ) {
232   if (!TM)
233     return;
234 
235   // Declare your legalization info
236   DefineLegalizerInfo(A,
237                       { getActionDefinitionsBuilder(G_CTLZ).legalFor({s16}); });
238   // Build
239   // Trunc it to s8.
240   LLT s8{LLT::scalar(8)};
241   LLT s16{LLT::scalar(16)};
242   auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
243   auto MIBCTLZ = B.buildInstr(TargetOpcode::G_CTLZ, s8, MIBTrunc);
244   AInfo Info(MF->getSubtarget());
245   DummyGISelObserver Observer;
246   LegalizerHelper Helper(*MF, Info, Observer);
247   ASSERT_TRUE(Helper.widenScalar(*MIBCTLZ, 0, s16) ==
248               LegalizerHelper::LegalizeResult::Legalized);
249 
250   auto CheckStr = R"(
251   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
252   CHECK: [[Zext:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
253   CHECK: [[Ctlz:%[0-9]+]]:_(s16) = G_CTLZ [[Zext]]
254   CHECK: [[Cst8:%[0-9]+]]:_(s16) = G_CONSTANT i16 8
255   CHECK: [[Sub:%[0-9]+]]:_(s16) = G_SUB [[Ctlz]]:_, [[Cst8]]:_
256   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC [[Sub]]
257   )";
258 
259   // Check
260   ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
261 }
262 
263 // CTLZ_ZERO_UNDEF widening.
264 TEST_F(LegalizerHelperTest, WidenBitCountingCTLZZeroUndef) {
265   if (!TM)
266     return;
267 
268   // Declare your legalization info
269   DefineLegalizerInfo(
270       A, { getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF).legalFor({s16}); });
271   // Build
272   // Trunc it to s8.
273   LLT s8{LLT::scalar(8)};
274   LLT s16{LLT::scalar(16)};
275   auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
276   auto MIBCTLZ_ZU = B.buildInstr(TargetOpcode::G_CTLZ_ZERO_UNDEF, s8, MIBTrunc);
277   AInfo Info(MF->getSubtarget());
278   DummyGISelObserver Observer;
279   LegalizerHelper Helper(*MF, Info, Observer);
280   ASSERT_TRUE(Helper.widenScalar(*MIBCTLZ_ZU, 0, s16) ==
281               LegalizerHelper::LegalizeResult::Legalized);
282 
283   auto CheckStr = R"(
284   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
285   CHECK: [[Zext:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
286   CHECK: [[CtlzZu:%[0-9]+]]:_(s16) = G_CTLZ_ZERO_UNDEF [[Zext]]
287   CHECK: [[Cst8:%[0-9]+]]:_(s16) = G_CONSTANT i16 8
288   CHECK: [[Sub:%[0-9]+]]:_(s16) = G_SUB [[CtlzZu]]:_, [[Cst8]]:_
289   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC [[Sub]]
290   )";
291 
292   // Check
293   ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
294 }
295 
296 // CTPOP widening.
297 TEST_F(LegalizerHelperTest, WidenBitCountingCTPOP) {
298   if (!TM)
299     return;
300 
301   // Declare your legalization info
302   DefineLegalizerInfo(
303       A, { getActionDefinitionsBuilder(G_CTPOP).legalFor({s16}); });
304   // Build
305   // Trunc it to s8.
306   LLT s8{LLT::scalar(8)};
307   LLT s16{LLT::scalar(16)};
308   auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
309   auto MIBCTPOP = B.buildInstr(TargetOpcode::G_CTPOP, s8, MIBTrunc);
310   AInfo Info(MF->getSubtarget());
311   DummyGISelObserver Observer;
312   LegalizerHelper Helper(*MF, Info, Observer);
313   ASSERT_TRUE(Helper.widenScalar(*MIBCTPOP, 0, s16) ==
314               LegalizerHelper::LegalizeResult::Legalized);
315 
316   auto CheckStr = R"(
317   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
318   CHECK: [[Zext:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
319   CHECK: [[Ctpop:%[0-9]+]]:_(s16) = G_CTPOP [[Zext]]
320   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC [[Ctpop]]
321   )";
322 
323   // Check
324   ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
325 }
326 
327 // CTTZ_ZERO_UNDEF widening.
328 TEST_F(LegalizerHelperTest, WidenBitCountingCTTZ_ZERO_UNDEF) {
329   if (!TM)
330     return;
331 
332   // Declare your legalization info
333   DefineLegalizerInfo(
334       A, { getActionDefinitionsBuilder(G_CTTZ_ZERO_UNDEF).legalFor({s16}); });
335   // Build
336   // Trunc it to s8.
337   LLT s8{LLT::scalar(8)};
338   LLT s16{LLT::scalar(16)};
339   auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
340   auto MIBCTTZ_ZERO_UNDEF =
341       B.buildInstr(TargetOpcode::G_CTTZ_ZERO_UNDEF, s8, MIBTrunc);
342   AInfo Info(MF->getSubtarget());
343   DummyGISelObserver Observer;
344   LegalizerHelper Helper(*MF, Info, Observer);
345   ASSERT_TRUE(Helper.widenScalar(*MIBCTTZ_ZERO_UNDEF, 0, s16) ==
346               LegalizerHelper::LegalizeResult::Legalized);
347 
348   auto CheckStr = R"(
349   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
350   CHECK: [[Zext:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
351   CHECK: [[CttzZu:%[0-9]+]]:_(s16) = G_CTTZ_ZERO_UNDEF [[Zext]]
352   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC [[CttzZu]]
353   )";
354 
355   // Check
356   ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
357 }
358 
359 // CTTZ widening.
360 TEST_F(LegalizerHelperTest, WidenBitCountingCTTZ) {
361   if (!TM)
362     return;
363 
364   // Declare your legalization info
365   DefineLegalizerInfo(A,
366                       { getActionDefinitionsBuilder(G_CTTZ).legalFor({s16}); });
367   // Build
368   // Trunc it to s8.
369   LLT s8{LLT::scalar(8)};
370   LLT s16{LLT::scalar(16)};
371   auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
372   auto MIBCTTZ = B.buildInstr(TargetOpcode::G_CTTZ, s8, MIBTrunc);
373   AInfo Info(MF->getSubtarget());
374   DummyGISelObserver Observer;
375   LegalizerHelper Helper(*MF, Info, Observer);
376   ASSERT_TRUE(Helper.widenScalar(*MIBCTTZ, 0, s16) ==
377               LegalizerHelper::LegalizeResult::Legalized);
378 
379   auto CheckStr = R"(
380   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
381   CHECK: [[Zext:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
382   CHECK: [[Cst:%[0-9]+]]:_(s16) = G_CONSTANT i16 256
383   CHECK: [[Or:%[0-9]+]]:_(s16) = G_OR [[Zext]]:_, [[Cst]]
384   CHECK: [[Cttz:%[0-9]+]]:_(s16) = G_CTTZ [[Or]]
385   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC [[Cttz]]
386   )";
387 
388   // Check
389   ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
390 }
391 // UADDO widening.
392 TEST_F(LegalizerHelperTest, WidenUADDO) {
393   if (!TM)
394     return;
395 
396   // Declare your legalization info
397   DefineLegalizerInfo(A,
398                       { getActionDefinitionsBuilder(G_ADD).legalFor({s16}); });
399   // Build
400   // Trunc it to s8.
401   LLT s8{LLT::scalar(8)};
402   LLT s16{LLT::scalar(16)};
403   auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
404   unsigned CarryReg = MRI->createGenericVirtualRegister(LLT::scalar(1));
405   auto MIBUAddO = B.buildInstr(TargetOpcode::G_UADDO, s8)
406                       .addDef(CarryReg)
407                       .addUse(MIBTrunc->getOperand(0).getReg())
408                       .addUse(MIBTrunc->getOperand(0).getReg());
409   AInfo Info(MF->getSubtarget());
410   DummyGISelObserver Observer;
411   LegalizerHelper Helper(*MF, Info, Observer);
412   ASSERT_TRUE(Helper.widenScalar(*MIBUAddO, 0, s16) ==
413               LegalizerHelper::LegalizeResult::Legalized);
414 
415   auto CheckStr = R"(
416   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
417   CHECK: [[LHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
418   CHECK: [[RHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
419   CHECK: [[ADD:%[0-9]+]]:_(s16) = G_ADD [[LHS]]:_, [[RHS]]:_
420   CHECK: [[CST:%[0-9]+]]:_(s16) = G_CONSTANT i16 255
421   CHECK: [[AND:%[0-9]+]]:_(s16) = G_AND [[ADD]]:_, [[CST]]:_
422   CHECK: G_ICMP intpred(ne), [[ADD]]:_(s16), [[AND]]:_
423   CHECK: G_TRUNC [[ADD]]
424   )";
425 
426   // Check
427   ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
428 }
429 
430 // USUBO widening.
431 TEST_F(LegalizerHelperTest, WidenUSUBO) {
432   if (!TM)
433     return;
434 
435   // Declare your legalization info
436   DefineLegalizerInfo(A,
437                       { getActionDefinitionsBuilder(G_SUB).legalFor({s16}); });
438   // Build
439   // Trunc it to s8.
440   LLT s8{LLT::scalar(8)};
441   LLT s16{LLT::scalar(16)};
442   auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
443   unsigned CarryReg = MRI->createGenericVirtualRegister(LLT::scalar(1));
444   auto MIBUSUBO = B.buildInstr(TargetOpcode::G_USUBO, s8)
445                       .addDef(CarryReg)
446                       .addUse(MIBTrunc->getOperand(0).getReg())
447                       .addUse(MIBTrunc->getOperand(0).getReg());
448   AInfo Info(MF->getSubtarget());
449   DummyGISelObserver Observer;
450   LegalizerHelper Helper(*MF, Info, Observer);
451   ASSERT_TRUE(Helper.widenScalar(*MIBUSUBO, 0, s16) ==
452               LegalizerHelper::LegalizeResult::Legalized);
453 
454   auto CheckStr = R"(
455   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
456   CHECK: [[LHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
457   CHECK: [[RHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
458   CHECK: [[SUB:%[0-9]+]]:_(s16) = G_SUB [[LHS]]:_, [[RHS]]:_
459   CHECK: [[CST:%[0-9]+]]:_(s16) = G_CONSTANT i16 255
460   CHECK: [[AND:%[0-9]+]]:_(s16) = G_AND [[SUB]]:_, [[CST]]:_
461   CHECK: G_ICMP intpred(ne), [[SUB]]:_(s16), [[AND]]:_
462   CHECK: G_TRUNC [[SUB]]
463   )";
464 
465   // Check
466   ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
467 }
468 } // namespace
469