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