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