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