xref: /llvm-project/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp (revision 4c6ab48fb1149c4f1f1d2953f5d232211b3a6bce)
1 //===- LegalizerHelperTest.cpp
2 //-----------------------------------------------===//
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "GISelMITest.h"
11 
12 using namespace LegalizeActions;
13 using namespace LegalizeMutations;
14 using namespace LegalityPredicates;
15 
16 namespace {
17 
18 class DummyGISelObserver : public GISelChangeObserver {
19 public:
20   void changingInstr(MachineInstr &MI) override {}
21   void changedInstr(MachineInstr &MI) override {}
22   void createdInstr(MachineInstr &MI) override {}
23   void erasingInstr(MachineInstr &MI) override {}
24 };
25 
26 // Test CTTZ expansion when CTTZ_ZERO_UNDEF is legal or custom,
27 // in which case it becomes CTTZ_ZERO_UNDEF with select.
28 TEST_F(AArch64GISelMITest, LowerBitCountingCTTZ0) {
29   setUp();
30   if (!TM)
31     return;
32 
33   // Declare your legalization info
34   DefineLegalizerInfo(A, {
35     getActionDefinitionsBuilder(G_CTTZ_ZERO_UNDEF).legalFor({{s32, s64}});
36   });
37   // Build Instr
38   auto MIBCTTZ =
39       B.buildInstr(TargetOpcode::G_CTTZ, {LLT::scalar(32)}, {Copies[0]});
40   AInfo Info(MF->getSubtarget());
41   DummyGISelObserver Observer;
42   LegalizerHelper Helper(*MF, Info, Observer, B);
43   // Perform Legalization
44   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
45             Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)));
46 
47   auto CheckStr = R"(
48   CHECK: [[CZU:%[0-9]+]]:_(s32) = G_CTTZ_ZERO_UNDEF %0
49   CHECK: [[ZERO:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
50   CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), %0:_(s64), [[ZERO]]
51   CHECK: [[SIXTY4:%[0-9]+]]:_(s32) = G_CONSTANT i32 64
52   CHECK: [[SEL:%[0-9]+]]:_(s32) = G_SELECT [[CMP]]:_(s1), [[SIXTY4]]:_, [[CZU]]
53   )";
54 
55   // Check
56   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
57 }
58 
59 // CTTZ expansion in terms of CTLZ
60 TEST_F(AArch64GISelMITest, LowerBitCountingCTTZ1) {
61   setUp();
62   if (!TM)
63     return;
64 
65   // Declare your legalization info
66   DefineLegalizerInfo(A, {
67     getActionDefinitionsBuilder(G_CTLZ).legalFor({{s64, s64}});
68   });
69   // Build Instr
70   auto MIBCTTZ =
71       B.buildInstr(TargetOpcode::G_CTTZ, {LLT::scalar(64)}, {Copies[0]});
72   AInfo Info(MF->getSubtarget());
73   DummyGISelObserver Observer;
74   LegalizerHelper Helper(*MF, Info, Observer, B);
75   // Perform Legalization
76   EXPECT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) ==
77               LegalizerHelper::LegalizeResult::Legalized);
78 
79   auto CheckStr = R"(
80   CHECK: [[NEG1:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1
81   CHECK: [[NOT:%[0-9]+]]:_(s64) = G_XOR %0:_, [[NEG1]]
82   CHECK: [[SUB1:%[0-9]+]]:_(s64) = G_ADD %0:_, [[NEG1]]
83   CHECK: [[AND1:%[0-9]+]]:_(s64) = G_AND [[NOT]]:_, [[SUB1]]:_
84   CHECK: [[CST64:%[0-9]+]]:_(s64) = G_CONSTANT i64 64
85   CHECK: [[CTLZ:%[0-9]+]]:_(s64) = G_CTLZ [[AND1]]:_
86   CHECK: G_SUB [[CST64]]:_, [[CTLZ]]:_
87   )";
88 
89   // Check
90   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
91 }
92 
93 // CTLZ scalar narrowing
94 TEST_F(AArch64GISelMITest, NarrowScalarCTLZ) {
95   setUp();
96   if (!TM)
97     return;
98 
99   // Declare your legalization info
100   DefineLegalizerInfo(A, {
101     getActionDefinitionsBuilder(G_CTLZ).legalFor({{s32, s32}});
102   });
103   // Build Instr
104   auto CTLZ =
105       B.buildInstr(TargetOpcode::G_CTLZ, {LLT::scalar(32)}, {Copies[0]});
106   AInfo Info(MF->getSubtarget());
107   DummyGISelObserver Observer;
108   LegalizerHelper Helper(*MF, Info, Observer, B);
109   // Perform Legalization
110   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
111             Helper.narrowScalar(*CTLZ, 1, LLT::scalar(32)));
112 
113   auto CheckStr = R"(
114   CHECK: [[UNMERGE_LO:%[0-9]+]]:_(s32), [[UNMERGE_HI:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES %0:_(s64)
115   CHECK: [[ZERO:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
116   CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[UNMERGE_HI]]:_(s32), [[ZERO]]:_
117   CHECK: [[CTLZ_LO:%[0-9]+]]:_(s32) = G_CTLZ [[UNMERGE_LO]]:_(s32)
118   CHECK: [[THIRTYTWO:%[0-9]+]]:_(s32) = G_CONSTANT i32 32
119   CHECK: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[CTLZ_LO]]:_, [[THIRTYTWO]]:_
120   CHECK: [[CTLZ_HI:%[0-9]+]]:_(s32) = G_CTLZ_ZERO_UNDEF [[UNMERGE_HI]]:_(s32)
121   CHECK: %{{[0-9]+}}:_(s32) = G_SELECT [[CMP]]:_(s1), [[ADD]]:_, [[CTLZ_HI]]:_
122   )";
123 
124   // Check
125   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
126 }
127 
128 // CTTZ scalar narrowing
129 TEST_F(AArch64GISelMITest, NarrowScalarCTTZ) {
130   setUp();
131   if (!TM)
132     return;
133 
134   // Declare your legalization info
135   DefineLegalizerInfo(A, {
136     getActionDefinitionsBuilder(G_CTTZ).legalFor({{s32, s64}});
137   });
138   // Build Instr
139   auto CTTZ =
140       B.buildInstr(TargetOpcode::G_CTTZ, {LLT::scalar(32)}, {Copies[0]});
141   AInfo Info(MF->getSubtarget());
142   DummyGISelObserver Observer;
143   LegalizerHelper Helper(*MF, Info, Observer, B);
144   // Perform Legalization
145   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
146             Helper.narrowScalar(*CTTZ, 1, LLT::scalar(32)));
147 
148   auto CheckStr = R"(
149   CHECK: [[UNMERGE_LO:%[0-9]+]]:_(s32), [[UNMERGE_HI:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES %0:_(s64)
150   CHECK: [[ZERO:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
151   CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[UNMERGE_LO]]:_(s32), [[ZERO]]:_
152   CHECK: [[CTTZ_HI:%[0-9]+]]:_(s32) = G_CTTZ [[UNMERGE_HI]]:_(s32)
153   CHECK: [[THIRTYTWO:%[0-9]+]]:_(s32) = G_CONSTANT i32 32
154   CHECK: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[CTTZ_HI]]:_, [[THIRTYTWO]]:_
155   CHECK: [[CTTZ_LO:%[0-9]+]]:_(s32) = G_CTTZ_ZERO_UNDEF [[UNMERGE_LO]]:_(s32)
156   CHECK: %{{[0-9]+}}:_(s32) = G_SELECT [[CMP]]:_(s1), [[ADD]]:_, [[CTTZ_LO]]:_
157   )";
158 
159   // Check
160   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
161 }
162 
163 // CTTZ expansion in terms of CTPOP
164 TEST_F(AArch64GISelMITest, LowerBitCountingCTTZ2) {
165   setUp();
166   if (!TM)
167     return;
168 
169   // Declare your legalization info
170   DefineLegalizerInfo(A, {
171     getActionDefinitionsBuilder(G_CTPOP).legalFor({{s64, s64}});
172   });
173   // Build
174   auto MIBCTTZ =
175       B.buildInstr(TargetOpcode::G_CTTZ, {LLT::scalar(64)}, {Copies[0]});
176   AInfo Info(MF->getSubtarget());
177   DummyGISelObserver Observer;
178   LegalizerHelper Helper(*MF, Info, Observer, B);
179 
180   B.setInsertPt(*EntryMBB, MIBCTTZ->getIterator());
181   EXPECT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) ==
182               LegalizerHelper::LegalizeResult::Legalized);
183 
184   auto CheckStr = R"(
185   CHECK: [[NEG1:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1
186   CHECK: [[NOT:%[0-9]+]]:_(s64) = G_XOR %0:_, [[NEG1]]
187   CHECK: [[SUB1:%[0-9]+]]:_(s64) = G_ADD %0:_, [[NEG1]]
188   CHECK: [[AND1:%[0-9]+]]:_(s64) = G_AND [[NOT]]:_, [[SUB1]]:_
189   CHECK: [[POP:%[0-9]+]]:_(s64) = G_CTPOP [[AND1]]
190   )";
191 
192   // Check
193   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
194 }
195 
196 // CTPOP widening.
197 TEST_F(AArch64GISelMITest, WidenBitCountingCTPOP1) {
198   setUp();
199   if (!TM)
200     return;
201 
202   // Declare your legalization info
203   DefineLegalizerInfo(A, {
204       getActionDefinitionsBuilder(G_CTPOP).legalFor({{s16, s16}});
205     });
206 
207   // Build
208   // Trunc it to s8.
209   LLT s8{LLT::scalar(8)};
210   LLT s16{LLT::scalar(16)};
211   auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
212   auto MIBCTPOP = B.buildInstr(TargetOpcode::G_CTPOP, {s16}, {MIBTrunc});
213   AInfo Info(MF->getSubtarget());
214   DummyGISelObserver Observer;
215   LegalizerHelper Helper(*MF, Info, Observer, B);
216   B.setInstr(*MIBCTPOP);
217   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
218             Helper.widenScalar(*MIBCTPOP, 1, s16));
219 
220   auto CheckStr = R"(
221   CHECK: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC %0:_(s64)
222   CHECK: [[ZEXT:%[0-9]+]]:_(s16) = G_ZEXT [[TRUNC]]:_(s8)
223   CHECK: [[CTPOP:%[0-9]+]]:_(s16) = G_CTPOP [[ZEXT]]
224   CHECK: [[COPY:%[0-9]+]]:_(s16) = COPY [[CTPOP]]:_(s16)
225   )";
226 
227   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
228 }
229 
230 // Test a strange case where the result is wider than the source
231 TEST_F(AArch64GISelMITest, WidenBitCountingCTPOP2) {
232   setUp();
233   if (!TM)
234     return;
235 
236   // Declare your legalization info
237   DefineLegalizerInfo(A, {
238       getActionDefinitionsBuilder(G_CTPOP).legalFor({{s32, s16}});
239     });
240 
241   // Build
242   // Trunc it to s8.
243   LLT s8{LLT::scalar(8)};
244   LLT s16{LLT::scalar(16)};
245   LLT s32{LLT::scalar(32)};
246   auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
247   auto MIBCTPOP = B.buildInstr(TargetOpcode::G_CTPOP, {s32}, {MIBTrunc});
248   AInfo Info(MF->getSubtarget());
249   DummyGISelObserver Observer;
250   LegalizerHelper Helper(*MF, Info, Observer, B);
251   B.setInstr(*MIBCTPOP);
252   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
253             Helper.widenScalar(*MIBCTPOP, 1, s16));
254 
255   auto CheckStr = R"(
256   CHECK: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC %0:_(s64)
257   CHECK: [[ZEXT:%[0-9]+]]:_(s16) = G_ZEXT [[TRUNC]]:_(s8)
258   CHECK: [[CTPOP:%[0-9]+]]:_(s16) = G_CTPOP [[ZEXT]]
259   CHECK: [[COPY:%[0-9]+]]:_(s32) = G_ZEXT [[CTPOP]]:_(s16)
260   )";
261 
262   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
263 }
264 
265 // CTTZ_ZERO_UNDEF expansion in terms of CTTZ
266 TEST_F(AArch64GISelMITest, LowerBitCountingCTTZ3) {
267   setUp();
268   if (!TM)
269     return;
270 
271   // Declare your legalization info
272   DefineLegalizerInfo(A, {
273     getActionDefinitionsBuilder(G_CTTZ).legalFor({{s64, s64}});
274   });
275   // Build
276   auto MIBCTTZ = B.buildInstr(TargetOpcode::G_CTTZ_ZERO_UNDEF,
277                               {LLT::scalar(64)}, {Copies[0]});
278   AInfo Info(MF->getSubtarget());
279   DummyGISelObserver Observer;
280   LegalizerHelper Helper(*MF, Info, Observer, B);
281   EXPECT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) ==
282               LegalizerHelper::LegalizeResult::Legalized);
283 
284   auto CheckStr = R"(
285   CHECK: CTTZ
286   )";
287 
288   // Check
289   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
290 }
291 
292 // CTLZ expansion in terms of CTLZ_ZERO_UNDEF
293 TEST_F(AArch64GISelMITest, LowerBitCountingCTLZ0) {
294   setUp();
295   if (!TM)
296     return;
297 
298   // Declare your legalization info
299   DefineLegalizerInfo(A, {
300     getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF).legalFor({{s64, s64}});
301   });
302   // Build
303   auto MIBCTLZ =
304       B.buildInstr(TargetOpcode::G_CTLZ, {LLT::scalar(64)}, {Copies[0]});
305   AInfo Info(MF->getSubtarget());
306   DummyGISelObserver Observer;
307   LegalizerHelper Helper(*MF, Info, Observer, B);
308   EXPECT_TRUE(Helper.lower(*MIBCTLZ, 0, LLT::scalar(64)) ==
309               LegalizerHelper::LegalizeResult::Legalized);
310 
311   auto CheckStr = R"(
312   CHECK: [[CZU:%[0-9]+]]:_(s64) = G_CTLZ_ZERO_UNDEF %0
313   CHECK: [[ZERO:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
314   CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), %0:_(s64), [[ZERO]]
315   CHECK: [[SIXTY4:%[0-9]+]]:_(s64) = G_CONSTANT i64 64
316   CHECK: [[SEL:%[0-9]+]]:_(s64) = G_SELECT [[CMP]]:_(s1), [[SIXTY4]]:_, [[CZU]]
317   )";
318 
319   // Check
320   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
321 }
322 
323 // CTLZ expansion in terms of CTLZ_ZERO_UNDEF if the latter is a libcall
324 TEST_F(AArch64GISelMITest, LowerBitCountingCTLZLibcall) {
325   setUp();
326   if (!TM)
327     return;
328 
329   // Declare your legalization info
330   DefineLegalizerInfo(A, {
331     getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF).libcallFor({{s32, s64}});
332   });
333   // Build
334   auto MIBCTLZ =
335       B.buildInstr(TargetOpcode::G_CTLZ, {LLT::scalar(32)}, {Copies[0]});
336   AInfo Info(MF->getSubtarget());
337   DummyGISelObserver Observer;
338   LegalizerHelper Helper(*MF, Info, Observer, B);
339   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
340             Helper.lower(*MIBCTLZ, 0, LLT::scalar(32)));
341 
342   auto CheckStr = R"(
343   CHECK: [[CZU:%[0-9]+]]:_(s32) = G_CTLZ_ZERO_UNDEF %0
344   CHECK: [[ZERO:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
345   CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), %0:_(s64), [[ZERO]]
346   CHECK: [[THIRTY2:%[0-9]+]]:_(s32) = G_CONSTANT i32 64
347   CHECK: [[SEL:%[0-9]+]]:_(s32) = G_SELECT [[CMP]]:_(s1), [[THIRTY2]]:_, [[CZU]]
348   )";
349 
350   // Check
351   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
352 }
353 
354 // CTLZ expansion
355 TEST_F(AArch64GISelMITest, LowerBitCountingCTLZ1) {
356   setUp();
357   if (!TM)
358     return;
359 
360   // Declare your legalization info
361   DefineLegalizerInfo(A, {
362     getActionDefinitionsBuilder(G_CTPOP).legalFor({{s8, s8}});
363   });
364   // Build
365   // Trunc it to s8.
366   LLT s8{LLT::scalar(8)};
367   auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
368   auto MIBCTLZ = B.buildInstr(TargetOpcode::G_CTLZ, {s8}, {MIBTrunc});
369   AInfo Info(MF->getSubtarget());
370   DummyGISelObserver Observer;
371   LegalizerHelper Helper(*MF, Info, Observer, B);
372   EXPECT_TRUE(Helper.lower(*MIBCTLZ, 0, s8) ==
373               LegalizerHelper::LegalizeResult::Legalized);
374 
375   auto CheckStr = R"(
376   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
377   CHECK: [[Cst1:%[0-9]+]]:_(s8) = G_CONSTANT i8 1
378   CHECK: [[Sh1:%[0-9]+]]:_(s8) = G_LSHR [[Trunc]]:_, [[Cst1]]:_
379   CHECK: [[Or1:%[0-9]+]]:_(s8) = G_OR [[Trunc]]:_, [[Sh1]]:_
380   CHECK: [[Cst2:%[0-9]+]]:_(s8) = G_CONSTANT i8 2
381   CHECK: [[Sh2:%[0-9]+]]:_(s8) = G_LSHR [[Or1]]:_, [[Cst2]]:_
382   CHECK: [[Or2:%[0-9]+]]:_(s8) = G_OR [[Or1]]:_, [[Sh2]]:_
383   CHECK: [[Cst4:%[0-9]+]]:_(s8) = G_CONSTANT i8 4
384   CHECK: [[Sh4:%[0-9]+]]:_(s8) = G_LSHR [[Or2]]:_, [[Cst4]]:_
385   CHECK: [[Or4:%[0-9]+]]:_(s8) = G_OR [[Or2]]:_, [[Sh4]]:_
386   CHECK: [[CTPOP:%[0-9]+]]:_(s8) = G_CTPOP [[Or4]]:_
387   CHECK: [[Len:%[0-9]+]]:_(s8) = G_CONSTANT i8 8
388   CHECK: [[Sub:%[0-9]+]]:_(s8) = G_SUB [[Len]]:_, [[CTPOP]]:_
389   )";
390 
391   // Check
392   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
393 }
394 
395 // CTLZ widening.
396 TEST_F(AArch64GISelMITest, WidenBitCountingCTLZ) {
397   setUp();
398   if (!TM)
399     return;
400 
401   // Declare your legalization info
402   DefineLegalizerInfo(A, {
403     getActionDefinitionsBuilder(G_CTLZ).legalFor({{s16, s16}});
404   });
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   auto MIBCTLZ = B.buildInstr(TargetOpcode::G_CTLZ, {s8}, {MIBTrunc});
411   AInfo Info(MF->getSubtarget());
412   DummyGISelObserver Observer;
413   LegalizerHelper Helper(*MF, Info, Observer, B);
414   EXPECT_TRUE(Helper.widenScalar(*MIBCTLZ, 1, s16) ==
415               LegalizerHelper::LegalizeResult::Legalized);
416 
417   auto CheckStr = R"(
418   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
419   CHECK: [[Zext:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
420   CHECK: [[Ctlz:%[0-9]+]]:_(s16) = G_CTLZ [[Zext]]
421   CHECK: [[Cst8:%[0-9]+]]:_(s16) = G_CONSTANT i16 8
422   CHECK: [[Sub:%[0-9]+]]:_(s16) = G_SUB [[Ctlz]]:_, [[Cst8]]:_
423   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC [[Sub]]
424   )";
425 
426   // Check
427   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
428 }
429 
430 // CTLZ_ZERO_UNDEF widening.
431 TEST_F(AArch64GISelMITest, WidenBitCountingCTLZZeroUndef) {
432   setUp();
433   if (!TM)
434     return;
435 
436   // Declare your legalization info
437   DefineLegalizerInfo(A, {
438     getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF).legalFor({{s16, s16}});
439   });
440   // Build
441   // Trunc it to s8.
442   LLT s8{LLT::scalar(8)};
443   LLT s16{LLT::scalar(16)};
444   auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
445   auto MIBCTLZ_ZU =
446       B.buildInstr(TargetOpcode::G_CTLZ_ZERO_UNDEF, {s8}, {MIBTrunc});
447   AInfo Info(MF->getSubtarget());
448   DummyGISelObserver Observer;
449   LegalizerHelper Helper(*MF, Info, Observer, B);
450   EXPECT_TRUE(Helper.widenScalar(*MIBCTLZ_ZU, 1, s16) ==
451               LegalizerHelper::LegalizeResult::Legalized);
452 
453   auto CheckStr = R"(
454   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
455   CHECK: [[Zext:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
456   CHECK: [[CtlzZu:%[0-9]+]]:_(s16) = G_CTLZ_ZERO_UNDEF [[Zext]]
457   CHECK: [[Cst8:%[0-9]+]]:_(s16) = G_CONSTANT i16 8
458   CHECK: [[Sub:%[0-9]+]]:_(s16) = G_SUB [[CtlzZu]]:_, [[Cst8]]:_
459   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC [[Sub]]
460   )";
461 
462   // Check
463   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
464 }
465 
466 // CTPOP widening.
467 TEST_F(AArch64GISelMITest, WidenBitCountingCTPOP) {
468   setUp();
469   if (!TM)
470     return;
471 
472   // Declare your legalization info
473   DefineLegalizerInfo(A, {
474     getActionDefinitionsBuilder(G_CTPOP).legalFor({{s16, s16}});
475   });
476   // Build
477   // Trunc it to s8.
478   LLT s8{LLT::scalar(8)};
479   LLT s16{LLT::scalar(16)};
480   auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
481   auto MIBCTPOP = B.buildInstr(TargetOpcode::G_CTPOP, {s8}, {MIBTrunc});
482   AInfo Info(MF->getSubtarget());
483   DummyGISelObserver Observer;
484   LegalizerHelper Helper(*MF, Info, Observer, B);
485   EXPECT_TRUE(Helper.widenScalar(*MIBCTPOP, 1, s16) ==
486               LegalizerHelper::LegalizeResult::Legalized);
487 
488   auto CheckStr = R"(
489   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
490   CHECK: [[Zext:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
491   CHECK: [[Ctpop:%[0-9]+]]:_(s16) = G_CTPOP [[Zext]]
492   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC [[Ctpop]]
493   )";
494 
495   // Check
496   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
497 }
498 
499 // CTTZ_ZERO_UNDEF widening.
500 TEST_F(AArch64GISelMITest, WidenBitCountingCTTZ_ZERO_UNDEF) {
501   setUp();
502   if (!TM)
503     return;
504 
505   // Declare your legalization info
506   DefineLegalizerInfo(A, {
507     getActionDefinitionsBuilder(G_CTTZ_ZERO_UNDEF).legalFor({{s16, s16}});
508   });
509   // Build
510   // Trunc it to s8.
511   LLT s8{LLT::scalar(8)};
512   LLT s16{LLT::scalar(16)};
513   auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
514   auto MIBCTTZ_ZERO_UNDEF =
515       B.buildInstr(TargetOpcode::G_CTTZ_ZERO_UNDEF, {s8}, {MIBTrunc});
516   AInfo Info(MF->getSubtarget());
517   DummyGISelObserver Observer;
518   LegalizerHelper Helper(*MF, Info, Observer, B);
519   EXPECT_TRUE(Helper.widenScalar(*MIBCTTZ_ZERO_UNDEF, 1, s16) ==
520               LegalizerHelper::LegalizeResult::Legalized);
521 
522   auto CheckStr = R"(
523   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
524   CHECK: [[Zext:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
525   CHECK: [[CttzZu:%[0-9]+]]:_(s16) = G_CTTZ_ZERO_UNDEF [[Zext]]
526   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC [[CttzZu]]
527   )";
528 
529   // Check
530   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
531 }
532 
533 // CTTZ widening.
534 TEST_F(AArch64GISelMITest, WidenBitCountingCTTZ) {
535   setUp();
536   if (!TM)
537     return;
538 
539   // Declare your legalization info
540   DefineLegalizerInfo(A, {
541     getActionDefinitionsBuilder(G_CTTZ).legalFor({{s16, s16}});
542   });
543   // Build
544   // Trunc it to s8.
545   LLT s8{LLT::scalar(8)};
546   LLT s16{LLT::scalar(16)};
547   auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
548   auto MIBCTTZ = B.buildInstr(TargetOpcode::G_CTTZ, {s8}, {MIBTrunc});
549   AInfo Info(MF->getSubtarget());
550   DummyGISelObserver Observer;
551   LegalizerHelper Helper(*MF, Info, Observer, B);
552   EXPECT_TRUE(Helper.widenScalar(*MIBCTTZ, 1, s16) ==
553               LegalizerHelper::LegalizeResult::Legalized);
554 
555   auto CheckStr = R"(
556   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
557   CHECK: [[Zext:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
558   CHECK: [[Cst:%[0-9]+]]:_(s16) = G_CONSTANT i16 256
559   CHECK: [[Or:%[0-9]+]]:_(s16) = G_OR [[Zext]]:_, [[Cst]]
560   CHECK: [[Cttz:%[0-9]+]]:_(s16) = G_CTTZ [[Or]]
561   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC [[Cttz]]
562   )";
563 
564   // Check
565   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
566 }
567 // UADDO widening.
568 TEST_F(AArch64GISelMITest, WidenUADDO) {
569   setUp();
570   if (!TM)
571     return;
572 
573   // Declare your legalization info
574   DefineLegalizerInfo(A, {
575     getActionDefinitionsBuilder(G_ADD).legalFor({{s16, s16}});
576   });
577   // Build
578   // Trunc it to s8.
579   LLT s8{LLT::scalar(8)};
580   LLT s16{LLT::scalar(16)};
581   auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
582   unsigned CarryReg = MRI->createGenericVirtualRegister(LLT::scalar(1));
583   auto MIBUAddO =
584       B.buildInstr(TargetOpcode::G_UADDO, {s8, CarryReg}, {MIBTrunc, MIBTrunc});
585   AInfo Info(MF->getSubtarget());
586   DummyGISelObserver Observer;
587   LegalizerHelper Helper(*MF, Info, Observer, B);
588   EXPECT_TRUE(Helper.widenScalar(*MIBUAddO, 0, s16) ==
589               LegalizerHelper::LegalizeResult::Legalized);
590 
591   auto CheckStr = R"(
592   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
593   CHECK: [[LHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
594   CHECK: [[RHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
595   CHECK: [[ADD:%[0-9]+]]:_(s16) = G_ADD [[LHS]]:_, [[RHS]]:_
596   CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[ADD]]
597   CHECK: [[ZEXT:%[0-9]+]]:_(s16) = G_ZEXT [[TRUNC1]]
598   CHECK: G_ICMP intpred(ne), [[ADD]]:_(s16), [[ZEXT]]:_
599   CHECK: G_TRUNC [[ADD]]
600   )";
601 
602   // Check
603   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
604 }
605 
606 // USUBO widening.
607 TEST_F(AArch64GISelMITest, WidenUSUBO) {
608   setUp();
609   if (!TM)
610     return;
611 
612   // Declare your legalization info
613   DefineLegalizerInfo(A, {
614     getActionDefinitionsBuilder(G_SUB).legalFor({{s16, s16}});
615   });
616   // Build
617   // Trunc it to s8.
618   LLT s8{LLT::scalar(8)};
619   LLT s16{LLT::scalar(16)};
620   auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
621   unsigned CarryReg = MRI->createGenericVirtualRegister(LLT::scalar(1));
622   auto MIBUSUBO =
623       B.buildInstr(TargetOpcode::G_USUBO, {s8, CarryReg}, {MIBTrunc, MIBTrunc});
624   AInfo Info(MF->getSubtarget());
625   DummyGISelObserver Observer;
626   LegalizerHelper Helper(*MF, Info, Observer, B);
627   EXPECT_TRUE(Helper.widenScalar(*MIBUSUBO, 0, s16) ==
628               LegalizerHelper::LegalizeResult::Legalized);
629 
630   auto CheckStr = R"(
631   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
632   CHECK: [[LHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
633   CHECK: [[RHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
634   CHECK: [[SUB:%[0-9]+]]:_(s16) = G_SUB [[LHS]]:_, [[RHS]]:_
635   CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[SUB]]
636   CHECK: [[ZEXT:%[0-9]+]]:_(s16) = G_ZEXT [[TRUNC1]]
637   CHECK: G_ICMP intpred(ne), [[SUB]]:_(s16), [[ZEXT]]:_
638   CHECK: G_TRUNC [[SUB]]
639   )";
640 
641   // Check
642   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
643 }
644 
645 // SADDO widening.
646 TEST_F(AArch64GISelMITest, WidenSADDO) {
647   setUp();
648   if (!TM)
649     return;
650 
651   // Declare your legalization info
652   DefineLegalizerInfo(A, {
653     getActionDefinitionsBuilder(G_ADD).legalFor({{s16, s16}});
654   });
655   // Build
656   // Trunc it to s8.
657   LLT s8{LLT::scalar(8)};
658   LLT s16{LLT::scalar(16)};
659   auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
660   unsigned CarryReg = MRI->createGenericVirtualRegister(LLT::scalar(1));
661   auto MIBSAddO =
662       B.buildInstr(TargetOpcode::G_SADDO, {s8, CarryReg}, {MIBTrunc, MIBTrunc});
663   AInfo Info(MF->getSubtarget());
664   DummyGISelObserver Observer;
665   LegalizerHelper Helper(*MF, Info, Observer, B);
666   EXPECT_TRUE(Helper.widenScalar(*MIBSAddO, 0, s16) ==
667               LegalizerHelper::LegalizeResult::Legalized);
668 
669   auto CheckStr = R"(
670   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
671   CHECK: [[LHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]]
672   CHECK: [[RHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]]
673   CHECK: [[ADD:%[0-9]+]]:_(s16) = G_ADD [[LHS]]:_, [[RHS]]:_
674   CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[ADD]]
675   CHECK: [[SEXT:%[0-9]+]]:_(s16) = G_SEXT [[TRUNC1]]
676   CHECK: G_ICMP intpred(ne), [[ADD]]:_(s16), [[SEXT]]:_
677   CHECK: G_TRUNC [[ADD]]
678   )";
679 
680   // Check
681   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
682 }
683 
684 // SSUBO widening.
685 TEST_F(AArch64GISelMITest, WidenSSUBO) {
686   setUp();
687   if (!TM)
688     return;
689 
690   // Declare your legalization info
691   DefineLegalizerInfo(A, {
692     getActionDefinitionsBuilder(G_SUB).legalFor({{s16, s16}});
693   });
694   // Build
695   // Trunc it to s8.
696   LLT s8{LLT::scalar(8)};
697   LLT s16{LLT::scalar(16)};
698   auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
699   unsigned CarryReg = MRI->createGenericVirtualRegister(LLT::scalar(1));
700   auto MIBSSUBO =
701       B.buildInstr(TargetOpcode::G_SSUBO, {s8, CarryReg}, {MIBTrunc, MIBTrunc});
702   AInfo Info(MF->getSubtarget());
703   DummyGISelObserver Observer;
704   LegalizerHelper Helper(*MF, Info, Observer, B);
705   EXPECT_TRUE(Helper.widenScalar(*MIBSSUBO, 0, s16) ==
706               LegalizerHelper::LegalizeResult::Legalized);
707 
708   auto CheckStr = R"(
709   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
710   CHECK: [[LHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]]
711   CHECK: [[RHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]]
712   CHECK: [[SUB:%[0-9]+]]:_(s16) = G_SUB [[LHS]]:_, [[RHS]]:_
713   CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[SUB]]
714   CHECK: [[SEXT:%[0-9]+]]:_(s16) = G_SEXT [[TRUNC1]]
715   CHECK: G_ICMP intpred(ne), [[SUB]]:_(s16), [[SEXT]]:_
716   CHECK: G_TRUNC [[SUB]]
717   )";
718 
719   // Check
720   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
721 }
722 
723 TEST_F(AArch64GISelMITest, WidenUADDE) {
724   setUp();
725   if (!TM)
726     return;
727 
728   // Declare your legalization info
729   DefineLegalizerInfo(A, {
730     getActionDefinitionsBuilder(G_UADDE).legalFor({{s16, s16}});
731   });
732   // Build
733   // Trunc it to s8.
734   LLT s8{LLT::scalar(8)};
735   LLT s16{LLT::scalar(16)};
736   auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
737   auto CarryIn = B.buildUndef(LLT::scalar(1));
738   Register CarryReg = MRI->createGenericVirtualRegister(LLT::scalar(1));
739   auto MIBUAddO = B.buildInstr(TargetOpcode::G_UADDE, {s8, CarryReg},
740                                {MIBTrunc, MIBTrunc, CarryIn});
741   AInfo Info(MF->getSubtarget());
742   DummyGISelObserver Observer;
743   LegalizerHelper Helper(*MF, Info, Observer, B);
744   EXPECT_TRUE(Helper.widenScalar(*MIBUAddO, 0, s16) ==
745               LegalizerHelper::LegalizeResult::Legalized);
746 
747   const char *CheckStr = R"(
748   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
749   CHECK: [[Implicit:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF
750   CHECK: [[LHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
751   CHECK: [[RHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
752   CHECK: [[UADDE:%[0-9]+]]:_(s16), [[CARRY:%[0-9]+]]:_(s1) = G_UADDE [[LHS]]:_, [[RHS]]:_, [[Implicit]]:_
753   CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[UADDE]]
754   CHECK: [[ZEXT:%[0-9]+]]:_(s16) = G_ZEXT [[TRUNC1]]
755   CHECK: G_ICMP intpred(ne), [[UADDE]]:_(s16), [[ZEXT]]:_
756   CHECK: G_TRUNC [[UADDE]]
757   )";
758 
759   // Check
760   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
761 }
762 
763 TEST_F(AArch64GISelMITest, WidenUSUBE) {
764   setUp();
765   if (!TM)
766     return;
767 
768   // Declare your legalization info
769   DefineLegalizerInfo(A, {
770     getActionDefinitionsBuilder(G_USUBE).legalFor({{s16, s16}});
771   });
772   // Build
773   // Trunc it to s8.
774   LLT s8{LLT::scalar(8)};
775   LLT s16{LLT::scalar(16)};
776   auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
777   auto CarryIn = B.buildUndef(LLT::scalar(1));
778   Register CarryReg = MRI->createGenericVirtualRegister(LLT::scalar(1));
779   auto MIBUSUBE = B.buildInstr(TargetOpcode::G_USUBE, {s8, CarryReg},
780                                {MIBTrunc, MIBTrunc, CarryIn});
781   AInfo Info(MF->getSubtarget());
782   DummyGISelObserver Observer;
783   LegalizerHelper Helper(*MF, Info, Observer, B);
784   EXPECT_TRUE(Helper.widenScalar(*MIBUSUBE, 0, s16) ==
785               LegalizerHelper::LegalizeResult::Legalized);
786 
787   const char *CheckStr = R"(
788   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
789   CHECK: [[Implicit:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF
790   CHECK: [[LHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
791   CHECK: [[RHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
792   CHECK: [[USUBE:%[0-9]+]]:_(s16), [[CARRY:%[0-9]+]]:_(s1) = G_USUBE [[LHS]]:_, [[RHS]]:_, [[Implicit]]:_
793   CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[USUBE]]
794   CHECK: [[ZEXT:%[0-9]+]]:_(s16) = G_ZEXT [[TRUNC1]]
795   CHECK: G_ICMP intpred(ne), [[USUBE]]:_(s16), [[ZEXT]]:_
796   CHECK: G_TRUNC [[USUBE]]
797   )";
798 
799   // Check
800   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
801 }
802 
803 TEST_F(AArch64GISelMITest, WidenSADDE) {
804   setUp();
805   if (!TM)
806     return;
807 
808   // Declare your legalization info
809   DefineLegalizerInfo(A, {
810     getActionDefinitionsBuilder({G_SADDE, G_UADDE}).legalFor({{s16, s16}});
811   });
812   // Build
813   // Trunc it to s8.
814   LLT s8{LLT::scalar(8)};
815   LLT s16{LLT::scalar(16)};
816   auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
817   auto CarryIn = B.buildUndef(LLT::scalar(1));
818   Register CarryReg = MRI->createGenericVirtualRegister(LLT::scalar(1));
819   auto MIBUAddO = B.buildInstr(TargetOpcode::G_SADDE, {s8, CarryReg},
820                                {MIBTrunc, MIBTrunc, CarryIn});
821   AInfo Info(MF->getSubtarget());
822   DummyGISelObserver Observer;
823   LegalizerHelper Helper(*MF, Info, Observer, B);
824   EXPECT_TRUE(Helper.widenScalar(*MIBUAddO, 0, s16) ==
825               LegalizerHelper::LegalizeResult::Legalized);
826 
827   const char *CheckStr = R"(
828   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
829   CHECK: [[Implicit:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF
830   CHECK: [[LHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]]
831   CHECK: [[RHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]]
832   CHECK: [[SADDE:%[0-9]+]]:_(s16), [[CARRY:%[0-9]+]]:_(s1) = G_UADDE [[LHS]]:_, [[RHS]]:_, [[Implicit]]:_
833   CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[SADDE]]
834   CHECK: [[SEXT:%[0-9]+]]:_(s16) = G_SEXT [[TRUNC1]]
835   CHECK: G_ICMP intpred(ne), [[SADDE]]:_(s16), [[SEXT]]:_
836   CHECK: G_TRUNC [[SADDE]]
837   )";
838 
839   // Check
840   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
841 }
842 
843 TEST_F(AArch64GISelMITest, WidenSSUBE) {
844   setUp();
845   if (!TM)
846     return;
847 
848   // Declare your legalization info
849   DefineLegalizerInfo(A, {
850     getActionDefinitionsBuilder({G_SSUBE, G_USUBE}).legalFor({{s16, s16}});
851   });
852   // Build
853   // Trunc it to s8.
854   LLT s8{LLT::scalar(8)};
855   LLT s16{LLT::scalar(16)};
856   auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
857   auto CarryIn = B.buildUndef(LLT::scalar(1));
858   Register CarryReg = MRI->createGenericVirtualRegister(LLT::scalar(1));
859   auto MIBSSUBE = B.buildInstr(TargetOpcode::G_SSUBE, {s8, CarryReg},
860                                {MIBTrunc, MIBTrunc, CarryIn});
861   AInfo Info(MF->getSubtarget());
862   DummyGISelObserver Observer;
863   LegalizerHelper Helper(*MF, Info, Observer, B);
864   EXPECT_TRUE(Helper.widenScalar(*MIBSSUBE, 0, s16) ==
865               LegalizerHelper::LegalizeResult::Legalized);
866 
867   const char *CheckStr = R"(
868   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
869   CHECK: [[Implicit:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF
870   CHECK: [[LHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]]
871   CHECK: [[RHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]]
872   CHECK: [[SSUBE:%[0-9]+]]:_(s16), [[CARRY:%[0-9]+]]:_(s1) = G_USUBE [[LHS]]:_, [[RHS]]:_, [[Implicit]]:_
873   CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[SSUBE]]
874   CHECK: [[SEXT:%[0-9]+]]:_(s16) = G_SEXT [[TRUNC1]]
875   CHECK: G_ICMP intpred(ne), [[SSUBE]]:_(s16), [[SEXT]]:_
876   CHECK: G_TRUNC [[SSUBE]]
877   )";
878 
879   // Check
880   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
881 }
882 
883 TEST_F(AArch64GISelMITest, NarrowUADDO) {
884   setUp();
885   if (!TM)
886     return;
887 
888   LLT S1 = LLT::scalar(1);
889   LLT S32 = LLT::scalar(32);
890   LLT S96 = LLT::scalar(96);
891   DefineLegalizerInfo(A, {
892     getActionDefinitionsBuilder({G_UADDO, G_UADDE})
893         .legalFor({{LLT::scalar(32), LLT::scalar(1)}});
894   });
895 
896   auto Op0 = B.buildUndef(S96);
897   auto Op1 = B.buildUndef(S96);
898   auto UADDO = B.buildUAddo(S96, S1, Op0, Op1);
899 
900   AInfo Info(MF->getSubtarget());
901   DummyGISelObserver Observer;
902   LegalizerHelper Helper(*MF, Info, Observer, B);
903   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
904             Helper.narrowScalar(*UADDO, 0, S32));
905 
906   const char *CheckStr = R"(
907   CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
908   CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
909   CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]]
910   CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]]
911   CHECK: [[UADDO0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_UADDO [[OP0_0]]:_, [[OP1_0]]:_
912   CHECK: [[UADDO1:%[0-9]+]]:_(s32), [[CARRY1:%[0-9]+]]:_(s1) = G_UADDE [[OP0_1]]:_, [[OP1_1]]:_, [[CARRY0]]:_
913   CHECK: [[UADDO2:%[0-9]+]]:_(s32), [[CARRY2:%[0-9]+]]:_(s1) = G_UADDE [[OP0_2]]:_, [[OP1_2]]:_, [[CARRY1]]:_
914   CHECK: [[UADDO:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[UADDO0]]:_(s32), [[UADDO1]]:_(s32), [[UADDO2]]:_(s32)
915   )";
916 
917   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
918 }
919 
920 TEST_F(AArch64GISelMITest, NarrowUSUBO) {
921   setUp();
922   if (!TM)
923     return;
924 
925   LLT S1 = LLT::scalar(1);
926   LLT S32 = LLT::scalar(32);
927   LLT S96 = LLT::scalar(96);
928   DefineLegalizerInfo(A, {
929     getActionDefinitionsBuilder({G_USUBO, G_USUBE})
930         .legalFor({{LLT::scalar(32), LLT::scalar(1)}});
931   });
932 
933   auto Op0 = B.buildUndef(S96);
934   auto Op1 = B.buildUndef(S96);
935   auto USUBO = B.buildUSubo(S96, S1, Op0, Op1);
936 
937   AInfo Info(MF->getSubtarget());
938   DummyGISelObserver Observer;
939   LegalizerHelper Helper(*MF, Info, Observer, B);
940   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
941             Helper.narrowScalar(*USUBO, 0, S32));
942 
943   const char *CheckStr = R"(
944   CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
945   CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
946   CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]]
947   CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]]
948   CHECK: [[USUBO0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_USUBO [[OP0_0]]:_, [[OP1_0]]:_
949   CHECK: [[USUBO1:%[0-9]+]]:_(s32), [[CARRY1:%[0-9]+]]:_(s1) = G_USUBE [[OP0_1]]:_, [[OP1_1]]:_, [[CARRY0]]:_
950   CHECK: [[USUBO2:%[0-9]+]]:_(s32), [[CARRY2:%[0-9]+]]:_(s1) = G_USUBE [[OP0_2]]:_, [[OP1_2]]:_, [[CARRY1]]:_
951   CHECK: [[USUBO:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[USUBO0]]:_(s32), [[USUBO1]]:_(s32), [[USUBO2]]:_(s32)
952   )";
953 
954   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
955 }
956 
957 TEST_F(AArch64GISelMITest, NarrowSADDO) {
958   setUp();
959   if (!TM)
960     return;
961 
962   LLT S1 = LLT::scalar(1);
963   LLT S32 = LLT::scalar(32);
964   LLT S96 = LLT::scalar(96);
965   DefineLegalizerInfo(A, {
966     getActionDefinitionsBuilder({G_UADDO, G_UADDE, G_SADDE})
967         .legalFor({{LLT::scalar(32), LLT::scalar(1)}});
968   });
969 
970   auto Op0 = B.buildUndef(S96);
971   auto Op1 = B.buildUndef(S96);
972   auto SADDO = B.buildSAddo(S96, S1, Op0, Op1);
973 
974   AInfo Info(MF->getSubtarget());
975   DummyGISelObserver Observer;
976   LegalizerHelper Helper(*MF, Info, Observer, B);
977   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
978             Helper.narrowScalar(*SADDO, 0, S32));
979 
980   const char *CheckStr = R"(
981   CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
982   CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
983   CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]]
984   CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]]
985   CHECK: [[SADDO0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_UADDO [[OP0_0]]:_, [[OP1_0]]:_
986   CHECK: [[SADDO1:%[0-9]+]]:_(s32), [[CARRY1:%[0-9]+]]:_(s1) = G_UADDE [[OP0_1]]:_, [[OP1_1]]:_, [[CARRY0]]:_
987   CHECK: [[SADDO2:%[0-9]+]]:_(s32), [[CARRY2:%[0-9]+]]:_(s1) = G_SADDE [[OP0_2]]:_, [[OP1_2]]:_, [[CARRY1]]:_
988   CHECK: [[SADDO:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[SADDO0]]:_(s32), [[SADDO1]]:_(s32), [[SADDO2]]:_(s32)
989   )";
990 
991   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
992 }
993 
994 TEST_F(AArch64GISelMITest, NarrowSSUBO) {
995   setUp();
996   if (!TM)
997     return;
998 
999   LLT S1 = LLT::scalar(1);
1000   LLT S32 = LLT::scalar(32);
1001   LLT S96 = LLT::scalar(96);
1002   DefineLegalizerInfo(A, {
1003     getActionDefinitionsBuilder({G_USUBO, G_USUBE, G_SSUBE})
1004         .legalFor({{LLT::scalar(32), LLT::scalar(1)}});
1005   });
1006 
1007   auto Op0 = B.buildUndef(S96);
1008   auto Op1 = B.buildUndef(S96);
1009   auto SSUBO = B.buildSSubo(S96, S1, Op0, Op1);
1010 
1011   AInfo Info(MF->getSubtarget());
1012   DummyGISelObserver Observer;
1013   LegalizerHelper Helper(*MF, Info, Observer, B);
1014   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1015             Helper.narrowScalar(*SSUBO, 0, S32));
1016 
1017   const char *CheckStr = R"(
1018   CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
1019   CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
1020   CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]]
1021   CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]]
1022   CHECK: [[SSUBO0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_USUBO [[OP0_0]]:_, [[OP1_0]]:_
1023   CHECK: [[SSUBO1:%[0-9]+]]:_(s32), [[CARRY1:%[0-9]+]]:_(s1) = G_USUBE [[OP0_1]]:_, [[OP1_1]]:_, [[CARRY0]]:_
1024   CHECK: [[SSUBO2:%[0-9]+]]:_(s32), [[CARRY2:%[0-9]+]]:_(s1) = G_SSUBE [[OP0_2]]:_, [[OP1_2]]:_, [[CARRY1]]:_
1025   CHECK: [[SSUBO:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[SSUBO0]]:_(s32), [[SSUBO1]]:_(s32), [[SSUBO2]]:_(s32)
1026   )";
1027 
1028   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1029 }
1030 
1031 TEST_F(AArch64GISelMITest, NarrowUADDE) {
1032   setUp();
1033   if (!TM)
1034     return;
1035 
1036   LLT S1 = LLT::scalar(1);
1037   LLT S32 = LLT::scalar(32);
1038   LLT S96 = LLT::scalar(96);
1039   DefineLegalizerInfo(A, {
1040     getActionDefinitionsBuilder(G_UADDE).legalFor(
1041         {{LLT::scalar(32), LLT::scalar(1)}});
1042   });
1043 
1044   auto Op0 = B.buildUndef(S96);
1045   auto Op1 = B.buildUndef(S96);
1046   auto Op2 = B.buildUndef(S1);
1047   auto UADDE = B.buildUAdde(S96, S1, Op0, Op1, Op2);
1048 
1049   AInfo Info(MF->getSubtarget());
1050   DummyGISelObserver Observer;
1051   LegalizerHelper Helper(*MF, Info, Observer, B);
1052   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1053             Helper.narrowScalar(*UADDE, 0, S32));
1054 
1055   const char *CheckStr = R"(
1056   CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
1057   CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
1058   CHECK: [[IMP_DEF2:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF
1059   CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]]
1060   CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]]
1061   CHECK: [[UADDE0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_UADDE [[OP0_0]]:_, [[OP1_0]]:_, [[IMP_DEF2]]:_
1062   CHECK: [[UADDE1:%[0-9]+]]:_(s32), [[CARRY1:%[0-9]+]]:_(s1) = G_UADDE [[OP0_1]]:_, [[OP1_1]]:_, [[CARRY0]]:_
1063   CHECK: [[UADDE2:%[0-9]+]]:_(s32), [[CARRY2:%[0-9]+]]:_(s1) = G_UADDE [[OP0_2]]:_, [[OP1_2]]:_, [[CARRY1]]:_
1064   CHECK: [[UADDE:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[UADDE0]]:_(s32), [[UADDE1]]:_(s32), [[UADDE2]]:_(s32)
1065   )";
1066 
1067   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1068 }
1069 
1070 TEST_F(AArch64GISelMITest, NarrowUSUBE) {
1071   setUp();
1072   if (!TM)
1073     return;
1074 
1075   LLT S1 = LLT::scalar(1);
1076   LLT S32 = LLT::scalar(32);
1077   LLT S96 = LLT::scalar(96);
1078   DefineLegalizerInfo(A, {
1079     getActionDefinitionsBuilder(G_USUBE).legalFor(
1080         {{LLT::scalar(32), LLT::scalar(1)}});
1081   });
1082 
1083   auto Op0 = B.buildUndef(S96);
1084   auto Op1 = B.buildUndef(S96);
1085   auto Op2 = B.buildUndef(S1);
1086   auto USUBE = B.buildUSube(S96, S1, Op0, Op1, Op2);
1087 
1088   AInfo Info(MF->getSubtarget());
1089   DummyGISelObserver Observer;
1090   LegalizerHelper Helper(*MF, Info, Observer, B);
1091   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1092             Helper.narrowScalar(*USUBE, 0, S32));
1093 
1094   const char *CheckStr = R"(
1095   CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
1096   CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
1097   CHECK: [[IMP_DEF2:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF
1098   CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]]
1099   CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]]
1100   CHECK: [[USUBE0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_USUBE [[OP0_0]]:_, [[OP1_0]]:_, [[IMP_DEF2]]:_
1101   CHECK: [[USUBE1:%[0-9]+]]:_(s32), [[CARRY1:%[0-9]+]]:_(s1) = G_USUBE [[OP0_1]]:_, [[OP1_1]]:_, [[CARRY0]]:_
1102   CHECK: [[USUBE2:%[0-9]+]]:_(s32), [[CARRY2:%[0-9]+]]:_(s1) = G_USUBE [[OP0_2]]:_, [[OP1_2]]:_, [[CARRY1]]:_
1103   CHECK: [[USUBE:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[USUBE0]]:_(s32), [[USUBE1]]:_(s32), [[USUBE2]]:_(s32)
1104   )";
1105 
1106   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1107 }
1108 
1109 TEST_F(AArch64GISelMITest, NarrowSADDE) {
1110   setUp();
1111   if (!TM)
1112     return;
1113 
1114   LLT S1 = LLT::scalar(1);
1115   LLT S32 = LLT::scalar(32);
1116   LLT S96 = LLT::scalar(96);
1117   DefineLegalizerInfo(A, {
1118     getActionDefinitionsBuilder({G_SADDE, G_UADDE})
1119         .legalFor({{LLT::scalar(32), LLT::scalar(1)}});
1120   });
1121 
1122   auto Op0 = B.buildUndef(S96);
1123   auto Op1 = B.buildUndef(S96);
1124   auto Op2 = B.buildUndef(S1);
1125   auto SADDE = B.buildSAdde(S96, S1, Op0, Op1, Op2);
1126 
1127   AInfo Info(MF->getSubtarget());
1128   DummyGISelObserver Observer;
1129   LegalizerHelper Helper(*MF, Info, Observer, B);
1130   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1131             Helper.narrowScalar(*SADDE, 0, S32));
1132 
1133   const char *CheckStr = R"(
1134   CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
1135   CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
1136   CHECK: [[IMP_DEF2:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF
1137   CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]]
1138   CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]]
1139   CHECK: [[SADDE0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_UADDE [[OP0_0]]:_, [[OP1_0]]:_, [[IMP_DEF2]]:_
1140   CHECK: [[SADDE1:%[0-9]+]]:_(s32), [[CARRY1:%[0-9]+]]:_(s1) = G_UADDE [[OP0_1]]:_, [[OP1_1]]:_, [[CARRY0]]:_
1141   CHECK: [[SADDE2:%[0-9]+]]:_(s32), [[CARRY2:%[0-9]+]]:_(s1) = G_SADDE [[OP0_2]]:_, [[OP1_2]]:_, [[CARRY1]]:_
1142   CHECK: [[SADDE:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[SADDE0]]:_(s32), [[SADDE1]]:_(s32), [[SADDE2]]:_(s32)
1143   )";
1144 
1145   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1146 }
1147 
1148 TEST_F(AArch64GISelMITest, NarrowSSUBE) {
1149   setUp();
1150   if (!TM)
1151     return;
1152 
1153   LLT S1 = LLT::scalar(1);
1154   LLT S32 = LLT::scalar(32);
1155   LLT S96 = LLT::scalar(96);
1156   DefineLegalizerInfo(A, {
1157     getActionDefinitionsBuilder({G_SSUBE, G_USUBE})
1158         .legalFor({{LLT::scalar(32), LLT::scalar(1)}});
1159   });
1160 
1161   auto Op0 = B.buildUndef(S96);
1162   auto Op1 = B.buildUndef(S96);
1163   auto Op2 = B.buildUndef(S1);
1164   auto SSUBE = B.buildSSube(S96, S1, Op0, Op1, Op2);
1165 
1166   AInfo Info(MF->getSubtarget());
1167   DummyGISelObserver Observer;
1168   LegalizerHelper Helper(*MF, Info, Observer, B);
1169   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1170             Helper.narrowScalar(*SSUBE, 0, S32));
1171 
1172   const char *CheckStr = R"(
1173   CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
1174   CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
1175   CHECK: [[IMP_DEF2:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF
1176   CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]]
1177   CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]]
1178   CHECK: [[SSUBE0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_USUBE [[OP0_0]]:_, [[OP1_0]]:_, [[IMP_DEF2]]:_
1179   CHECK: [[SSUBE1:%[0-9]+]]:_(s32), [[CARRY1:%[0-9]+]]:_(s1) = G_USUBE [[OP0_1]]:_, [[OP1_1]]:_, [[CARRY0]]:_
1180   CHECK: [[SSUBE2:%[0-9]+]]:_(s32), [[CARRY2:%[0-9]+]]:_(s1) = G_SSUBE [[OP0_2]]:_, [[OP1_2]]:_, [[CARRY1]]:_
1181   CHECK: [[SSUBE:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[SSUBE0]]:_(s32), [[SSUBE1]]:_(s32), [[SSUBE2]]:_(s32)
1182   )";
1183 
1184   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1185 }
1186 
1187 TEST_F(AArch64GISelMITest, FewerElementsAnd) {
1188   setUp();
1189   if (!TM)
1190     return;
1191 
1192   const LLT V2S32 = LLT::vector(2, 32);
1193   const LLT V5S32 = LLT::vector(5, 32);
1194 
1195   // Declare your legalization info
1196   DefineLegalizerInfo(A, {
1197     getActionDefinitionsBuilder(G_AND)
1198       .legalFor({s32});
1199   });
1200 
1201   auto Op0 = B.buildUndef(V5S32);
1202   auto Op1 = B.buildUndef(V5S32);
1203   auto And = B.buildAnd(V5S32, Op0, Op1);
1204 
1205   AInfo Info(MF->getSubtarget());
1206   DummyGISelObserver Observer;
1207   LegalizerHelper Helper(*MF, Info, Observer, B);
1208   B.setInstr(*And);
1209   EXPECT_TRUE(Helper.fewerElementsVector(*And, 0, V2S32) ==
1210               LegalizerHelper::LegalizeResult::Legalized);
1211 
1212   auto CheckStr = R"(
1213   CHECK: [[IMP_DEF0:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF
1214   CHECK: [[IMP_DEF1:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF
1215   CHECK: [[VALUE0:%[0-9]+]]:_(s32), [[VALUE1:%[0-9]+]]:_(s32), [[VALUE2:%[0-9]+]]:_(s32), [[VALUE3:%[0-9]+]]:_(s32), [[VALUE4:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]]:_(<5 x s32>)
1216   CHECK: [[IMP_DEF2:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
1217   CHECK: [[VECTOR0:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[VALUE0]]:_(s32), [[VALUE1]]:_(s32)
1218   CHECK: [[VECTOR1:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[VALUE2]]:_(s32), [[VALUE3]]:_(s32)
1219   CHECK: [[VECTOR2:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[VALUE4]]:_(s32), [[IMP_DEF2]]:_(s32)
1220   CHECK: [[IMP_DEF3:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
1221   CHECK: [[VALUE5:%[0-9]+]]:_(s32), [[VALUE6:%[0-9]+]]:_(s32), [[VALUE7:%[0-9]+]]:_(s32), [[VALUE8:%[0-9]+]]:_(s32), [[VALUE9:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]]:_(<5 x s32>)
1222   CHECK: [[IMP_DEF4:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
1223   CHECK: [[VECTOR3:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[VALUE5]]:_(s32), [[VALUE6]]:_(s32)
1224   CHECK: [[VECTOR4:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[VALUE7]]:_(s32), [[VALUE8]]:_(s32)
1225   CHECK: [[VECTOR5:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[VALUE9]]:_(s32), [[IMP_DEF4]]:_(s32)
1226   CHECK: [[IMP_DEF5:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
1227 
1228   CHECK: [[AND0:%[0-9]+]]:_(<2 x s32>) = G_AND [[VECTOR0]]:_, [[VECTOR3]]:_
1229   CHECK: [[AND1:%[0-9]+]]:_(<2 x s32>) = G_AND [[VECTOR1]]:_, [[VECTOR4]]:_
1230   CHECK: [[AND2:%[0-9]+]]:_(<2 x s32>) = G_AND [[VECTOR2]]:_, [[VECTOR5]]:_
1231   CHECK: [[IMP_DEF6:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
1232 
1233   CHECK: [[VECTOR6:%[0-9]+]]:_(<10 x s32>) = G_CONCAT_VECTORS [[AND0]]:_(<2 x s32>), [[AND1]]:_(<2 x s32>), [[AND2]]:_(<2 x s32>), [[IMP_DEF6]]:_(<2 x s32>), [[IMP_DEF6]]:_(<2 x s32>)
1234   CHECK: [[VECTOR7:%[0-9]+]]:_(<10 x s32>) = G_CONCAT_VECTORS [[AND0]]:_(<2 x s32>), [[AND1]]:_(<2 x s32>), [[AND2]]:_(<2 x s32>), [[IMP_DEF6]]:_(<2 x s32>), [[IMP_DEF6]]:_(<2 x s32>)
1235   CHECK: [[VECTOR8:%[0-9]+]]:_(<5 x s32>), [[VECTOR9:%[0-9]+]]:_(<5 x s32>) = G_UNMERGE_VALUES [[VECTOR7]]:_(<10 x s32>)
1236   )";
1237 
1238   // Check
1239   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1240 }
1241 
1242 TEST_F(AArch64GISelMITest, MoreElementsAnd) {
1243   setUp();
1244   if (!TM)
1245     return;
1246 
1247   LLT s32 = LLT::scalar(32);
1248   LLT v2s32 = LLT::vector(2, 32);
1249   LLT v6s32 = LLT::vector(6, 32);
1250 
1251   LegalizerInfo LI;
1252   LI.getActionDefinitionsBuilder(TargetOpcode::G_AND)
1253     .legalFor({v6s32})
1254     .clampMinNumElements(0, s32, 6);
1255   LI.computeTables();
1256 
1257   DummyGISelObserver Observer;
1258   LegalizerHelper Helper(*MF, LI, Observer, B);
1259 
1260   B.setInsertPt(*EntryMBB, EntryMBB->end());
1261 
1262   auto Val0 = B.buildBitcast(v2s32, Copies[0]);
1263   auto Val1 = B.buildBitcast(v2s32, Copies[1]);
1264 
1265   auto And = B.buildAnd(v2s32, Val0, Val1);
1266 
1267   B.setInstr(*And);
1268   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1269             Helper.moreElementsVector(*And, 0, v6s32));
1270 
1271   auto CheckStr = R"(
1272   CHECK: [[BITCAST0:%[0-9]+]]:_(<2 x s32>) = G_BITCAST
1273   CHECK: [[BITCAST1:%[0-9]+]]:_(<2 x s32>) = G_BITCAST
1274   CHECK: [[IMP_DEF0:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
1275   CHECK: [[CONCAT0:%[0-9]+]]:_(<6 x s32>) = G_CONCAT_VECTORS [[BITCAST0]]:_(<2 x s32>), [[IMP_DEF0]]:_(<2 x s32>), [[IMP_DEF0]]:_(<2 x s32>)
1276   CHECK: [[IMP_DEF1:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
1277   CHECK: [[CONCAT1:%[0-9]+]]:_(<6 x s32>) = G_CONCAT_VECTORS [[BITCAST1]]:_(<2 x s32>), [[IMP_DEF1]]:_(<2 x s32>), [[IMP_DEF1]]:_(<2 x s32>)
1278   CHECK: [[AND:%[0-9]+]]:_(<6 x s32>) = G_AND [[CONCAT0]]:_, [[CONCAT1]]:_
1279   CHECK: (<2 x s32>) = G_UNMERGE_VALUES [[AND]]:_(<6 x s32>)
1280   )";
1281 
1282   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1283 }
1284 
1285 TEST_F(AArch64GISelMITest, FewerElementsPhi) {
1286   setUp();
1287   if (!TM)
1288     return;
1289 
1290   LLT s1 = LLT::scalar(1);
1291   LLT s32 = LLT::scalar(32);
1292   LLT s64 = LLT::scalar(64);
1293   LLT v2s32 = LLT::vector(2, 32);
1294   LLT v5s32 = LLT::vector(5, 32);
1295 
1296   LegalizerInfo LI;
1297   LI.getActionDefinitionsBuilder(TargetOpcode::G_PHI)
1298     .legalFor({v2s32})
1299     .clampMinNumElements(0, s32, 2);
1300   LI.computeTables();
1301 
1302   LLT PhiTy = v5s32;
1303   DummyGISelObserver Observer;
1304   LegalizerHelper Helper(*MF, LI, Observer, B);
1305   B.setMBB(*EntryMBB);
1306 
1307   MachineBasicBlock *MidMBB = MF->CreateMachineBasicBlock();
1308   MachineBasicBlock *EndMBB = MF->CreateMachineBasicBlock();
1309   MF->insert(MF->end(), MidMBB);
1310   MF->insert(MF->end(), EndMBB);
1311 
1312   EntryMBB->addSuccessor(MidMBB);
1313   EntryMBB->addSuccessor(EndMBB);
1314   MidMBB->addSuccessor(EndMBB);
1315 
1316   auto InitVal = B.buildUndef(PhiTy);
1317   auto InitOtherVal = B.buildConstant(s64, 999);
1318 
1319   auto ICmp = B.buildICmp(CmpInst::ICMP_EQ, s1, Copies[0], Copies[1]);
1320   B.buildBrCond(ICmp.getReg(0), *MidMBB);
1321   B.buildBr(*EndMBB);
1322 
1323 
1324   B.setMBB(*MidMBB);
1325   auto MidVal = B.buildUndef(PhiTy);
1326   auto MidOtherVal = B.buildConstant(s64, 345);
1327   B.buildBr(*EndMBB);
1328 
1329   B.setMBB(*EndMBB);
1330   auto Phi = B.buildInstr(TargetOpcode::G_PHI)
1331     .addDef(MRI->createGenericVirtualRegister(PhiTy))
1332     .addUse(InitVal.getReg(0))
1333     .addMBB(EntryMBB)
1334     .addUse(MidVal.getReg(0))
1335     .addMBB(MidMBB);
1336 
1337   // Insert another irrelevant phi to make sure the rebuild is inserted after
1338   // it.
1339   B.buildInstr(TargetOpcode::G_PHI)
1340     .addDef(MRI->createGenericVirtualRegister(s64))
1341     .addUse(InitOtherVal.getReg(0))
1342     .addMBB(EntryMBB)
1343     .addUse(MidOtherVal.getReg(0))
1344     .addMBB(MidMBB);
1345 
1346   // Add some use instruction after the phis.
1347   B.buildAnd(PhiTy, Phi.getReg(0), Phi.getReg(0));
1348 
1349   B.setInstr(*Phi);
1350   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1351             Helper.fewerElementsVector(*Phi, 0, v2s32));
1352 
1353   auto CheckStr = R"(
1354   CHECK: [[INITVAL:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF
1355   CHECK: [[EXTRACT0:%[0-9]+]]:_(<2 x s32>) = G_EXTRACT [[INITVAL]]:_(<5 x s32>), 0
1356   CHECK: [[EXTRACT1:%[0-9]+]]:_(<2 x s32>) = G_EXTRACT [[INITVAL]]:_(<5 x s32>), 64
1357   CHECK: [[EXTRACT2:%[0-9]+]]:_(s32) = G_EXTRACT [[INITVAL]]:_(<5 x s32>), 128
1358   CHECK: G_BRCOND
1359 
1360   CHECK: [[MIDVAL:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF
1361   CHECK: [[EXTRACT3:%[0-9]+]]:_(<2 x s32>) = G_EXTRACT [[MIDVAL]]:_(<5 x s32>), 0
1362   CHECK: [[EXTRACT4:%[0-9]+]]:_(<2 x s32>) = G_EXTRACT [[MIDVAL]]:_(<5 x s32>), 64
1363   CHECK: [[EXTRACT5:%[0-9]+]]:_(s32) = G_EXTRACT [[MIDVAL]]:_(<5 x s32>), 128
1364   CHECK: G_BR
1365 
1366   CHECK: [[PHI0:%[0-9]+]]:_(<2 x s32>) = G_PHI [[EXTRACT0]]:_(<2 x s32>), %bb.0, [[EXTRACT3]]:_(<2 x s32>), %bb.1
1367   CHECK: [[PHI1:%[0-9]+]]:_(<2 x s32>) = G_PHI [[EXTRACT1]]:_(<2 x s32>), %bb.0, [[EXTRACT4]]:_(<2 x s32>), %bb.1
1368   CHECK: [[PHI2:%[0-9]+]]:_(s32) = G_PHI [[EXTRACT2]]:_(s32), %bb.0, [[EXTRACT5]]:_(s32), %bb.1
1369 
1370   CHECK: [[OTHER_PHI:%[0-9]+]]:_(s64) = G_PHI
1371   CHECK: [[REBUILD_VAL_IMPDEF:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF
1372   CHECK: [[INSERT0:%[0-9]+]]:_(<5 x s32>) = G_INSERT [[REBUILD_VAL_IMPDEF]]:_, [[PHI0]]:_(<2 x s32>), 0
1373   CHECK: [[INSERT1:%[0-9]+]]:_(<5 x s32>) = G_INSERT [[INSERT0]]:_, [[PHI1]]:_(<2 x s32>), 64
1374   CHECK: [[INSERT2:%[0-9]+]]:_(<5 x s32>) = G_INSERT [[INSERT1]]:_, [[PHI2]]:_(s32), 128
1375   CHECK: [[USE_OP:%[0-9]+]]:_(<5 x s32>) = G_AND [[INSERT2]]:_, [[INSERT2]]:_
1376   )";
1377 
1378   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1379 }
1380 
1381 // FNEG expansion in terms of XOR
1382 TEST_F(AArch64GISelMITest, LowerFNEG) {
1383   setUp();
1384   if (!TM)
1385     return;
1386 
1387   // Declare your legalization info
1388   DefineLegalizerInfo(A, {
1389     getActionDefinitionsBuilder(G_FSUB).legalFor({s64});
1390   });
1391 
1392   // Build Instr. Make sure FMF are preserved.
1393   auto FAdd =
1394     B.buildInstr(TargetOpcode::G_FADD, {LLT::scalar(64)}, {Copies[0], Copies[1]},
1395                  MachineInstr::MIFlag::FmNsz);
1396 
1397   // Should not propagate the flags of src instruction.
1398   auto FNeg0 =
1399     B.buildInstr(TargetOpcode::G_FNEG, {LLT::scalar(64)}, {FAdd.getReg(0)},
1400                  {MachineInstr::MIFlag::FmArcp});
1401 
1402   // Preserve the one flag.
1403   auto FNeg1 =
1404     B.buildInstr(TargetOpcode::G_FNEG, {LLT::scalar(64)}, {Copies[0]},
1405                  MachineInstr::MIFlag::FmNoInfs);
1406 
1407   AInfo Info(MF->getSubtarget());
1408   DummyGISelObserver Observer;
1409   LegalizerHelper Helper(*MF, Info, Observer, B);
1410   // Perform Legalization
1411   B.setInstr(*FNeg0);
1412   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1413             Helper.lower(*FNeg0, 0, LLT::scalar(64)));
1414   B.setInstr(*FNeg1);
1415   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1416             Helper.lower(*FNeg1, 0, LLT::scalar(64)));
1417 
1418   auto CheckStr = R"(
1419   CHECK: [[FADD:%[0-9]+]]:_(s64) = nsz G_FADD %0:_, %1:_
1420   CHECK: [[CONST0:%[0-9]+]]:_(s64) = G_CONSTANT i64 -9223372036854775808
1421   CHECK: [[FSUB0:%[0-9]+]]:_(s64) = G_XOR [[FADD]]:_, [[CONST0]]:_
1422   CHECK: [[CONST1:%[0-9]+]]:_(s64) = G_CONSTANT i64 -9223372036854775808
1423   CHECK: [[FSUB1:%[0-9]+]]:_(s64) = G_XOR %0:_, [[CONST1]]:_
1424   )";
1425 
1426   // Check
1427   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1428 }
1429 
1430 TEST_F(AArch64GISelMITest, LowerMinMax) {
1431   setUp();
1432   if (!TM)
1433     return;
1434 
1435   LLT s64 = LLT::scalar(64);
1436   LLT v2s32 = LLT::vector(2, 32);
1437 
1438   DefineLegalizerInfo(A, {
1439     getActionDefinitionsBuilder({G_SMIN, G_SMAX, G_UMIN, G_UMAX})
1440       .lowerFor({s64, LLT::vector(2, s32)});
1441   });
1442 
1443   auto SMin = B.buildSMin(s64, Copies[0], Copies[1]);
1444   auto SMax = B.buildSMax(s64, Copies[0], Copies[1]);
1445   auto UMin = B.buildUMin(s64, Copies[0], Copies[1]);
1446   auto UMax = B.buildUMax(s64, Copies[0], Copies[1]);
1447 
1448   auto VecVal0 = B.buildBitcast(v2s32, Copies[0]);
1449   auto VecVal1 = B.buildBitcast(v2s32, Copies[1]);
1450 
1451   auto SMinV = B.buildSMin(v2s32, VecVal0, VecVal1);
1452   auto SMaxV = B.buildSMax(v2s32, VecVal0, VecVal1);
1453   auto UMinV = B.buildUMin(v2s32, VecVal0, VecVal1);
1454   auto UMaxV = B.buildUMax(v2s32, VecVal0, VecVal1);
1455 
1456   AInfo Info(MF->getSubtarget());
1457   DummyGISelObserver Observer;
1458   LegalizerHelper Helper(*MF, Info, Observer, B);
1459   B.setInstr(*SMin);
1460   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1461             Helper.lower(*SMin, 0, s64));
1462   B.setInstr(*SMax);
1463   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1464             Helper.lower(*SMax, 0, s64));
1465   B.setInstr(*UMin);
1466   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1467             Helper.lower(*UMin, 0, s64));
1468   B.setInstr(*UMax);
1469   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1470             Helper.lower(*UMax, 0, s64));
1471 
1472   B.setInstr(*SMinV);
1473   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1474             Helper.lower(*SMinV, 0, v2s32));
1475   B.setInstr(*SMaxV);
1476   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1477             Helper.lower(*SMaxV, 0, v2s32));
1478   B.setInstr(*UMinV);
1479   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1480             Helper.lower(*UMinV, 0, v2s32));
1481   B.setInstr(*UMaxV);
1482   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1483             Helper.lower(*UMaxV, 0, v2s32));
1484 
1485   auto CheckStr = R"(
1486   CHECK: [[CMP0:%[0-9]+]]:_(s1) = G_ICMP intpred(slt), %0:_(s64), %1:_
1487   CHECK: [[SMIN:%[0-9]+]]:_(s64) = G_SELECT [[CMP0]]:_(s1), %0:_, %1:_
1488 
1489   CHECK: [[CMP1:%[0-9]+]]:_(s1) = G_ICMP intpred(sgt), %0:_(s64), %1:_
1490   CHECK: [[SMAX:%[0-9]+]]:_(s64) = G_SELECT [[CMP1]]:_(s1), %0:_, %1:_
1491 
1492   CHECK: [[CMP2:%[0-9]+]]:_(s1) = G_ICMP intpred(ult), %0:_(s64), %1:_
1493   CHECK: [[UMIN:%[0-9]+]]:_(s64) = G_SELECT [[CMP2]]:_(s1), %0:_, %1:_
1494 
1495   CHECK: [[CMP3:%[0-9]+]]:_(s1) = G_ICMP intpred(ugt), %0:_(s64), %1:_
1496   CHECK: [[UMAX:%[0-9]+]]:_(s64) = G_SELECT [[CMP3]]:_(s1), %0:_, %1:_
1497 
1498   CHECK: [[VEC0:%[0-9]+]]:_(<2 x s32>) = G_BITCAST %0:_(s64)
1499   CHECK: [[VEC1:%[0-9]+]]:_(<2 x s32>) = G_BITCAST %1:_(s64)
1500 
1501   CHECK: [[VCMP0:%[0-9]+]]:_(<2 x s1>) = G_ICMP intpred(slt), [[VEC0]]:_(<2 x s32>), [[VEC1]]:_
1502   CHECK: [[SMINV:%[0-9]+]]:_(<2 x s32>) = G_SELECT [[VCMP0]]:_(<2 x s1>), [[VEC0]]:_, [[VEC1]]:_
1503 
1504   CHECK: [[VCMP1:%[0-9]+]]:_(<2 x s1>) = G_ICMP intpred(sgt), [[VEC0]]:_(<2 x s32>), [[VEC1]]:_
1505   CHECK: [[SMAXV:%[0-9]+]]:_(<2 x s32>) = G_SELECT [[VCMP1]]:_(<2 x s1>), [[VEC0]]:_, [[VEC1]]:_
1506 
1507   CHECK: [[VCMP2:%[0-9]+]]:_(<2 x s1>) = G_ICMP intpred(ult), [[VEC0]]:_(<2 x s32>), [[VEC1]]:_
1508   CHECK: [[UMINV:%[0-9]+]]:_(<2 x s32>) = G_SELECT [[VCMP2]]:_(<2 x s1>), [[VEC0]]:_, [[VEC1]]:_
1509 
1510   CHECK: [[VCMP3:%[0-9]+]]:_(<2 x s1>) = G_ICMP intpred(ugt), [[VEC0]]:_(<2 x s32>), [[VEC1]]:_
1511   CHECK: [[UMAXV:%[0-9]+]]:_(<2 x s32>) = G_SELECT [[VCMP3]]:_(<2 x s1>), [[VEC0]]:_, [[VEC1]]:_
1512   )";
1513 
1514   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1515 }
1516 
1517 TEST_F(AArch64GISelMITest, WidenScalarBuildVector) {
1518   setUp();
1519   if (!TM)
1520     return;
1521 
1522   LLT S32 = LLT::scalar(32);
1523   LLT S16 = LLT::scalar(16);
1524   LLT V2S16 = LLT::vector(2, S16);
1525   LLT V2S32 = LLT::vector(2, S32);
1526 
1527   DefineLegalizerInfo(A, {
1528     getActionDefinitionsBuilder({G_SMIN, G_SMAX, G_UMIN, G_UMAX})
1529       .lowerFor({s64, LLT::vector(2, s32)});
1530   });
1531 
1532   AInfo Info(MF->getSubtarget());
1533   DummyGISelObserver Observer;
1534   LegalizerHelper Helper(*MF, Info, Observer, B);
1535   B.setInsertPt(*EntryMBB, EntryMBB->end());
1536 
1537   Register Constant0 = B.buildConstant(S16, 1).getReg(0);
1538   Register Constant1 = B.buildConstant(S16, 2).getReg(0);
1539   auto BV0 = B.buildBuildVector(V2S16, {Constant0, Constant1});
1540   auto BV1 = B.buildBuildVector(V2S16, {Constant0, Constant1});
1541 
1542   B.setInstr(*BV0);
1543   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1544             Helper.widenScalar(*BV0, 0, V2S32));
1545   B.setInstr(*BV1);
1546   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1547             Helper.widenScalar(*BV1, 1, S32));
1548 
1549   auto CheckStr = R"(
1550   CHECK: [[K0:%[0-9]+]]:_(s16) = G_CONSTANT i16 1
1551   CHECK-NEXT: [[K1:%[0-9]+]]:_(s16) = G_CONSTANT i16 2
1552   CHECK-NEXT: [[EXT_K0_0:%[0-9]+]]:_(s32) = G_ANYEXT [[K0]]
1553   CHECK-NEXT: [[EXT_K1_0:%[0-9]+]]:_(s32) = G_ANYEXT [[K1]]
1554   CHECK-NEXT: [[BV0:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[EXT_K0_0]]:_(s32), [[EXT_K1_0]]:_(s32)
1555   CHECK-NEXT: [[BV0_TRUNC:%[0-9]+]]:_(<2 x s16>) = G_TRUNC [[BV0]]
1556 
1557   CHECK: [[EXT_K0_1:%[0-9]+]]:_(s32) = G_ANYEXT [[K0]]
1558   CHECK-NEXT: [[EXT_K1_1:%[0-9]+]]:_(s32) = G_ANYEXT [[K1]]
1559 
1560   CHECK-NEXT: [[BV1:%[0-9]+]]:_(<2 x s16>) = G_BUILD_VECTOR_TRUNC [[EXT_K0_1]]:_(s32), [[EXT_K1_1]]:_(s32)
1561   )";
1562 
1563   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1564 }
1565 
1566 TEST_F(AArch64GISelMITest, LowerMergeValues) {
1567   setUp();
1568   if (!TM)
1569     return;
1570 
1571   const LLT S32 = LLT::scalar(32);
1572   const LLT S24 = LLT::scalar(24);
1573   const LLT S21 = LLT::scalar(21);
1574   const LLT S16 = LLT::scalar(16);
1575   const LLT S9 = LLT::scalar(9);
1576   const LLT S8 = LLT::scalar(8);
1577   const LLT S3 = LLT::scalar(3);
1578 
1579   DefineLegalizerInfo(A, {
1580     getActionDefinitionsBuilder(G_UNMERGE_VALUES)
1581       .widenScalarIf(typeIs(1, LLT::scalar(3)), changeTo(1, LLT::scalar(9)));
1582   });
1583 
1584   AInfo Info(MF->getSubtarget());
1585   DummyGISelObserver Observer;
1586   LegalizerHelper Helper(*MF, Info, Observer, B);
1587   B.setInsertPt(*EntryMBB, EntryMBB->end());
1588 
1589   // 24 = 3 3 3   3 3 3   3 3
1590   //     => 9
1591   //
1592   // This can do 3 merges, but need an extra implicit_def.
1593   SmallVector<Register, 8> Merge0Ops;
1594   for (int I = 0; I != 8; ++I)
1595     Merge0Ops.push_back(B.buildConstant(S3, I).getReg(0));
1596 
1597   auto Merge0 = B.buildMerge(S24, Merge0Ops);
1598 
1599   // 21 = 3 3 3   3 3 3   3
1600   //     => 9, 2 extra implicit_def needed
1601   //
1602   SmallVector<Register, 8> Merge1Ops;
1603   for (int I = 0; I != 7; ++I)
1604     Merge1Ops.push_back(B.buildConstant(S3, I).getReg(0));
1605 
1606   auto Merge1 = B.buildMerge(S21, Merge1Ops);
1607 
1608   SmallVector<Register, 8> Merge2Ops;
1609   for (int I = 0; I != 2; ++I)
1610     Merge2Ops.push_back(B.buildConstant(S8, I).getReg(0));
1611 
1612   auto Merge2 = B.buildMerge(S16, Merge2Ops);
1613 
1614   B.setInstr(*Merge0);
1615   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1616             Helper.widenScalar(*Merge0, 1, S9));
1617   B.setInstr(*Merge1);
1618   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1619             Helper.widenScalar(*Merge1, 1, S9));
1620 
1621   // Request a source size greater than the original destination size.
1622   B.setInstr(*Merge2);
1623   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1624             Helper.widenScalar(*Merge2, 1, S32));
1625 
1626   auto CheckStr = R"(
1627   CHECK: [[K0:%[0-9]+]]:_(s3) = G_CONSTANT i3 0
1628   CHECK-NEXT: [[K1:%[0-9]+]]:_(s3) = G_CONSTANT i3 1
1629   CHECK-NEXT: [[K2:%[0-9]+]]:_(s3) = G_CONSTANT i3 2
1630   CHECK-NEXT: [[K3:%[0-9]+]]:_(s3) = G_CONSTANT i3 3
1631   CHECK-NEXT: [[K4:%[0-9]+]]:_(s3) = G_CONSTANT i3 -4
1632   CHECK-NEXT: [[K5:%[0-9]+]]:_(s3) = G_CONSTANT i3 -3
1633   CHECK-NEXT: [[K6:%[0-9]+]]:_(s3) = G_CONSTANT i3 -2
1634   CHECK-NEXT: [[K7:%[0-9]+]]:_(s3) = G_CONSTANT i3 -1
1635   CHECK-NEXT: [[IMPDEF0:%[0-9]+]]:_(s3) = G_IMPLICIT_DEF
1636   CHECK-NEXT: [[MERGE0:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K0]]:_(s3), [[K1]]:_(s3), [[K2]]:_(s3)
1637   CHECK-NEXT: [[MERGE1:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K3]]:_(s3), [[K4]]:_(s3), [[K5]]:_(s3)
1638   CHECK-NEXT: [[MERGE2:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K6]]:_(s3), [[K7]]:_(s3), [[IMPDEF0]]:_(s3)
1639   CHECK-NEXT: [[MERGE3:%[0-9]+]]:_(s27) = G_MERGE_VALUES [[MERGE0]]:_(s9), [[MERGE1]]:_(s9), [[MERGE2]]:_(s9)
1640   CHECK-NEXT: (s24) = G_TRUNC [[MERGE3]]:_(s27)
1641 
1642 
1643   CHECK: [[K8:%[0-9]+]]:_(s3) = G_CONSTANT i3 0
1644   CHECK-NEXT: [[K9:%[0-9]+]]:_(s3) = G_CONSTANT i3 1
1645   CHECK-NEXT: [[K10:%[0-9]+]]:_(s3) = G_CONSTANT i3 2
1646   CHECK-NEXT: [[K11:%[0-9]+]]:_(s3) = G_CONSTANT i3 3
1647   CHECK-NEXT: [[K12:%[0-9]+]]:_(s3) = G_CONSTANT i3 -4
1648   CHECK-NEXT: [[K13:%[0-9]+]]:_(s3) = G_CONSTANT i3 -3
1649   CHECK-NEXT: [[K14:%[0-9]+]]:_(s3) = G_CONSTANT i3 -2
1650   CHECK-NEXT: [[IMPDEF1:%[0-9]+]]:_(s3) = G_IMPLICIT_DEF
1651   CHECK-NEXT: [[MERGE4:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K8]]:_(s3), [[K9]]:_(s3), [[K10]]:_(s3)
1652   CHECK-NEXT: [[MERGE5:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K11]]:_(s3), [[K12]]:_(s3), [[K13]]:_(s3)
1653   CHECK-NEXT: [[MERGE6:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K14]]:_(s3), [[IMPDEF1]]:_(s3), [[IMPDEF1]]:_(s3)
1654   CHECK-NEXT: [[MERGE7:%[0-9]+]]:_(s27) = G_MERGE_VALUES [[MERGE4]]:_(s9), [[MERGE5]]:_(s9), [[MERGE6]]:_(s9)
1655   CHECK-NEXT: (s21) = G_TRUNC [[MERGE7]]:_(s27)
1656 
1657 
1658   CHECK: [[K15:%[0-9]+]]:_(s8) = G_CONSTANT i8 0
1659   CHECK-NEXT: [[K16:%[0-9]+]]:_(s8) = G_CONSTANT i8 1
1660   CHECK-NEXT: [[ZEXT_K15:[0-9]+]]:_(s32) = G_ZEXT [[K15]]:_(s8)
1661   CHECK-NEXT: [[ZEXT_K16:[0-9]+]]:_(s32) = G_ZEXT [[K16]]:_(s8)
1662   [[K16:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
1663   [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ZEXT_K16]]:_, [[K16]]:_(s32)
1664   [[OR:%[0-9]+]]:_(s32) = G_OR [[ZEXT_K16]]:_, [[SHL]]:_
1665   (s16) = G_TRUNC [[OR]]:_(s32)
1666   )";
1667 
1668   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1669 }
1670 
1671 TEST_F(AArch64GISelMITest, WidenScalarMergeValuesPointer) {
1672   setUp();
1673   if (!TM)
1674     return;
1675 
1676   DefineLegalizerInfo(A, {});
1677 
1678   AInfo Info(MF->getSubtarget());
1679   DummyGISelObserver Observer;
1680   LegalizerHelper Helper(*MF, Info, Observer, B);
1681   B.setInsertPt(*EntryMBB, EntryMBB->end());
1682 
1683   const LLT S32 = LLT::scalar(32);
1684   const LLT S64 = LLT::scalar(64);
1685   const LLT P0 = LLT::pointer(0, 64);
1686 
1687   auto Lo = B.buildTrunc(S32, Copies[0]);
1688   auto Hi = B.buildTrunc(S32, Copies[1]);
1689 
1690   auto Merge = B.buildMerge(P0, {Lo, Hi});
1691 
1692   B.setInstr(*Merge);
1693   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1694             Helper.widenScalar(*Merge, 1, S64));
1695 
1696   auto CheckStr = R"(
1697    CHECK: [[TRUNC0:%[0-9]+]]:_(s32) = G_TRUNC
1698    CHECK: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC
1699    CHECK: [[ZEXT_TRUNC0:%[0-9]+]]:_(s64) = G_ZEXT [[TRUNC0]]
1700    CHECK: [[ZEXT_TRUNC1:%[0-9]+]]:_(s64) = G_ZEXT [[TRUNC1]]
1701    CHECK: [[SHIFT_AMT:%[0-9]+]]:_(s64) = G_CONSTANT i64 32
1702    CHECK: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ZEXT_TRUNC1]]:_, [[SHIFT_AMT]]
1703    CHECK: [[OR:%[0-9]+]]:_(s64) = G_OR [[ZEXT_TRUNC0]]:_, [[SHL]]
1704    CHECK: [[INTTOPTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[OR]]:_(s64)
1705   )";
1706 
1707   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1708 }
1709 
1710 TEST_F(AArch64GISelMITest, WidenSEXTINREG) {
1711   setUp();
1712   if (!TM)
1713     return;
1714 
1715   // Declare your legalization info
1716   DefineLegalizerInfo(A, {
1717     getActionDefinitionsBuilder(G_SEXT_INREG).legalForTypeWithAnyImm({s64});
1718   });
1719   // Build Instr
1720   auto MIB = B.buildInstr(
1721       TargetOpcode::G_SEXT_INREG, {LLT::scalar(32)},
1722       {B.buildInstr(TargetOpcode::G_TRUNC, {LLT::scalar(32)}, {Copies[0]}),
1723        uint64_t(8)});
1724   AInfo Info(MF->getSubtarget());
1725   DummyGISelObserver Observer;
1726   LegalizerHelper Helper(*MF, Info, Observer, B);
1727   // Perform Legalization
1728   B.setInstr(*MIB);
1729   ASSERT_TRUE(Helper.widenScalar(*MIB, 0, LLT::scalar(64)) ==
1730               LegalizerHelper::LegalizeResult::Legalized);
1731 
1732   auto CheckStr = R"(
1733   CHECK: [[T0:%[0-9]+]]:_(s32) = G_TRUNC
1734   CHECK: [[T1:%[0-9]+]]:_(s64) = G_ANYEXT [[T0]]:_(s32)
1735   CHECK: [[T2:%[0-9]+]]:_(s64) = G_SEXT_INREG [[T1]]:_, 8
1736   CHECK: [[T3:%[0-9]+]]:_(s32) = G_TRUNC [[T2]]:_(s64)
1737   )";
1738 
1739   // Check
1740   ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1741 }
1742 
1743 TEST_F(AArch64GISelMITest, NarrowSEXTINREG) {
1744   setUp();
1745   if (!TM)
1746     return;
1747 
1748   // Declare your legalization info, these aren't actually relevant to the test.
1749   DefineLegalizerInfo(A, {
1750     getActionDefinitionsBuilder(G_SEXT_INREG).legalForTypeWithAnyImm({s64});
1751   });
1752   // Build Instr
1753   auto MIB = B.buildInstr(
1754       TargetOpcode::G_SEXT_INREG, {LLT::scalar(16)},
1755       {B.buildInstr(TargetOpcode::G_TRUNC, {LLT::scalar(16)}, {Copies[0]}),
1756        uint64_t(8)});
1757   AInfo Info(MF->getSubtarget());
1758   DummyGISelObserver Observer;
1759   LegalizerHelper Helper(*MF, Info, Observer, B);
1760   // Perform Legalization
1761   B.setInstr(*MIB);
1762   ASSERT_TRUE(Helper.narrowScalar(*MIB, 0, LLT::scalar(10)) ==
1763               LegalizerHelper::LegalizeResult::Legalized);
1764 
1765   auto CheckStr = R"(
1766   CHECK: [[T0:%[0-9]+]]:_(s16) = G_TRUNC
1767   CHECK: [[T1:%[0-9]+]]:_(s10) = G_TRUNC [[T0]]:_(s16)
1768   CHECK: [[T2:%[0-9]+]]:_(s10) = G_SEXT_INREG [[T1]]:_, 8
1769   CHECK: [[T3:%[0-9]+]]:_(s16) = G_SEXT [[T2]]:_(s10)
1770   )";
1771 
1772   // Check
1773   ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1774 }
1775 
1776 TEST_F(AArch64GISelMITest, NarrowSEXTINREG2) {
1777   setUp();
1778   if (!TM)
1779     return;
1780 
1781   // Declare your legalization info, these aren't actually relevant to the test.
1782   DefineLegalizerInfo(
1783       A, { getActionDefinitionsBuilder(G_SEXT_INREG).legalForTypeWithAnyImm({s64}); });
1784   // Build Instr
1785   auto MIB = B.buildInstr(
1786       TargetOpcode::G_SEXT_INREG, {LLT::scalar(32)},
1787       {B.buildInstr(TargetOpcode::G_TRUNC, {LLT::scalar(32)}, {Copies[0]}),
1788        uint64_t(9)});
1789   AInfo Info(MF->getSubtarget());
1790   DummyGISelObserver Observer;
1791   LegalizerHelper Helper(*MF, Info, Observer, B);
1792   // Perform Legalization
1793   B.setInstr(*MIB);
1794   ASSERT_TRUE(Helper.narrowScalar(*MIB, 0, LLT::scalar(8)) ==
1795               LegalizerHelper::LegalizeResult::Legalized);
1796 
1797   auto CheckStr = R"(
1798   CHECK: [[T0:%[0-9]+]]:_(s32) = G_TRUNC
1799   CHECK: [[T1:%[0-9]+]]:_(s8), [[T2:%[0-9]+]]:_(s8), [[T3:%[0-9]+]]:_(s8), [[T4:%[0-9]+]]:_(s8) = G_UNMERGE_VALUES [[T0]]:_(s32)
1800   CHECK: [[CST2:%[0-9]+]]:_(s8) = G_CONSTANT i8 7
1801   CHECK: [[T5:%[0-9]+]]:_(s8) = G_SEXT_INREG [[T2]]:_, 1
1802   CHECK: [[T6:%[0-9]+]]:_(s8) = G_ASHR [[T5]]:_, [[CST2]]:_
1803   CHECK: [[T7:%[0-9]+]]:_(s32) = G_MERGE_VALUES [[T1]]:_(s8), [[T5]]:_(s8), [[T6]]:_(s8), [[T6]]:_(s8)
1804   )";
1805 
1806   // Check
1807   ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
1808 }
1809 
1810 TEST_F(AArch64GISelMITest, LowerSEXTINREG) {
1811   setUp();
1812   if (!TM)
1813     return;
1814 
1815   // Declare your legalization info, these aren't actually relevant to the test.
1816   DefineLegalizerInfo(
1817       A, { getActionDefinitionsBuilder(G_SEXT_INREG).legalForTypeWithAnyImm({s64}); });
1818   // Build Instr
1819   auto MIB = B.buildInstr(
1820       TargetOpcode::G_SEXT_INREG, {LLT::scalar(32)},
1821       {B.buildInstr(TargetOpcode::G_TRUNC, {LLT::scalar(32)}, {Copies[0]}),
1822        uint64_t(8)});
1823   AInfo Info(MF->getSubtarget());
1824   DummyGISelObserver Observer;
1825   LegalizerHelper Helper(*MF, Info, Observer, B);
1826   // Perform Legalization
1827   B.setInstr(*MIB);
1828   ASSERT_TRUE(Helper.lower(*MIB, 0, LLT()) ==
1829               LegalizerHelper::LegalizeResult::Legalized);
1830 
1831   auto CheckStr = R"(
1832   CHECK: [[T1:%[0-9]+]]:_(s32) = G_TRUNC
1833   CHECK: [[CST:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
1834   CHECK: [[T2:%[0-9]+]]:_(s32) = G_SHL [[T1]]:_, [[CST]]:_
1835   CHECK: [[T3:%[0-9]+]]:_(s32) = G_ASHR [[T2]]:_, [[CST]]:_
1836   )";
1837 
1838   // Check
1839   ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
1840 }
1841 
1842 TEST_F(AArch64GISelMITest, LibcallFPExt) {
1843   setUp();
1844   if (!TM)
1845     return;
1846 
1847   // Declare your legalization info
1848   DefineLegalizerInfo(A, {
1849     getActionDefinitionsBuilder(G_FPEXT).libcallFor({{s32, s16}, {s128, s64}});
1850   });
1851 
1852   LLT S16{LLT::scalar(16)};
1853   LLT S32{LLT::scalar(32)};
1854   LLT S128{LLT::scalar(128)};
1855   auto MIBTrunc = B.buildTrunc(S16, Copies[0]);
1856   auto MIBFPExt1 =
1857       B.buildInstr(TargetOpcode::G_FPEXT, {S32}, {MIBTrunc});
1858 
1859   auto MIBFPExt2 =
1860       B.buildInstr(TargetOpcode::G_FPEXT, {S128}, {Copies[1]});
1861   AInfo Info(MF->getSubtarget());
1862   DummyGISelObserver Observer;
1863   LegalizerHelper Helper(*MF, Info, Observer, B);
1864   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1865               Helper.libcall(*MIBFPExt1));
1866 
1867   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1868               Helper.libcall(*MIBFPExt2));
1869   auto CheckStr = R"(
1870   CHECK: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC
1871   CHECK: $h0 = COPY [[TRUNC]]
1872   CHECK: BL &__gnu_h2f_ieee
1873   CHECK: $d0 = COPY
1874   CHECK: BL &__extenddftf2
1875   )";
1876 
1877   // Check
1878   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1879 }
1880 
1881 TEST_F(AArch64GISelMITest, LibcallFPTrunc) {
1882   setUp();
1883   if (!TM)
1884     return;
1885 
1886   // Declare your legalization info
1887   DefineLegalizerInfo(A, {
1888     getActionDefinitionsBuilder(G_FPTRUNC).libcallFor({{s16, s32}, {s64, s128}});
1889   });
1890 
1891   LLT S16{LLT::scalar(16)};
1892   LLT S32{LLT::scalar(32)};
1893   LLT S64{LLT::scalar(64)};
1894   LLT S128{LLT::scalar(128)};
1895   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
1896   auto MIBFPTrunc1 =
1897       B.buildInstr(TargetOpcode::G_FPTRUNC, {S16}, {MIBTrunc});
1898 
1899   auto MIBMerge = B.buildMerge(S128, {Copies[1], Copies[2]});
1900 
1901   auto MIBFPTrunc2 =
1902       B.buildInstr(TargetOpcode::G_FPTRUNC, {S64}, {MIBMerge});
1903   AInfo Info(MF->getSubtarget());
1904   DummyGISelObserver Observer;
1905   LegalizerHelper Helper(*MF, Info, Observer, B);
1906   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1907             Helper.libcall(*MIBFPTrunc1));
1908 
1909   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1910             Helper.libcall(*MIBFPTrunc2));
1911   auto CheckStr = R"(
1912   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
1913   CHECK: $s0 = COPY [[TRUNC]]
1914   CHECK: BL &__gnu_f2h_ieee
1915   CHECK: $q0 = COPY
1916   CHECK: BL &__trunctfdf2
1917   )";
1918 
1919   // Check
1920   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1921 }
1922 
1923 TEST_F(AArch64GISelMITest, LibcallSimple) {
1924   setUp();
1925   if (!TM)
1926     return;
1927 
1928   // Declare your legalization info
1929   DefineLegalizerInfo(A, {
1930     getActionDefinitionsBuilder(G_FADD).libcallFor({s16});
1931   });
1932 
1933   LLT S16{LLT::scalar(16)};
1934   auto MIBTrunc = B.buildTrunc(S16, Copies[0]);
1935   auto MIBFADD =
1936       B.buildInstr(TargetOpcode::G_FADD, {S16}, {MIBTrunc, MIBTrunc});
1937 
1938   AInfo Info(MF->getSubtarget());
1939   DummyGISelObserver Observer;
1940   LegalizerHelper Helper(*MF, Info, Observer, B);
1941   // Make sure we do not crash anymore
1942   EXPECT_EQ(LegalizerHelper::LegalizeResult::UnableToLegalize,
1943             Helper.libcall(*MIBFADD));
1944 }
1945 
1946 TEST_F(AArch64GISelMITest, LibcallSRem) {
1947   setUp();
1948   if (!TM)
1949     return;
1950 
1951   // Declare your legalization info
1952   DefineLegalizerInfo(A, {
1953     getActionDefinitionsBuilder(G_SREM).libcallFor({s32, s64, s128});
1954   });
1955 
1956   LLT S32{LLT::scalar(32)};
1957   LLT S64{LLT::scalar(64)};
1958   LLT S128{LLT::scalar(128)};
1959   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
1960   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
1961 
1962   auto MIBSRem32 =
1963       B.buildInstr(TargetOpcode::G_SREM, {S32}, {MIBTrunc, MIBTrunc});
1964   auto MIBSRem64 =
1965       B.buildInstr(TargetOpcode::G_SREM, {S64}, {Copies[0], Copies[0]});
1966   auto MIBSRem128 =
1967       B.buildInstr(TargetOpcode::G_SREM, {S128}, {MIBExt, MIBExt});
1968 
1969   AInfo Info(MF->getSubtarget());
1970   DummyGISelObserver Observer;
1971   LegalizerHelper Helper(*MF, Info, Observer, B);
1972 
1973   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1974             Helper.libcall(*MIBSRem32));
1975   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1976             Helper.libcall(*MIBSRem64));
1977   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1978             Helper.libcall(*MIBSRem128));
1979 
1980   auto CheckStr = R"(
1981   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
1982   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
1983   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
1984   CHECK: $w0 = COPY [[TRUNC]]
1985   CHECK: $w1 = COPY [[TRUNC]]
1986   CHECK: BL &__modsi3
1987   CHECK: $x0 = COPY [[COPY]]
1988   CHECK: $x1 = COPY [[COPY]]
1989   CHECK: BL &__moddi3
1990   CHECK: [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[ANYEXT]]
1991   CHECK: $x0 = COPY [[UV]]
1992   CHECK: $x1 = COPY [[UV1]]
1993   CHECK: [[UV2:%[0-9]+]]:_(s64), [[UV3:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[ANYEXT]]
1994   CHECK: $x2 = COPY [[UV2]]
1995   CHECK: $x3 = COPY [[UV3]]
1996   CHECK: BL &__modti3
1997   )";
1998 
1999   // Check
2000   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2001 }
2002 
2003 TEST_F(AArch64GISelMITest, LibcallURem) {
2004   setUp();
2005   if (!TM)
2006     return;
2007 
2008   // Declare your legalization info
2009   DefineLegalizerInfo(A, {
2010     getActionDefinitionsBuilder(G_UREM).libcallFor({s32, s64, s128});
2011   });
2012 
2013   LLT S32{LLT::scalar(32)};
2014   LLT S64{LLT::scalar(64)};
2015   LLT S128{LLT::scalar(128)};
2016   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2017   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2018 
2019   auto MIBURem32 =
2020       B.buildInstr(TargetOpcode::G_UREM, {S32}, {MIBTrunc, MIBTrunc});
2021   auto MIBURem64 =
2022       B.buildInstr(TargetOpcode::G_UREM, {S64}, {Copies[0], Copies[0]});
2023   auto MIBURem128 =
2024       B.buildInstr(TargetOpcode::G_UREM, {S128}, {MIBExt, MIBExt});
2025 
2026   AInfo Info(MF->getSubtarget());
2027   DummyGISelObserver Observer;
2028   LegalizerHelper Helper(*MF, Info, Observer, B);
2029 
2030   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2031             Helper.libcall(*MIBURem32));
2032   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2033             Helper.libcall(*MIBURem64));
2034   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2035             Helper.libcall(*MIBURem128));
2036 
2037   const auto *CheckStr = R"(
2038   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2039   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2040   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2041   CHECK: $w0 = COPY [[TRUNC]]
2042   CHECK: $w1 = COPY [[TRUNC]]
2043   CHECK: BL &__umodsi3
2044   CHECK: $x0 = COPY [[COPY]]
2045   CHECK: $x1 = COPY [[COPY]]
2046   CHECK: BL &__umoddi3
2047   CHECK: [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[ANYEXT]]
2048   CHECK: $x0 = COPY [[UV]]
2049   CHECK: $x1 = COPY [[UV1]]
2050   CHECK: [[UV2:%[0-9]+]]:_(s64), [[UV3:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[ANYEXT]]
2051   CHECK: $x2 = COPY [[UV2]]
2052   CHECK: $x3 = COPY [[UV3]]
2053   CHECK: BL &__umodti3
2054   )";
2055 
2056   // Check
2057   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2058 }
2059 
2060 TEST_F(AArch64GISelMITest, LibcallCtlzZeroUndef) {
2061   setUp();
2062   if (!TM)
2063     return;
2064 
2065   // Declare your legalization info
2066   DefineLegalizerInfo(A, {
2067     getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF)
2068         .libcallFor({{s32, s32}, {s64, s64}, {s128, s128}});
2069   });
2070 
2071   LLT S32{LLT::scalar(32)};
2072   LLT S64{LLT::scalar(64)};
2073   LLT S128{LLT::scalar(128)};
2074   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2075   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2076 
2077   auto MIBCtlz32 =
2078       B.buildInstr(TargetOpcode::G_CTLZ_ZERO_UNDEF, {S32}, {MIBTrunc});
2079   auto MIBCtlz64 =
2080       B.buildInstr(TargetOpcode::G_CTLZ_ZERO_UNDEF, {S64}, {Copies[0]});
2081   auto MIBCtlz128 =
2082       B.buildInstr(TargetOpcode::G_CTLZ_ZERO_UNDEF, {S128}, {MIBExt});
2083 
2084   AInfo Info(MF->getSubtarget());
2085   DummyGISelObserver Observer;
2086   LegalizerHelper Helper(*MF, Info, Observer, B);
2087 
2088   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2089             Helper.libcall(*MIBCtlz32));
2090   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2091             Helper.libcall(*MIBCtlz64));
2092   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2093             Helper.libcall(*MIBCtlz128));
2094 
2095   const auto *CheckStr = R"(
2096   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2097   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2098   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2099   CHECK: $w0 = COPY [[TRUNC]]
2100   CHECK: BL &__clzsi2
2101   CHECK: $x0 = COPY [[COPY]]
2102   CHECK: BL &__clzdi2
2103   CHECK: [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[ANYEXT]]
2104   CHECK: $x0 = COPY [[UV]]
2105   CHECK: $x1 = COPY [[UV1]]
2106   CHECK: BL &__clzti2
2107   )";
2108 
2109   // Check
2110   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2111 }
2112 
2113 TEST_F(AArch64GISelMITest, LibcallFAdd) {
2114   setUp();
2115   if (!TM)
2116     return;
2117 
2118   // Declare your legalization info
2119   DefineLegalizerInfo(A, {
2120     getActionDefinitionsBuilder(G_FADD).libcallFor({s32, s64, s128});
2121   });
2122 
2123   LLT S32{LLT::scalar(32)};
2124   LLT S64{LLT::scalar(64)};
2125   LLT S128{LLT::scalar(128)};
2126   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2127   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2128 
2129   auto MIBAdd32 =
2130       B.buildInstr(TargetOpcode::G_FADD, {S32}, {MIBTrunc, MIBTrunc});
2131   auto MIBAdd64 =
2132       B.buildInstr(TargetOpcode::G_FADD, {S64}, {Copies[0], Copies[0]});
2133   auto MIBAdd128 = B.buildInstr(TargetOpcode::G_FADD, {S128}, {MIBExt, MIBExt});
2134 
2135   AInfo Info(MF->getSubtarget());
2136   DummyGISelObserver Observer;
2137   LegalizerHelper Helper(*MF, Info, Observer, B);
2138 
2139   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2140             Helper.libcall(*MIBAdd32));
2141   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2142             Helper.libcall(*MIBAdd64));
2143   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2144             Helper.libcall(*MIBAdd128));
2145 
2146   const auto *CheckStr = R"(
2147   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2148   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2149   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2150   CHECK: $s0 = COPY [[TRUNC]]
2151   CHECK: $s1 = COPY [[TRUNC]]
2152   CHECK: BL &__addsf3
2153   CHECK: $d0 = COPY [[COPY]]
2154   CHECK: $d1 = COPY [[COPY]]
2155   CHECK: BL &__adddf3
2156   CHECK: $q0 = COPY [[ANYEXT]]
2157   CHECK: $q1 = COPY [[ANYEXT]]
2158   CHECK: BL &__addtf3
2159   )";
2160 
2161   // Check
2162   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2163 }
2164 
2165 TEST_F(AArch64GISelMITest, LibcallFSub) {
2166   setUp();
2167   if (!TM)
2168     return;
2169 
2170   // Declare your legalization info
2171   DefineLegalizerInfo(A, {
2172     getActionDefinitionsBuilder(G_FSUB).libcallFor({s32, s64, s128});
2173   });
2174 
2175   LLT S32{LLT::scalar(32)};
2176   LLT S64{LLT::scalar(64)};
2177   LLT S128{LLT::scalar(128)};
2178   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2179   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2180 
2181   auto MIBSub32 =
2182       B.buildInstr(TargetOpcode::G_FSUB, {S32}, {MIBTrunc, MIBTrunc});
2183   auto MIBSub64 =
2184       B.buildInstr(TargetOpcode::G_FSUB, {S64}, {Copies[0], Copies[0]});
2185   auto MIBSub128 = B.buildInstr(TargetOpcode::G_FSUB, {S128}, {MIBExt, MIBExt});
2186 
2187   AInfo Info(MF->getSubtarget());
2188   DummyGISelObserver Observer;
2189   LegalizerHelper Helper(*MF, Info, Observer, B);
2190 
2191   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2192             Helper.libcall(*MIBSub32));
2193   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2194             Helper.libcall(*MIBSub64));
2195   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2196             Helper.libcall(*MIBSub128));
2197 
2198   const auto *CheckStr = R"(
2199   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2200   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2201   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2202   CHECK: $s0 = COPY [[TRUNC]]
2203   CHECK: $s1 = COPY [[TRUNC]]
2204   CHECK: BL &__subsf3
2205   CHECK: $d0 = COPY [[COPY]]
2206   CHECK: $d1 = COPY [[COPY]]
2207   CHECK: BL &__subdf3
2208   CHECK: $q0 = COPY [[ANYEXT]]
2209   CHECK: $q1 = COPY [[ANYEXT]]
2210   CHECK: BL &__subtf3
2211   )";
2212 
2213   // Check
2214   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2215 }
2216 
2217 TEST_F(AArch64GISelMITest, LibcallFMul) {
2218   setUp();
2219   if (!TM)
2220     return;
2221 
2222   // Declare your legalization info
2223   DefineLegalizerInfo(A, {
2224     getActionDefinitionsBuilder(G_FMUL).libcallFor({s32, s64, s128});
2225   });
2226 
2227   LLT S32{LLT::scalar(32)};
2228   LLT S64{LLT::scalar(64)};
2229   LLT S128{LLT::scalar(128)};
2230   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2231   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2232 
2233   auto MIBMul32 =
2234       B.buildInstr(TargetOpcode::G_FMUL, {S32}, {MIBTrunc, MIBTrunc});
2235   auto MIBMul64 =
2236       B.buildInstr(TargetOpcode::G_FMUL, {S64}, {Copies[0], Copies[0]});
2237   auto MIBMul128 = B.buildInstr(TargetOpcode::G_FMUL, {S128}, {MIBExt, MIBExt});
2238 
2239   AInfo Info(MF->getSubtarget());
2240   DummyGISelObserver Observer;
2241   LegalizerHelper Helper(*MF, Info, Observer, B);
2242 
2243   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2244             Helper.libcall(*MIBMul32));
2245   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2246             Helper.libcall(*MIBMul64));
2247   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2248             Helper.libcall(*MIBMul128));
2249 
2250   const auto *CheckStr = R"(
2251   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2252   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2253   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2254   CHECK: $s0 = COPY [[TRUNC]]
2255   CHECK: $s1 = COPY [[TRUNC]]
2256   CHECK: BL &__mulsf3
2257   CHECK: $d0 = COPY [[COPY]]
2258   CHECK: $d1 = COPY [[COPY]]
2259   CHECK: BL &__muldf3
2260   CHECK: $q0 = COPY [[ANYEXT]]
2261   CHECK: $q1 = COPY [[ANYEXT]]
2262   CHECK: BL &__multf3
2263   )";
2264 
2265   // Check
2266   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2267 }
2268 
2269 TEST_F(AArch64GISelMITest, LibcallFDiv) {
2270   setUp();
2271   if (!TM)
2272     return;
2273 
2274   // Declare your legalization info
2275   DefineLegalizerInfo(A, {
2276     getActionDefinitionsBuilder(G_FDIV).libcallFor({s32, s64, s128});
2277   });
2278 
2279   LLT S32{LLT::scalar(32)};
2280   LLT S64{LLT::scalar(64)};
2281   LLT S128{LLT::scalar(128)};
2282   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2283   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2284 
2285   auto MIBDiv32 =
2286       B.buildInstr(TargetOpcode::G_FDIV, {S32}, {MIBTrunc, MIBTrunc});
2287   auto MIBDiv64 =
2288       B.buildInstr(TargetOpcode::G_FDIV, {S64}, {Copies[0], Copies[0]});
2289   auto MIBDiv128 = B.buildInstr(TargetOpcode::G_FDIV, {S128}, {MIBExt, MIBExt});
2290 
2291   AInfo Info(MF->getSubtarget());
2292   DummyGISelObserver Observer;
2293   LegalizerHelper Helper(*MF, Info, Observer, B);
2294 
2295   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2296             Helper.libcall(*MIBDiv32));
2297   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2298             Helper.libcall(*MIBDiv64));
2299   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2300             Helper.libcall(*MIBDiv128));
2301 
2302   const auto *CheckStr = R"(
2303   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2304   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2305   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2306   CHECK: $s0 = COPY [[TRUNC]]
2307   CHECK: $s1 = COPY [[TRUNC]]
2308   CHECK: BL &__divsf3
2309   CHECK: $d0 = COPY [[COPY]]
2310   CHECK: $d1 = COPY [[COPY]]
2311   CHECK: BL &__divdf3
2312   CHECK: $q0 = COPY [[ANYEXT]]
2313   CHECK: $q1 = COPY [[ANYEXT]]
2314   CHECK: BL &__divtf3
2315   )";
2316 
2317   // Check
2318   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2319 }
2320 
2321 TEST_F(AArch64GISelMITest, LibcallFExp) {
2322   setUp();
2323   if (!TM)
2324     return;
2325 
2326   // Declare your legalization info
2327   DefineLegalizerInfo(A, {
2328     getActionDefinitionsBuilder(G_FEXP).libcallFor({s32, s64, s128});
2329   });
2330 
2331   LLT S32{LLT::scalar(32)};
2332   LLT S64{LLT::scalar(64)};
2333   LLT S128{LLT::scalar(128)};
2334   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2335   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2336 
2337   auto MIBExp32 = B.buildInstr(TargetOpcode::G_FEXP, {S32}, {MIBTrunc});
2338   auto MIBExp64 = B.buildInstr(TargetOpcode::G_FEXP, {S64}, {Copies[0]});
2339   auto MIBExp128 = B.buildInstr(TargetOpcode::G_FEXP, {S128}, {MIBExt});
2340 
2341   AInfo Info(MF->getSubtarget());
2342   DummyGISelObserver Observer;
2343   LegalizerHelper Helper(*MF, Info, Observer, B);
2344 
2345   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2346             Helper.libcall(*MIBExp32));
2347   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2348             Helper.libcall(*MIBExp64));
2349   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2350             Helper.libcall(*MIBExp128));
2351 
2352   const auto *CheckStr = R"(
2353   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2354   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2355   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2356   CHECK: $s0 = COPY [[TRUNC]]
2357   CHECK: BL &expf
2358   CHECK: $d0 = COPY [[COPY]]
2359   CHECK: BL &exp
2360   CHECK: $q0 = COPY [[ANYEXT]]
2361   CHECK: BL &expl
2362   )";
2363 
2364   // Check
2365   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2366 }
2367 
2368 TEST_F(AArch64GISelMITest, LibcallFExp2) {
2369   setUp();
2370   if (!TM)
2371     return;
2372 
2373   // Declare your legalization info
2374   DefineLegalizerInfo(A, {
2375     getActionDefinitionsBuilder(G_FEXP2).libcallFor({s32, s64, s128});
2376   });
2377 
2378   LLT S32{LLT::scalar(32)};
2379   LLT S64{LLT::scalar(64)};
2380   LLT S128{LLT::scalar(128)};
2381   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2382   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2383 
2384   auto MIBExp232 = B.buildInstr(TargetOpcode::G_FEXP2, {S32}, {MIBTrunc});
2385   auto MIBExp264 = B.buildInstr(TargetOpcode::G_FEXP2, {S64}, {Copies[0]});
2386   auto MIBExp2128 = B.buildInstr(TargetOpcode::G_FEXP2, {S128}, {MIBExt});
2387 
2388   AInfo Info(MF->getSubtarget());
2389   DummyGISelObserver Observer;
2390   LegalizerHelper Helper(*MF, Info, Observer, B);
2391 
2392   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2393             Helper.libcall(*MIBExp232));
2394   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2395             Helper.libcall(*MIBExp264));
2396   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2397             Helper.libcall(*MIBExp2128));
2398 
2399   const auto *CheckStr = R"(
2400   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2401   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2402   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2403   CHECK: $s0 = COPY [[TRUNC]]
2404   CHECK: BL &exp2f
2405   CHECK: $d0 = COPY [[COPY]]
2406   CHECK: BL &exp2
2407   CHECK: $q0 = COPY [[ANYEXT]]
2408   CHECK: BL &exp2l
2409   )";
2410 
2411   // Check
2412   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2413 }
2414 
2415 TEST_F(AArch64GISelMITest, LibcallFRem) {
2416   setUp();
2417   if (!TM)
2418     return;
2419 
2420   // Declare your legalization info
2421   DefineLegalizerInfo(A, {
2422     getActionDefinitionsBuilder(G_FREM).libcallFor({s32, s64, s128});
2423   });
2424 
2425   LLT S32{LLT::scalar(32)};
2426   LLT S64{LLT::scalar(64)};
2427   LLT S128{LLT::scalar(128)};
2428   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2429   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2430 
2431   auto MIBFRem32 = B.buildInstr(TargetOpcode::G_FREM, {S32}, {MIBTrunc});
2432   auto MIBFRem64 = B.buildInstr(TargetOpcode::G_FREM, {S64}, {Copies[0]});
2433   auto MIBFRem128 = B.buildInstr(TargetOpcode::G_FREM, {S128}, {MIBExt});
2434 
2435   AInfo Info(MF->getSubtarget());
2436   DummyGISelObserver Observer;
2437   LegalizerHelper Helper(*MF, Info, Observer, B);
2438 
2439   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2440             Helper.libcall(*MIBFRem32));
2441   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2442             Helper.libcall(*MIBFRem64));
2443   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2444             Helper.libcall(*MIBFRem128));
2445 
2446   const auto *CheckStr = R"(
2447   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2448   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2449   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2450   CHECK: $s0 = COPY [[TRUNC]]
2451   CHECK: BL &fmodf
2452   CHECK: $d0 = COPY [[COPY]]
2453   CHECK: BL &fmod
2454   CHECK: $q0 = COPY [[ANYEXT]]
2455   CHECK: BL &fmodl
2456   )";
2457 
2458   // Check
2459   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2460 }
2461 
2462 TEST_F(AArch64GISelMITest, LibcallFPow) {
2463   setUp();
2464   if (!TM)
2465     return;
2466 
2467   // Declare your legalization info
2468   DefineLegalizerInfo(A, {
2469     getActionDefinitionsBuilder(G_FPOW).libcallFor({s32, s64, s128});
2470   });
2471 
2472   LLT S32{LLT::scalar(32)};
2473   LLT S64{LLT::scalar(64)};
2474   LLT S128{LLT::scalar(128)};
2475   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2476   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2477 
2478   auto MIBPow32 = B.buildInstr(TargetOpcode::G_FPOW, {S32}, {MIBTrunc});
2479   auto MIBPow64 = B.buildInstr(TargetOpcode::G_FPOW, {S64}, {Copies[0]});
2480   auto MIBPow128 = B.buildInstr(TargetOpcode::G_FPOW, {S128}, {MIBExt});
2481 
2482   AInfo Info(MF->getSubtarget());
2483   DummyGISelObserver Observer;
2484   LegalizerHelper Helper(*MF, Info, Observer, B);
2485 
2486   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2487             Helper.libcall(*MIBPow32));
2488   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2489             Helper.libcall(*MIBPow64));
2490   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2491             Helper.libcall(*MIBPow128));
2492 
2493   const auto *CheckStr = R"(
2494   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2495   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2496   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2497   CHECK: $s0 = COPY [[TRUNC]]
2498   CHECK: BL &powf
2499   CHECK: $d0 = COPY [[COPY]]
2500   CHECK: BL &pow
2501   CHECK: $q0 = COPY [[ANYEXT]]
2502   CHECK: BL &powl
2503   )";
2504 
2505   // Check
2506   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2507 }
2508 
2509 TEST_F(AArch64GISelMITest, LibcallFMa) {
2510   setUp();
2511   if (!TM)
2512     return;
2513 
2514   // Declare your legalization info
2515   DefineLegalizerInfo(A, {
2516     getActionDefinitionsBuilder(G_FMA).libcallFor({s32, s64, s128});
2517   });
2518 
2519   LLT S32{LLT::scalar(32)};
2520   LLT S64{LLT::scalar(64)};
2521   LLT S128{LLT::scalar(128)};
2522   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2523   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2524 
2525   auto MIBMa32 = B.buildInstr(TargetOpcode::G_FMA, {S32}, {MIBTrunc, MIBTrunc});
2526   auto MIBMa64 =
2527       B.buildInstr(TargetOpcode::G_FMA, {S64}, {Copies[0], Copies[0]});
2528   auto MIBMa128 = B.buildInstr(TargetOpcode::G_FMA, {S128}, {MIBExt, MIBExt});
2529 
2530   AInfo Info(MF->getSubtarget());
2531   DummyGISelObserver Observer;
2532   LegalizerHelper Helper(*MF, Info, Observer, B);
2533 
2534   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2535             Helper.libcall(*MIBMa32));
2536   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2537             Helper.libcall(*MIBMa64));
2538   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2539             Helper.libcall(*MIBMa128));
2540 
2541   const auto *CheckStr = R"(
2542   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2543   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2544   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2545   CHECK: $s0 = COPY [[TRUNC]]
2546   CHECK: BL &fmaf
2547   CHECK: $d0 = COPY [[COPY]]
2548   CHECK: BL &fma
2549   CHECK: $q0 = COPY [[ANYEXT]]
2550   CHECK: BL &fmal
2551   )";
2552 
2553   // Check
2554   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2555 }
2556 
2557 TEST_F(AArch64GISelMITest, LibcallFCeil) {
2558   setUp();
2559   if (!TM)
2560     return;
2561 
2562   // Declare your legalization info
2563   DefineLegalizerInfo(A, {
2564     getActionDefinitionsBuilder(G_FCEIL).libcallFor({s32, s64, s128});
2565   });
2566 
2567   LLT S32{LLT::scalar(32)};
2568   LLT S64{LLT::scalar(64)};
2569   LLT S128{LLT::scalar(128)};
2570   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2571   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2572 
2573   auto MIBCeil32 = B.buildInstr(TargetOpcode::G_FCEIL, {S32}, {MIBTrunc});
2574   auto MIBCeil64 = B.buildInstr(TargetOpcode::G_FCEIL, {S64}, {Copies[0]});
2575   auto MIBCeil128 = B.buildInstr(TargetOpcode::G_FCEIL, {S128}, {MIBExt});
2576 
2577   AInfo Info(MF->getSubtarget());
2578   DummyGISelObserver Observer;
2579   LegalizerHelper Helper(*MF, Info, Observer, B);
2580 
2581   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2582             Helper.libcall(*MIBCeil32));
2583   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2584             Helper.libcall(*MIBCeil64));
2585   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2586             Helper.libcall(*MIBCeil128));
2587 
2588   const auto *CheckStr = R"(
2589   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2590   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2591   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2592   CHECK: $s0 = COPY [[TRUNC]]
2593   CHECK: BL &ceilf
2594   CHECK: $d0 = COPY [[COPY]]
2595   CHECK: BL &ceil
2596   CHECK: $q0 = COPY [[ANYEXT]]
2597   CHECK: BL &ceill
2598   )";
2599 
2600   // Check
2601   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2602 }
2603 
2604 TEST_F(AArch64GISelMITest, LibcallFFloor) {
2605   setUp();
2606   if (!TM)
2607     return;
2608 
2609   // Declare your legalization info
2610   DefineLegalizerInfo(A, {
2611     getActionDefinitionsBuilder(G_FFLOOR).libcallFor({s32, s64, s128});
2612   });
2613 
2614   LLT S32{LLT::scalar(32)};
2615   LLT S64{LLT::scalar(64)};
2616   LLT S128{LLT::scalar(128)};
2617   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2618   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2619 
2620   auto MIBFloor32 = B.buildInstr(TargetOpcode::G_FFLOOR, {S32}, {MIBTrunc});
2621   auto MIBFloor64 = B.buildInstr(TargetOpcode::G_FFLOOR, {S64}, {Copies[0]});
2622   auto MIBFloor128 = B.buildInstr(TargetOpcode::G_FFLOOR, {S128}, {MIBExt});
2623 
2624   AInfo Info(MF->getSubtarget());
2625   DummyGISelObserver Observer;
2626   LegalizerHelper Helper(*MF, Info, Observer, B);
2627 
2628   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2629             Helper.libcall(*MIBFloor32));
2630   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2631             Helper.libcall(*MIBFloor64));
2632   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2633             Helper.libcall(*MIBFloor128));
2634 
2635   const auto *CheckStr = R"(
2636   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2637   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2638   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2639   CHECK: $s0 = COPY [[TRUNC]]
2640   CHECK: BL &floorf
2641   CHECK: $d0 = COPY [[COPY]]
2642   CHECK: BL &floor
2643   CHECK: $q0 = COPY [[ANYEXT]]
2644   CHECK: BL &floorl
2645   )";
2646 
2647   // Check
2648   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2649 }
2650 
2651 TEST_F(AArch64GISelMITest, LibcallFMinNum) {
2652   setUp();
2653   if (!TM)
2654     return;
2655 
2656   // Declare your legalization info
2657   DefineLegalizerInfo(A, {
2658     getActionDefinitionsBuilder(G_FMINNUM).libcallFor({s32, s64, s128});
2659   });
2660 
2661   LLT S32{LLT::scalar(32)};
2662   LLT S64{LLT::scalar(64)};
2663   LLT S128{LLT::scalar(128)};
2664   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2665   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2666 
2667   auto MIBMin32 = B.buildFMinNum(S32, MIBTrunc, MIBTrunc);
2668   auto MIBMin64 = B.buildFMinNum(S64, Copies[0], Copies[0]);
2669   auto MIBMin128 = B.buildFMinNum(S128, MIBExt, MIBExt);
2670 
2671   AInfo Info(MF->getSubtarget());
2672   DummyGISelObserver Observer;
2673   LegalizerHelper Helper(*MF, Info, Observer, B);
2674 
2675   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2676             Helper.libcall(*MIBMin32));
2677   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2678             Helper.libcall(*MIBMin64));
2679   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2680             Helper.libcall(*MIBMin128));
2681 
2682   const auto *CheckStr = R"(
2683   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2684   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2685   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2686   CHECK: $s0 = COPY [[TRUNC]]
2687   CHECK: $s1 = COPY [[TRUNC]]
2688   CHECK: BL &fminf
2689   CHECK: $d0 = COPY [[COPY]]
2690   CHECK: $d1 = COPY [[COPY]]
2691   CHECK: BL &fmin
2692   CHECK: $q0 = COPY [[ANYEXT]]
2693   CHECK: $q1 = COPY [[ANYEXT]]
2694   CHECK: BL &fminl
2695   )";
2696 
2697   // Check
2698   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2699 }
2700 
2701 TEST_F(AArch64GISelMITest, LibcallFMaxNum) {
2702   setUp();
2703   if (!TM)
2704     return;
2705 
2706   // Declare your legalization info
2707   DefineLegalizerInfo(A, {
2708     getActionDefinitionsBuilder(G_FMAXNUM).libcallFor({s32, s64, s128});
2709   });
2710 
2711   LLT S32{LLT::scalar(32)};
2712   LLT S64{LLT::scalar(64)};
2713   LLT S128{LLT::scalar(128)};
2714   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2715   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2716 
2717   auto MIBMax32 = B.buildFMaxNum(S32, MIBTrunc, MIBTrunc);
2718   auto MIBMax64 = B.buildFMaxNum(S64, Copies[0], Copies[0]);
2719   auto MIBMax128 = B.buildFMaxNum(S128, MIBExt, MIBExt);
2720 
2721   AInfo Info(MF->getSubtarget());
2722   DummyGISelObserver Observer;
2723   LegalizerHelper Helper(*MF, Info, Observer, B);
2724 
2725   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2726             Helper.libcall(*MIBMax32));
2727   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2728             Helper.libcall(*MIBMax64));
2729   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2730             Helper.libcall(*MIBMax128));
2731 
2732   const auto *CheckStr = R"(
2733   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2734   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2735   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2736   CHECK: $s0 = COPY [[TRUNC]]
2737   CHECK: $s1 = COPY [[TRUNC]]
2738   CHECK: BL &fmaxf
2739   CHECK: $d0 = COPY [[COPY]]
2740   CHECK: $d1 = COPY [[COPY]]
2741   CHECK: BL &fmax
2742   CHECK: $q0 = COPY [[ANYEXT]]
2743   CHECK: $q1 = COPY [[ANYEXT]]
2744   CHECK: BL &fmaxl
2745   )";
2746 
2747   // Check
2748   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2749 }
2750 
2751 TEST_F(AArch64GISelMITest, LibcallFSqrt) {
2752   setUp();
2753   if (!TM)
2754     return;
2755 
2756   // Declare your legalization info
2757   DefineLegalizerInfo(A, {
2758     getActionDefinitionsBuilder(G_FSQRT).libcallFor({s32, s64, s128});
2759   });
2760 
2761   LLT S32{LLT::scalar(32)};
2762   LLT S64{LLT::scalar(64)};
2763   LLT S128{LLT::scalar(128)};
2764   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2765   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2766 
2767   auto MIBSqrt32 = B.buildInstr(TargetOpcode::G_FSQRT, {S32}, {MIBTrunc});
2768   auto MIBSqrt64 = B.buildInstr(TargetOpcode::G_FSQRT, {S64}, {Copies[0]});
2769   auto MIBSqrt128 = B.buildInstr(TargetOpcode::G_FSQRT, {S128}, {MIBExt});
2770 
2771   AInfo Info(MF->getSubtarget());
2772   DummyGISelObserver Observer;
2773   LegalizerHelper Helper(*MF, Info, Observer, B);
2774 
2775   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2776             Helper.libcall(*MIBSqrt32));
2777   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2778             Helper.libcall(*MIBSqrt64));
2779   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2780             Helper.libcall(*MIBSqrt128));
2781 
2782   const auto *CheckStr = R"(
2783   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2784   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2785   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2786   CHECK: $s0 = COPY [[TRUNC]]
2787   CHECK: BL &sqrtf
2788   CHECK: $d0 = COPY [[COPY]]
2789   CHECK: BL &sqrt
2790   CHECK: $q0 = COPY [[ANYEXT]]
2791   CHECK: BL &sqrtl
2792   )";
2793 
2794   // Check
2795   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2796 }
2797 
2798 TEST_F(AArch64GISelMITest, LibcallFRint) {
2799   setUp();
2800   if (!TM)
2801     return;
2802 
2803   // Declare your legalization info
2804   DefineLegalizerInfo(A, {
2805     getActionDefinitionsBuilder(G_FRINT).libcallFor({s32, s64, s128});
2806   });
2807 
2808   LLT S32{LLT::scalar(32)};
2809   LLT S64{LLT::scalar(64)};
2810   LLT S128{LLT::scalar(128)};
2811   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2812   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2813 
2814   auto MIBRint32 = B.buildInstr(TargetOpcode::G_FRINT, {S32}, {MIBTrunc});
2815   auto MIBRint64 = B.buildInstr(TargetOpcode::G_FRINT, {S64}, {Copies[0]});
2816   auto MIBRint128 = B.buildInstr(TargetOpcode::G_FRINT, {S128}, {MIBExt});
2817 
2818   AInfo Info(MF->getSubtarget());
2819   DummyGISelObserver Observer;
2820   LegalizerHelper Helper(*MF, Info, Observer, B);
2821 
2822   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2823             Helper.libcall(*MIBRint32));
2824   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2825             Helper.libcall(*MIBRint64));
2826   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2827             Helper.libcall(*MIBRint128));
2828 
2829   const auto *CheckStr = R"(
2830   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2831   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2832   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2833   CHECK: $s0 = COPY [[TRUNC]]
2834   CHECK: BL &rintf
2835   CHECK: $d0 = COPY [[COPY]]
2836   CHECK: BL &rint
2837   CHECK: $q0 = COPY [[ANYEXT]]
2838   CHECK: BL &rintl
2839   )";
2840 
2841   // Check
2842   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2843 }
2844 
2845 TEST_F(AArch64GISelMITest, LibcallFNearbyInt) {
2846   setUp();
2847   if (!TM)
2848     return;
2849 
2850   // Declare your legalization info
2851   DefineLegalizerInfo(A, {
2852     getActionDefinitionsBuilder(G_FNEARBYINT).libcallFor({s32, s64, s128});
2853   });
2854 
2855   LLT S32{LLT::scalar(32)};
2856   LLT S64{LLT::scalar(64)};
2857   LLT S128{LLT::scalar(128)};
2858   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2859   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2860 
2861   auto MIBNearbyInt32 =
2862       B.buildInstr(TargetOpcode::G_FNEARBYINT, {S32}, {MIBTrunc});
2863   auto MIBNearbyInt64 =
2864       B.buildInstr(TargetOpcode::G_FNEARBYINT, {S64}, {Copies[0]});
2865   auto MIBNearbyInt128 =
2866       B.buildInstr(TargetOpcode::G_FNEARBYINT, {S128}, {MIBExt});
2867 
2868   AInfo Info(MF->getSubtarget());
2869   DummyGISelObserver Observer;
2870   LegalizerHelper Helper(*MF, Info, Observer, B);
2871 
2872   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2873             Helper.libcall(*MIBNearbyInt32));
2874   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2875             Helper.libcall(*MIBNearbyInt64));
2876   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2877             Helper.libcall(*MIBNearbyInt128));
2878 
2879   const auto *CheckStr = R"(
2880   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2881   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2882   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2883   CHECK: $s0 = COPY [[TRUNC]]
2884   CHECK: BL &nearbyintf
2885   CHECK: $d0 = COPY [[COPY]]
2886   CHECK: BL &nearbyint
2887   CHECK: $q0 = COPY [[ANYEXT]]
2888   CHECK: BL &nearbyintl
2889   )";
2890 
2891   // Check
2892   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2893 }
2894 
2895 TEST_F(AArch64GISelMITest, NarrowScalarExtract) {
2896   setUp();
2897   if (!TM)
2898     return;
2899 
2900   // Declare your legalization info
2901   DefineLegalizerInfo(A, {
2902     getActionDefinitionsBuilder(G_UNMERGE_VALUES).legalFor({{s32, s64}});
2903     getActionDefinitionsBuilder(G_EXTRACT).legalForTypeWithAnyImm({{s16, s32}});
2904   });
2905 
2906   LLT S16{LLT::scalar(16)};
2907   LLT S32{LLT::scalar(32)};
2908 
2909   auto MIBExtractS32 = B.buildExtract(S32, Copies[1], 32);
2910   auto MIBExtractS16 = B.buildExtract(S16, Copies[1], 0);
2911 
2912   AInfo Info(MF->getSubtarget());
2913   DummyGISelObserver Observer;
2914   LegalizerHelper Helper(*MF, Info, Observer, B);
2915 
2916   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2917             Helper.narrowScalar(*MIBExtractS32, 1, S32));
2918 
2919   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2920             Helper.narrowScalar(*MIBExtractS16, 1, S32));
2921 
2922   const auto *CheckStr = R"(
2923   CHECK: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES
2924   CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY [[UV1]]
2925   CHECK: [[UV3:%[0-9]+]]:_(s32), [[UV4:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES
2926   CHECK: [[EXTR:%[0-9]+]]:_(s16) = G_EXTRACT [[UV3]]:_(s32), 0
2927   CHECK: [[COPY:%[0-9]+]]:_(s16) = COPY [[EXTR]]
2928   )";
2929 
2930   // Check
2931   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2932 }
2933 
2934 TEST_F(AArch64GISelMITest, LowerInsert) {
2935   setUp();
2936   if (!TM)
2937     return;
2938 
2939   // Declare your legalization info
2940   DefineLegalizerInfo(A, { getActionDefinitionsBuilder(G_INSERT).lower(); });
2941 
2942   LLT S32{LLT::scalar(32)};
2943   LLT S64{LLT::scalar(64)};
2944   LLT P0{LLT::pointer(0, 64)};
2945   LLT P1{LLT::pointer(1, 32)};
2946   LLT V2S32{LLT::vector(2, 32)};
2947 
2948   auto TruncS32 = B.buildTrunc(S32, Copies[0]);
2949   auto IntToPtrP0 = B.buildIntToPtr(P0, Copies[0]);
2950   auto IntToPtrP1 = B.buildIntToPtr(P1, TruncS32);
2951   auto BitcastV2S32 = B.buildBitcast(V2S32, Copies[0]);
2952 
2953   auto InsertS64S32 = B.buildInsert(S64, Copies[0], TruncS32, 0);
2954   auto InsertS64P1 = B.buildInsert(S64, Copies[0], IntToPtrP1, 8);
2955   auto InsertP0S32 = B.buildInsert(P0, IntToPtrP0, TruncS32, 16);
2956   auto InsertP0P1 = B.buildInsert(P0, IntToPtrP0, IntToPtrP1, 4);
2957   auto InsertV2S32S32 = B.buildInsert(V2S32, BitcastV2S32, TruncS32, 32);
2958   auto InsertV2S32P1 = B.buildInsert(V2S32, BitcastV2S32, IntToPtrP1, 0);
2959 
2960   AInfo Info(MF->getSubtarget());
2961   DummyGISelObserver Observer;
2962   LegalizerHelper Helper(*MF, Info, Observer, B);
2963 
2964   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2965             Helper.lower(*InsertS64S32, 0, LLT{}));
2966 
2967   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2968             Helper.lower(*InsertS64P1, 0, LLT{}));
2969 
2970   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2971             Helper.lower(*InsertP0S32, 0, LLT{}));
2972 
2973   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2974             Helper.lower(*InsertP0P1, 0, LLT{}));
2975 
2976   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2977             Helper.lower(*InsertV2S32S32, 0, LLT{}));
2978 
2979   EXPECT_EQ(LegalizerHelper::LegalizeResult::UnableToLegalize,
2980             Helper.lower(*InsertV2S32P1, 0, LLT{}));
2981 
2982   const auto *CheckStr = R"(
2983   CHECK: [[S64:%[0-9]+]]:_(s64) = COPY
2984   CHECK: [[S32:%[0-9]+]]:_(s32) = G_TRUNC [[S64]]
2985   CHECK: [[P0:%[0-9]+]]:_(p0) = G_INTTOPTR [[S64]]
2986   CHECK: [[P1:%[0-9]+]]:_(p1) = G_INTTOPTR [[S32]]
2987   CHECK: [[V2S32:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[S64]]
2988   CHECK: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[S32]]
2989   CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT
2990   CHECK: [[AND:%[0-9]+]]:_(s64) = G_AND [[S64]]:_, [[C]]:_
2991   CHECK: [[OR:%[0-9]+]]:_(s64) = G_OR [[AND]]:_, [[ZEXT]]:_
2992 
2993   CHECK: [[PTRTOINT:%[0-9]+]]:_(s32) = G_PTRTOINT [[P1]]
2994   CHECK: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[PTRTOINT]]
2995   CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT
2996   CHECK: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ZEXT]]:_, [[C]]:_(s64)
2997   CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT
2998   CHECK: [[AND:%[0-9]+]]:_(s64) = G_AND [[S64]]:_, [[C]]:_
2999   CHECK: [[OR:%[0-9]+]]:_(s64) = G_OR [[AND]]:_, [[SHL]]:_
3000 
3001   CHECK: [[PTRTOINT:%[0-9]+]]:_(s64) = G_PTRTOINT [[P0]]
3002   CHECK: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[S32]]
3003   CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT
3004   CHECK: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ZEXT]]:_, [[C]]:_(s64)
3005   CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT
3006   CHECK: [[AND:%[0-9]+]]:_(s64) = G_AND [[PTRTOINT]]:_, [[C]]:_
3007   CHECK: [[OR:%[0-9]+]]:_(s64) = G_OR [[AND]]:_, [[SHL]]:_
3008   CHECK: [[INTTOPTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[OR]]
3009 
3010   CHECK: [[PTRTOINT:%[0-9]+]]:_(s64) = G_PTRTOINT [[P0]]
3011   CHECK: [[PTRTOINT1:%[0-9]+]]:_(s32) = G_PTRTOINT [[P1]]
3012   CHECK: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[PTRTOINT1]]
3013   CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT
3014   CHECK: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ZEXT]]:_, [[C]]:_(s64)
3015   CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT
3016   CHECK: [[AND:%[0-9]+]]:_(s64) = G_AND [[PTRTOINT]]:_, [[C]]:_
3017   CHECK: [[OR:%[0-9]+]]:_(s64) = G_OR [[AND]]:_, [[SHL]]:_
3018   CHECK: [[INTTOPTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[OR]]
3019 
3020   CHECK: [[BITCAST:%[0-9]+]]:_(s64) = G_BITCAST [[V2S32]]
3021   CHECK: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[S32]]
3022   CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT
3023   CHECK: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ZEXT]]:_, [[C]]:_(s64)
3024   CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT
3025   CHECK: [[AND:%[0-9]+]]:_(s64) = G_AND [[BITCAST]]:_, [[C]]:_
3026   CHECK: [[OR:%[0-9]+]]:_(s64) = G_OR [[AND]]:_, [[SHL]]:_
3027   CHECK: [[BITCAST:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[OR]]
3028   )";
3029 
3030   // Check
3031   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3032 }
3033 
3034 // Test lowering of G_FFLOOR
3035 TEST_F(AArch64GISelMITest, LowerFFloor) {
3036   setUp();
3037   if (!TM)
3038     return;
3039 
3040   // Declare your legalization info
3041   DefineLegalizerInfo(A, {});
3042   // Build Instr
3043   auto Floor = B.buildFFloor(LLT::scalar(64), Copies[0], MachineInstr::MIFlag::FmNoInfs);
3044   AInfo Info(MF->getSubtarget());
3045   DummyGISelObserver Observer;
3046   LegalizerHelper Helper(*MF, Info, Observer, B);
3047   // Perform Legalization
3048   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3049             Helper.lower(*Floor, 0, LLT()));
3050 
3051   auto CheckStr = R"(
3052   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
3053   CHECK: [[TRUNC:%[0-9]+]]:_(s64) = ninf G_INTRINSIC_TRUNC [[COPY]]
3054   CHECK: [[ZERO:%[0-9]+]]:_(s64) = G_FCONSTANT double 0.000000e+00
3055   CHECK: [[CMP0:%[0-9]+]]:_(s1) = ninf G_FCMP floatpred(olt), [[COPY]]:_(s64), [[ZERO]]:_
3056   CHECK: [[CMP1:%[0-9]+]]:_(s1) = ninf G_FCMP floatpred(one), [[COPY]]:_(s64), [[TRUNC]]:_
3057   CHECK: [[AND:%[0-9]+]]:_(s1) = G_AND [[CMP0]]:_, [[CMP1]]:_
3058   CHECK: [[ITOFP:%[0-9]+]]:_(s64) = G_SITOFP [[AND]]
3059   = ninf G_FADD [[TRUNC]]:_, [[ITOFP]]:_
3060   )";
3061 
3062   // Check
3063   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3064 }
3065 
3066 // Test lowering of G_BSWAP
3067 TEST_F(AArch64GISelMITest, LowerBSWAP) {
3068   setUp();
3069   if (!TM)
3070     return;
3071 
3072   DefineLegalizerInfo(A, {});
3073 
3074   // Make sure vector lowering doesn't assert.
3075   auto Cast = B.buildBitcast(LLT::vector(2, 32), Copies[0]);
3076   auto BSwap = B.buildBSwap(LLT::vector(2, 32), Cast);
3077   AInfo Info(MF->getSubtarget());
3078   DummyGISelObserver Observer;
3079   LegalizerHelper Helper(*MF, Info, Observer, B);
3080   // Perform Legalization
3081   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3082             Helper.lower(*BSwap, 0, LLT()));
3083 
3084   auto CheckStr = R"(
3085   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
3086   CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[COPY]]
3087   CHECK: [[K24:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
3088   CHECK: [[SPLAT24:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[K24]]:_(s32), [[K24]]:_(s32)
3089   CHECK: [[SHL0:%[0-9]+]]:_(<2 x s32>) = G_SHL [[VEC]]:_, [[SPLAT24]]
3090   CHECK: [[SHR0:%[0-9]+]]:_(<2 x s32>) = G_LSHR [[VEC]]:_, [[SPLAT24]]
3091   CHECK: [[OR0:%[0-9]+]]:_(<2 x s32>) = G_OR [[SHR0]]:_, [[SHL0]]:_
3092   CHECK: [[KMASK:%[0-9]+]]:_(s32) = G_CONSTANT i32 65280
3093   CHECK: [[SPLATMASK:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[KMASK]]:_(s32), [[KMASK]]:_(s32)
3094   CHECK: [[K8:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
3095   CHECK: [[SPLAT8:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[K8]]:_(s32), [[K8]]:_(s32)
3096   CHECK: [[AND0:%[0-9]+]]:_(<2 x s32>) = G_AND [[VEC]]:_, [[SPLATMASK]]:_
3097   CHECK: [[SHL1:%[0-9]+]]:_(<2 x s32>) = G_SHL [[AND0]]:_, [[SPLAT8]]
3098   CHECK: [[OR1:%[0-9]+]]:_(<2 x s32>) = G_OR [[OR0]]:_, [[SHL1]]:_
3099   CHECK: [[SHR1:%[0-9]+]]:_(<2 x s32>) = G_LSHR [[VEC]]:_, [[SPLAT8]]
3100   CHECK: [[AND1:%[0-9]+]]:_(<2 x s32>) = G_AND [[SHR1]]:_, [[SPLATMASK]]:_
3101   CHECK: [[BSWAP:%[0-9]+]]:_(<2 x s32>) = G_OR [[OR1]]:_, [[AND1]]:_
3102   )";
3103 
3104   // Check
3105   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3106 }
3107 
3108 // Test lowering of G_SDIVREM into G_SDIV and G_SREM
3109 TEST_F(AArch64GISelMITest, LowerSDIVREM) {
3110   setUp();
3111   if (!TM)
3112     return;
3113 
3114   // Declare your legalization info
3115   DefineLegalizerInfo(
3116       A, { getActionDefinitionsBuilder(G_SDIVREM).lowerFor({s64}); });
3117 
3118   LLT S64{LLT::scalar(64)};
3119 
3120   // Build Instr
3121   auto SDivrem =
3122       B.buildInstr(TargetOpcode::G_SDIVREM, {S64, S64}, {Copies[0], Copies[1]});
3123   AInfo Info(MF->getSubtarget());
3124   DummyGISelObserver Observer;
3125   LegalizerHelper Helper(*MF, Info, Observer, B);
3126   // Perform Legalization
3127   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3128             Helper.lower(*SDivrem, 0, S64));
3129 
3130   const auto *CheckStr = R"(
3131   CHECK: [[DIV:%[0-9]+]]:_(s64) = G_SDIV %0:_, %1:_
3132   CHECK: [[REM:%[0-9]+]]:_(s64) = G_SREM %0:_, %1:_
3133   )";
3134 
3135   // Check
3136   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3137 }
3138 
3139 // Test lowering of G_UDIVREM into G_UDIV and G_UREM
3140 TEST_F(AArch64GISelMITest, LowerUDIVREM) {
3141   setUp();
3142   if (!TM)
3143     return;
3144 
3145   // Declare your legalization info
3146   DefineLegalizerInfo(
3147       A, { getActionDefinitionsBuilder(G_UDIVREM).lowerFor({s64}); });
3148 
3149   LLT S64{LLT::scalar(64)};
3150 
3151   // Build Instr
3152   auto UDivrem =
3153       B.buildInstr(TargetOpcode::G_UDIVREM, {S64, S64}, {Copies[0], Copies[1]});
3154   AInfo Info(MF->getSubtarget());
3155   DummyGISelObserver Observer;
3156   LegalizerHelper Helper(*MF, Info, Observer, B);
3157   // Perform Legalization
3158   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3159             Helper.lower(*UDivrem, 0, S64));
3160 
3161   const auto *CheckStr = R"(
3162   CHECK: [[DIV:%[0-9]+]]:_(s64) = G_UDIV %0:_, %1:_
3163   CHECK: [[REM:%[0-9]+]]:_(s64) = G_UREM %0:_, %1:_
3164   )";
3165 
3166   // Check
3167   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3168 }
3169 
3170 // Test widening of G_UNMERGE_VALUES
3171 TEST_F(AArch64GISelMITest, WidenUnmerge) {
3172   setUp();
3173   if (!TM)
3174     return;
3175 
3176   DefineLegalizerInfo(A, {});
3177 
3178   // Check that widening G_UNMERGE_VALUES to a larger type than the source type
3179   // works as expected
3180   LLT P0{LLT::pointer(0, 64)};
3181   LLT S32{LLT::scalar(32)};
3182   LLT S96{LLT::scalar(96)};
3183 
3184   auto IntToPtr = B.buildIntToPtr(P0, Copies[0]);
3185   auto UnmergePtr = B.buildUnmerge(S32, IntToPtr);
3186   auto UnmergeScalar = B.buildUnmerge(S32, Copies[0]);
3187 
3188   AInfo Info(MF->getSubtarget());
3189   DummyGISelObserver Observer;
3190   LegalizerHelper Helper(*MF, Info, Observer, B);
3191 
3192   // Perform Legalization
3193   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3194             Helper.widenScalar(*UnmergePtr, 0, S96));
3195 
3196   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3197             Helper.widenScalar(*UnmergeScalar, 0, S96));
3198 
3199   const auto *CheckStr = R"(
3200   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
3201   CHECK: [[PTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[COPY]]
3202   CHECK: [[INT:%[0-9]+]]:_(s64) = G_PTRTOINT [[PTR]]
3203   CHECK: [[ANYEXT:%[0-9]+]]:_(s96) = G_ANYEXT [[INT]]
3204   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[ANYEXT]]
3205   CHECK: [[C:%[0-9]+]]:_(s96) = G_CONSTANT i96 32
3206   CHECK: [[LSHR:%[0-9]+]]:_(s96) = G_LSHR [[ANYEXT]]:_, [[C]]
3207   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[LSHR]]
3208   CHECK: [[ANYEXT:%[0-9]+]]:_(s96) = G_ANYEXT [[COPY]]
3209   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[ANYEXT]]
3210   CHECK: [[C:%[0-9]+]]:_(s96) = G_CONSTANT i96 32
3211   CHECK: [[LSHR:%[0-9]+]]:_(s96) = G_LSHR [[ANYEXT]]:_, [[C]]
3212   CHECK: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC [[LSHR]]
3213   )";
3214 
3215   // Check
3216   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3217 }
3218 
3219 TEST_F(AArch64GISelMITest, BitcastLoad) {
3220   setUp();
3221   if (!TM)
3222     return;
3223 
3224   LLT P0 = LLT::pointer(0, 64);
3225   LLT S32 = LLT::scalar(32);
3226   LLT V4S8 = LLT::vector(4, 8);
3227   auto Ptr = B.buildUndef(P0);
3228 
3229   DefineLegalizerInfo(A, {});
3230 
3231   MachineMemOperand *MMO = B.getMF().getMachineMemOperand(
3232       MachinePointerInfo(), MachineMemOperand::MOLoad, 4, Align(4));
3233   auto Load = B.buildLoad(V4S8, Ptr, *MMO);
3234 
3235   AInfo Info(MF->getSubtarget());
3236   DummyGISelObserver Observer;
3237   B.setInsertPt(*EntryMBB, Load->getIterator());
3238   LegalizerHelper Helper(*MF, Info, Observer, B);
3239   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3240             Helper.bitcast(*Load, 0, S32));
3241 
3242   auto CheckStr = R"(
3243   CHECK: [[PTR:%[0-9]+]]:_(p0) = G_IMPLICIT_DEF
3244   CHECK: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD
3245   CHECK: [[CAST:%[0-9]+]]:_(<4 x s8>) = G_BITCAST [[LOAD]]
3246 
3247   )";
3248 
3249   // Check
3250   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3251 }
3252 
3253 TEST_F(AArch64GISelMITest, BitcastStore) {
3254   setUp();
3255   if (!TM)
3256     return;
3257 
3258   LLT P0 = LLT::pointer(0, 64);
3259   LLT S32 = LLT::scalar(32);
3260   LLT V4S8 = LLT::vector(4, 8);
3261   auto Ptr = B.buildUndef(P0);
3262 
3263   DefineLegalizerInfo(A, {});
3264 
3265   MachineMemOperand *MMO = B.getMF().getMachineMemOperand(
3266       MachinePointerInfo(), MachineMemOperand::MOStore, 4, Align(4));
3267   auto Val = B.buildUndef(V4S8);
3268   auto Store = B.buildStore(Val, Ptr, *MMO);
3269 
3270   AInfo Info(MF->getSubtarget());
3271   DummyGISelObserver Observer;
3272   LegalizerHelper Helper(*MF, Info, Observer, B);
3273   B.setInsertPt(*EntryMBB, Store->getIterator());
3274   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3275             Helper.bitcast(*Store, 0, S32));
3276 
3277   auto CheckStr = R"(
3278   CHECK: [[VAL:%[0-9]+]]:_(<4 x s8>) = G_IMPLICIT_DEF
3279   CHECK: [[CAST:%[0-9]+]]:_(s32) = G_BITCAST [[VAL]]
3280   CHECK: G_STORE [[CAST]]
3281   )";
3282 
3283   // Check
3284   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3285 }
3286 
3287 TEST_F(AArch64GISelMITest, BitcastSelect) {
3288   setUp();
3289   if (!TM)
3290     return;
3291 
3292   LLT S1 = LLT::scalar(1);
3293   LLT S32 = LLT::scalar(32);
3294   LLT V4S8 = LLT::vector(4, 8);
3295 
3296   DefineLegalizerInfo(A, {});
3297 
3298   auto Cond = B.buildUndef(S1);
3299   auto Val0 = B.buildConstant(V4S8, 123);
3300   auto Val1 = B.buildConstant(V4S8, 99);
3301 
3302   auto Select = B.buildSelect(V4S8, Cond, Val0, Val1);
3303 
3304   AInfo Info(MF->getSubtarget());
3305   DummyGISelObserver Observer;
3306   LegalizerHelper Helper(*MF, Info, Observer, B);
3307   B.setInsertPt(*EntryMBB, Select->getIterator());
3308   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3309             Helper.bitcast(*Select, 0, S32));
3310 
3311   auto CheckStr = R"(
3312   CHECK: [[VAL0:%[0-9]+]]:_(<4 x s8>) = G_BUILD_VECTOR
3313   CHECK: [[VAL1:%[0-9]+]]:_(<4 x s8>) = G_BUILD_VECTOR
3314   CHECK: [[CAST0:%[0-9]+]]:_(s32) = G_BITCAST [[VAL0]]
3315   CHECK: [[CAST1:%[0-9]+]]:_(s32) = G_BITCAST [[VAL1]]
3316   CHECK: [[SELECT:%[0-9]+]]:_(s32) = G_SELECT %{{[0-9]+}}:_(s1), [[CAST0]]:_, [[CAST1]]:_
3317   CHECK: [[CAST2:%[0-9]+]]:_(<4 x s8>) = G_BITCAST [[SELECT]]
3318   )";
3319 
3320   // Check
3321   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3322 
3323   // Doesn't make sense
3324   auto VCond = B.buildUndef(LLT::vector(4, 1));
3325   auto VSelect = B.buildSelect(V4S8, VCond, Val0, Val1);
3326 
3327   B.setInsertPt(*EntryMBB, VSelect->getIterator());
3328   EXPECT_EQ(LegalizerHelper::LegalizeResult::UnableToLegalize,
3329             Helper.bitcast(*VSelect, 0, S32));
3330   EXPECT_EQ(LegalizerHelper::LegalizeResult::UnableToLegalize,
3331             Helper.bitcast(*VSelect, 1, LLT::scalar(4)));
3332 }
3333 
3334 TEST_F(AArch64GISelMITest, BitcastBitOps) {
3335   setUp();
3336   if (!TM)
3337     return;
3338 
3339   LLT S32 = LLT::scalar(32);
3340   LLT V4S8 = LLT::vector(4, 8);
3341 
3342   DefineLegalizerInfo(A, {});
3343 
3344   auto Val0 = B.buildConstant(V4S8, 123);
3345   auto Val1 = B.buildConstant(V4S8, 99);
3346   auto And = B.buildAnd(V4S8, Val0, Val1);
3347   auto Or = B.buildOr(V4S8, Val0, Val1);
3348   auto Xor = B.buildXor(V4S8, Val0, Val1);
3349 
3350   AInfo Info(MF->getSubtarget());
3351   DummyGISelObserver Observer;
3352   LegalizerHelper Helper(*MF, Info, Observer, B);
3353   B.setInsertPt(*EntryMBB, And->getIterator());
3354   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3355             Helper.bitcast(*And, 0, S32));
3356 
3357   B.setInsertPt(*EntryMBB, Or->getIterator());
3358   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3359             Helper.bitcast(*Or, 0, S32));
3360 
3361   B.setInsertPt(*EntryMBB, Xor->getIterator());
3362   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3363             Helper.bitcast(*Xor, 0, S32));
3364 
3365   auto CheckStr = R"(
3366   CHECK: [[VAL0:%[0-9]+]]:_(<4 x s8>) = G_BUILD_VECTOR
3367   CHECK: [[VAL1:%[0-9]+]]:_(<4 x s8>) = G_BUILD_VECTOR
3368   CHECK: [[CAST0:%[0-9]+]]:_(s32) = G_BITCAST [[VAL0]]
3369   CHECK: [[CAST1:%[0-9]+]]:_(s32) = G_BITCAST [[VAL1]]
3370   CHECK: [[AND:%[0-9]+]]:_(s32) = G_AND [[CAST0]]:_, [[CAST1]]:_
3371   CHECK: [[CAST_AND:%[0-9]+]]:_(<4 x s8>) = G_BITCAST [[AND]]
3372   CHECK: [[CAST2:%[0-9]+]]:_(s32) = G_BITCAST [[VAL0]]
3373   CHECK: [[CAST3:%[0-9]+]]:_(s32) = G_BITCAST [[VAL1]]
3374   CHECK: [[OR:%[0-9]+]]:_(s32) = G_OR [[CAST2]]:_, [[CAST3]]:_
3375   CHECK: [[CAST_OR:%[0-9]+]]:_(<4 x s8>) = G_BITCAST [[OR]]
3376   CHECK: [[CAST4:%[0-9]+]]:_(s32) = G_BITCAST [[VAL0]]
3377   CHECK: [[CAST5:%[0-9]+]]:_(s32) = G_BITCAST [[VAL1]]
3378   CHECK: [[XOR:%[0-9]+]]:_(s32) = G_XOR [[CAST4]]:_, [[CAST5]]:_
3379   CHECK: [[CAST_XOR:%[0-9]+]]:_(<4 x s8>) = G_BITCAST [[XOR]]
3380   )";
3381 
3382   // Check
3383   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3384 }
3385 
3386 TEST_F(AArch64GISelMITest, CreateLibcall) {
3387   setUp();
3388   if (!TM)
3389     return;
3390 
3391   DefineLegalizerInfo(A, {});
3392 
3393   AInfo Info(MF->getSubtarget());
3394   DummyGISelObserver Observer;
3395 
3396   LLVMContext &Ctx = MF->getFunction().getContext();
3397   auto *RetTy = Type::getVoidTy(Ctx);
3398 
3399   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3400             createLibcall(B, "abort", {{}, RetTy}, {}, CallingConv::C));
3401 
3402   auto CheckStr = R"(
3403   CHECK: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
3404   CHECK: BL &abort
3405   CHECK: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
3406   )";
3407 
3408   // Check
3409   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3410 }
3411 
3412 // Test narrowing of G_IMPLICIT_DEF
3413 TEST_F(AArch64GISelMITest, NarrowImplicitDef) {
3414   setUp();
3415   if (!TM)
3416     return;
3417 
3418   DefineLegalizerInfo(A, {});
3419 
3420   // Make sure that G_IMPLICIT_DEF can be narrowed if the original size is not a
3421   // multiple of narrow size
3422   LLT S32{LLT::scalar(32)};
3423   LLT S48{LLT::scalar(48)};
3424   LLT S64{LLT::scalar(64)};
3425   LLT V2S64{{LLT::vector(2, 64)}};
3426 
3427   auto Implicit1 = B.buildUndef(S64);
3428   auto Implicit2 = B.buildUndef(S64);
3429   auto Implicit3 = B.buildUndef(V2S64);
3430   auto Implicit4 = B.buildUndef(V2S64);
3431 
3432   AInfo Info(MF->getSubtarget());
3433   DummyGISelObserver Observer;
3434   LegalizerHelper Helper(*MF, Info, Observer, B);
3435 
3436   // Perform Legalization
3437 
3438   B.setInsertPt(*EntryMBB, Implicit1->getIterator());
3439   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3440             Helper.narrowScalar(*Implicit1, 0, S48));
3441 
3442   B.setInsertPt(*EntryMBB, Implicit2->getIterator());
3443   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3444             Helper.narrowScalar(*Implicit2, 0, S32));
3445 
3446   B.setInsertPt(*EntryMBB, Implicit3->getIterator());
3447   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3448             Helper.narrowScalar(*Implicit3, 0, S48));
3449 
3450   B.setInsertPt(*EntryMBB, Implicit4->getIterator());
3451   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3452             Helper.narrowScalar(*Implicit4, 0, S32));
3453 
3454   const auto *CheckStr = R"(
3455   CHECK: [[DEF:%[0-9]+]]:_(s48) = G_IMPLICIT_DEF
3456   CHECK: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[DEF]]
3457 
3458   CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
3459   CHECK: [[DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
3460   CHECK: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[DEF]]:_(s32), [[DEF1]]
3461 
3462   CHECK: [[DEF:%[0-9]+]]:_(<2 x s48>) = G_IMPLICIT_DEF
3463   CHECK: [[ANYEXT:%[0-9]+]]:_(<2 x s64>) = G_ANYEXT [[DEF]]
3464 
3465   CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
3466   CHECK: [[DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
3467   CHECK: [[DEF2:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
3468   CHECK: [[DEF3:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
3469   CHECK: [[BV:%[0-9]+]]:_(<2 x s64>) = G_BUILD_VECTOR [[DEF]]:_(s32), [[DEF1]]:_(s32), [[DEF2]]:_(s32), [[DEF3]]:_(s32)
3470   )";
3471 
3472   // Check
3473   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3474 }
3475 
3476 // Test widening of G_FREEZE
3477 TEST_F(AArch64GISelMITest, WidenFreeze) {
3478   setUp();
3479   if (!TM)
3480     return;
3481 
3482   DefineLegalizerInfo(A, {});
3483 
3484   // Make sure that G_FREEZE is widened with anyext
3485   LLT S64{LLT::scalar(64)};
3486   LLT S128{LLT::scalar(128)};
3487   LLT V2S32{LLT::vector(2, 32)};
3488   LLT V2S64{LLT::vector(2, 64)};
3489 
3490   auto Vector = B.buildBitcast(V2S32, Copies[0]);
3491 
3492   auto FreezeScalar = B.buildInstr(TargetOpcode::G_FREEZE, {S64}, {Copies[0]});
3493   auto FreezeVector = B.buildInstr(TargetOpcode::G_FREEZE, {V2S32}, {Vector});
3494 
3495   AInfo Info(MF->getSubtarget());
3496   DummyGISelObserver Observer;
3497   LegalizerHelper Helper(*MF, Info, Observer, B);
3498 
3499   // Perform Legalization
3500 
3501   B.setInsertPt(*EntryMBB, FreezeScalar->getIterator());
3502   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3503             Helper.widenScalar(*FreezeScalar, 0, S128));
3504 
3505   B.setInsertPt(*EntryMBB, FreezeVector->getIterator());
3506   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3507             Helper.widenScalar(*FreezeVector, 0, V2S64));
3508 
3509   const auto *CheckStr = R"(
3510   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
3511   CHECK: [[BITCAST:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[COPY]]
3512 
3513   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT [[COPY]]
3514   CHECK: [[FREEZE:%[0-9]+]]:_(s128) = G_FREEZE [[ANYEXT]]
3515   CHECK: [[TRUNC:%[0-9]+]]:_(s64) = G_TRUNC [[FREEZE]]
3516 
3517   CHECK: [[ANYEXT1:%[0-9]+]]:_(<2 x s64>) = G_ANYEXT [[BITCAST]]
3518   CHECK: [[FREEZE1:%[0-9]+]]:_(<2 x s64>) = G_FREEZE [[ANYEXT1]]
3519   CHECK: [[TRUNC1:%[0-9]+]]:_(<2 x s32>) = G_TRUNC [[FREEZE1]]
3520   )";
3521 
3522   // Check
3523   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3524 }
3525 
3526 // Test narrowing of G_FREEZE
3527 TEST_F(AArch64GISelMITest, NarrowFreeze) {
3528   setUp();
3529   if (!TM)
3530     return;
3531 
3532   DefineLegalizerInfo(A, {});
3533 
3534   // Make sure that G_FREEZE is narrowed using unmerge/extract
3535   LLT S16{LLT::scalar(16)};
3536   LLT S32{LLT::scalar(32)};
3537   LLT S33{LLT::scalar(33)};
3538   LLT S64{LLT::scalar(64)};
3539   LLT V2S16{LLT::vector(2, 16)};
3540   LLT V2S32{LLT::vector(2, 32)};
3541 
3542   auto Trunc = B.buildTrunc(S33, {Copies[0]});
3543   auto Vector = B.buildBitcast(V2S32, Copies[0]);
3544 
3545   auto FreezeScalar = B.buildInstr(TargetOpcode::G_FREEZE, {S64}, {Copies[0]});
3546   auto FreezeOdd = B.buildInstr(TargetOpcode::G_FREEZE, {S33}, {Trunc});
3547   auto FreezeVector = B.buildInstr(TargetOpcode::G_FREEZE, {V2S32}, {Vector});
3548   auto FreezeVector1 = B.buildInstr(TargetOpcode::G_FREEZE, {V2S32}, {Vector});
3549 
3550   AInfo Info(MF->getSubtarget());
3551   DummyGISelObserver Observer;
3552   LegalizerHelper Helper(*MF, Info, Observer, B);
3553 
3554   // Perform Legalization
3555 
3556   B.setInsertPt(*EntryMBB, FreezeScalar->getIterator());
3557   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3558             Helper.narrowScalar(*FreezeScalar, 0, S32));
3559 
3560   B.setInsertPt(*EntryMBB, FreezeOdd->getIterator());
3561   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3562             Helper.narrowScalar(*FreezeOdd, 0, S32));
3563 
3564   B.setInsertPt(*EntryMBB, FreezeVector->getIterator());
3565   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3566             Helper.narrowScalar(*FreezeVector, 0, V2S16));
3567 
3568   B.setInsertPt(*EntryMBB, FreezeVector1->getIterator());
3569   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3570             Helper.narrowScalar(*FreezeVector1, 0, S16));
3571 
3572   const auto *CheckStr = R"(
3573   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
3574   CHECK: [[TRUNC:%[0-9]+]]:_(s33) = G_TRUNC [[COPY]]
3575   CHECK: [[BITCAST:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[COPY]]
3576 
3577   CHECK: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[COPY]]
3578   CHECK: [[FREEZE:%[0-9]+]]:_(s32) = G_FREEZE [[UV]]
3579   CHECK: [[FREEZE1:%[0-9]+]]:_(s32) = G_FREEZE [[UV1]]
3580   CHECK: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[FREEZE]]:_(s32), [[FREEZE1]]
3581 
3582   CHECK: (s1) = G_UNMERGE_VALUES [[TRUNC]]:_(s33)
3583   CHECK: [[UNDEF:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF
3584   CHECK: [[MV1:%[0-9]+]]:_(s32) = G_MERGE_VALUES
3585   CHECK: [[MV2:%[0-9]+]]:_(s32) = G_MERGE_VALUES
3586   CHECK: [[UNDEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
3587   CHECK: [[FREEZE2:%[0-9]+]]:_(s32) = G_FREEZE [[MV1]]
3588   CHECK: [[FREEZE3:%[0-9]+]]:_(s32) = G_FREEZE [[MV2]]
3589   CHECK: [[UNDEF2:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
3590   CHECK: [[MV3:%[0-9]+]]:_(s1056) = G_MERGE_VALUES [[FREEZE2]]:_(s32), [[FREEZE3]]:_(s32), [[UNDEF2]]
3591   CHECK: [[TRUNC1:%[0-9]+]]:_(s33) = G_TRUNC [[MV3]]
3592 
3593   CHECK: [[BITCAST1:%[0-9]+]]:_(s64) = G_BITCAST [[BITCAST]]
3594   CHECK: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[BITCAST1]]
3595   CHECK: [[FREEZE4:%[0-9]+]]:_(s32) = G_FREEZE [[UV2]]
3596   CHECK: [[FREEZE5:%[0-9]+]]:_(s32) = G_FREEZE [[UV3]]
3597   CHECK: [[MV4:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[FREEZE4]]:_(s32), [[FREEZE5]]:_(s32)
3598   CHECK: [[BITCAST2:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[MV4]]
3599 
3600   CHECK: [[BITCAST3:%[0-9]+]]:_(s64) = G_BITCAST [[BITCAST]]
3601   CHECK: [[UV4:%[0-9]+]]:_(s16), [[UV5:%[0-9]+]]:_(s16), [[UV6:%[0-9]+]]:_(s16), [[UV7:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[BITCAST3]]
3602   CHECK: [[FREEZE6:%[0-9]+]]:_(s16) = G_FREEZE [[UV4]]
3603   CHECK: [[FREEZE7:%[0-9]+]]:_(s16) = G_FREEZE [[UV5]]
3604   CHECK: [[FREEZE8:%[0-9]+]]:_(s16) = G_FREEZE [[UV6]]
3605   CHECK: [[FREEZE9:%[0-9]+]]:_(s16) = G_FREEZE [[UV7]]
3606   CHECK: [[MV5:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[FREEZE6]]:_(s16), [[FREEZE7]]:_(s16), [[FREEZE8]]:_(s16), [[FREEZE9]]
3607   CHECK: [[BITCAST3:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[MV5]]
3608   )";
3609 
3610   // Check
3611   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3612 }
3613 
3614 // Test fewer elements of G_FREEZE
3615 TEST_F(AArch64GISelMITest, FewerElementsFreeze) {
3616   setUp();
3617   if (!TM)
3618     return;
3619 
3620   DefineLegalizerInfo(A, {});
3621 
3622   LLT S32{LLT::scalar(32)};
3623   LLT V2S16{LLT::vector(2, 16)};
3624   LLT V2S32{LLT::vector(2, 32)};
3625   LLT V4S16{LLT::vector(4, 16)};
3626 
3627   auto Vector1 = B.buildBitcast(V2S32, Copies[0]);
3628   auto Vector2 = B.buildBitcast(V4S16, Copies[0]);
3629 
3630   auto FreezeVector1 = B.buildInstr(TargetOpcode::G_FREEZE, {V2S32}, {Vector1});
3631   auto FreezeVector2 = B.buildInstr(TargetOpcode::G_FREEZE, {V4S16}, {Vector2});
3632 
3633   AInfo Info(MF->getSubtarget());
3634   DummyGISelObserver Observer;
3635   LegalizerHelper Helper(*MF, Info, Observer, B);
3636 
3637   // Perform Legalization
3638 
3639   B.setInsertPt(*EntryMBB, FreezeVector1->getIterator());
3640   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3641             Helper.fewerElementsVector(*FreezeVector1, 0, S32));
3642 
3643   B.setInsertPt(*EntryMBB, FreezeVector2->getIterator());
3644   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3645             Helper.fewerElementsVector(*FreezeVector2, 0, V2S16));
3646 
3647   const auto *CheckStr = R"(
3648   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
3649   CHECK: [[BITCAST:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[COPY]]
3650   CHECK: [[BITCAST1:%[0-9]+]]:_(<4 x s16>) = G_BITCAST [[COPY]]
3651 
3652   CHECK: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[BITCAST]]
3653   CHECK: [[FREEZE:%[0-9]+]]:_(s32) = G_FREEZE [[UV]]
3654   CHECK: [[FREEZE1:%[0-9]+]]:_(s32) = G_FREEZE [[UV1]]
3655   CHECK: [[MV:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[FREEZE]]:_(s32), [[FREEZE1]]
3656 
3657   CHECK: [[UV:%[0-9]+]]:_(<2 x s16>), [[UV1:%[0-9]+]]:_(<2 x s16>) = G_UNMERGE_VALUES [[BITCAST1]]
3658   CHECK: [[FREEZE2:%[0-9]+]]:_(<2 x s16>) = G_FREEZE [[UV]]
3659   CHECK: [[FREEZE3:%[0-9]+]]:_(<2 x s16>) = G_FREEZE [[UV1]]
3660   CHECK: [[MV:%[0-9]+]]:_(<4 x s16>) = G_CONCAT_VECTORS [[FREEZE2]]:_(<2 x s16>), [[FREEZE3]]
3661   )";
3662 
3663   // Check
3664   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3665 }
3666 
3667 // Test more elements of G_FREEZE
3668 TEST_F(AArch64GISelMITest, MoreElementsFreeze) {
3669   setUp();
3670   if (!TM)
3671     return;
3672 
3673   DefineLegalizerInfo(A, {});
3674 
3675   LLT V2S32{LLT::vector(2, 32)};
3676   LLT V4S32{LLT::vector(4, 32)};
3677 
3678   auto Vector1 = B.buildBitcast(V2S32, Copies[0]);
3679   auto FreezeVector1 = B.buildInstr(TargetOpcode::G_FREEZE, {V2S32}, {Vector1});
3680 
3681   AInfo Info(MF->getSubtarget());
3682   DummyGISelObserver Observer;
3683   LegalizerHelper Helper(*MF, Info, Observer, B);
3684 
3685   // Perform Legalization
3686   B.setInsertPt(*EntryMBB, FreezeVector1->getIterator());
3687   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3688             Helper.moreElementsVector(*FreezeVector1, 0, V4S32));
3689 
3690   const auto *CheckStr = R"(
3691   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
3692   CHECK: [[BITCAST:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[COPY]]
3693   CHECK: [[UNDEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
3694   CHECK: [[CV:%[0-9]+]]:_(<4 x s32>) = G_CONCAT_VECTORS [[BITCAST]]:_(<2 x s32>), [[UNDEF]]
3695   CHECK: [[FREEZE:%[0-9]+]]:_(<4 x s32>) = G_FREEZE [[CV]]
3696   CHECK: [[EXTR0:%[0-9]+]]:_(<2 x s32>), [[EXTR1:%[0-9]+]]:_(<2 x s32>) = G_UNMERGE_VALUES [[FREEZE]]:_(<4 x s32>)
3697   )";
3698 
3699   // Check
3700   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3701 }
3702 
3703 // Test fewer elements of G_INSERT_VECTOR_ELEMENT
3704 TEST_F(AArch64GISelMITest, FewerElementsInsertVectorElt) {
3705   setUp();
3706   if (!TM)
3707     return;
3708 
3709   DefineLegalizerInfo(A, {});
3710 
3711   LLT P0{LLT::pointer(0, 64)};
3712   LLT S64{LLT::scalar(64)};
3713   LLT S16{LLT::scalar(16)};
3714   LLT V2S16{LLT::vector(2, 16)};
3715   LLT V3S16{LLT::vector(3, 16)};
3716   LLT V8S16{LLT::vector(8, 16)};
3717 
3718   auto Ptr0 = B.buildIntToPtr(P0, Copies[0]);
3719   auto VectorV8 = B.buildLoad(V8S16, Ptr0, MachinePointerInfo(), Align(8));
3720   auto Value = B.buildTrunc(S16, Copies[1]);
3721 
3722   auto Seven = B.buildConstant(S64, 7);
3723   auto InsertV8Constant7_0 =
3724       B.buildInsertVectorElement(V8S16, VectorV8, Value, Seven);
3725   auto InsertV8Constant7_1 =
3726       B.buildInsertVectorElement(V8S16, VectorV8, Value, Seven);
3727 
3728   B.buildStore(InsertV8Constant7_0, Ptr0, MachinePointerInfo(), Align(8),
3729                MachineMemOperand::MOVolatile);
3730   B.buildStore(InsertV8Constant7_1, Ptr0, MachinePointerInfo(), Align(8),
3731                MachineMemOperand::MOVolatile);
3732 
3733   AInfo Info(MF->getSubtarget());
3734   DummyGISelObserver Observer;
3735   LegalizerHelper Helper(*MF, Info, Observer, B);
3736 
3737   // Perform Legalization
3738   B.setInsertPt(*EntryMBB, InsertV8Constant7_0->getIterator());
3739 
3740   // This should index the high element of the 4th piece of an unmerge.
3741   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3742             Helper.fewerElementsVector(*InsertV8Constant7_0, 0, V2S16));
3743 
3744   // This case requires extracting an intermediate vector type into the target
3745   // v4s16.
3746   B.setInsertPt(*EntryMBB, InsertV8Constant7_1->getIterator());
3747   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3748             Helper.fewerElementsVector(*InsertV8Constant7_1, 0, V3S16));
3749 
3750   const auto *CheckStr = R"(
3751   CHECK: [[COPY0:%[0-9]+]]:_(s64) = COPY
3752   CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY
3753   CHECK: [[COPY2:%[0-9]+]]:_(s64) = COPY
3754   CHECK: [[PTR0:%[0-9]+]]:_(p0) = G_INTTOPTR [[COPY0]]
3755   CHECK: [[VEC8:%[0-9]+]]:_(<8 x s16>) = G_LOAD [[PTR0]]:_(p0) :: (load 16, align 8)
3756   CHECK: [[INSERT_VAL:%[0-9]+]]:_(s16) = G_TRUNC [[COPY1]]
3757 
3758 
3759   CHECK: [[UNMERGE0:%[0-9]+]]:_(<2 x s16>), [[UNMERGE1:%[0-9]+]]:_(<2 x s16>), [[UNMERGE2:%[0-9]+]]:_(<2 x s16>), [[UNMERGE3:%[0-9]+]]:_(<2 x s16>) = G_UNMERGE_VALUES [[VEC8]]
3760   CHECK: [[ONE:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
3761   CHECK: [[SUB_INSERT_7:%[0-9]+]]:_(<2 x s16>) = G_INSERT_VECTOR_ELT [[UNMERGE3]]:_, [[INSERT_VAL]]:_(s16), [[ONE]]
3762   CHECK: [[INSERT_V8_7_0:%[0-9]+]]:_(<8 x s16>) = G_CONCAT_VECTORS [[UNMERGE0]]:_(<2 x s16>), [[UNMERGE1]]:_(<2 x s16>), [[UNMERGE2]]:_(<2 x s16>), [[SUB_INSERT_7]]:_(<2 x s16>)
3763 
3764 
3765   CHECK: [[UNMERGE1_0:%[0-9]+]]:_(s16), [[UNMERGE1_1:%[0-9]+]]:_(s16), [[UNMERGE1_2:%[0-9]+]]:_(s16), [[UNMERGE1_3:%[0-9]+]]:_(s16), [[UNMERGE1_4:%[0-9]+]]:_(s16), [[UNMERGE1_5:%[0-9]+]]:_(s16), [[UNMERGE1_6:%[0-9]+]]:_(s16), [[UNMERGE1_7:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[VEC8]]:_(<8 x s16>)
3766   CHECK: [[IMPDEF_S16:%[0-9]+]]:_(s16) = G_IMPLICIT_DEF
3767   CHECK: [[BUILD0:%[0-9]+]]:_(<3 x s16>) = G_BUILD_VECTOR [[UNMERGE1_0]]:_(s16), [[UNMERGE1_1]]:_(s16), [[UNMERGE1_2]]:_(s16)
3768   CHECK: [[BUILD1:%[0-9]+]]:_(<3 x s16>) = G_BUILD_VECTOR [[UNMERGE1_3]]:_(s16), [[UNMERGE1_4]]:_(s16), [[UNMERGE1_5]]:_(s16)
3769   CHECK: [[BUILD2:%[0-9]+]]:_(<3 x s16>) = G_BUILD_VECTOR [[UNMERGE1_6]]:_(s16), [[UNMERGE1_7]]:_(s16), [[IMPDEF_S16]]:_(s16)
3770   CHECK: [[IMPDEF_V3S16:%[0-9]+]]:_(<3 x s16>) = G_IMPLICIT_DEF
3771   CHECK: [[ONE_1:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
3772   CHECK: [[SUB_INSERT_7_V3S16:%[0-9]+]]:_(<3 x s16>) = G_INSERT_VECTOR_ELT [[BUILD2]]:_, [[INSERT_VAL]]:_(s16), [[ONE_1]]
3773 
3774   CHECK: [[WIDE_CONCAT_DEAD:%[0-9]+]]:_(<24 x s16>) = G_CONCAT_VECTORS [[BUILD0]]:_(<3 x s16>), [[BUILD1]]:_(<3 x s16>), [[SUB_INSERT_7_V3S16]]:_(<3 x s16>), [[IMPDEF_V3S16]]:_(<3 x s16>), [[IMPDEF_V3S16]]:_(<3 x s16>), [[IMPDEF_V3S16]]:_(<3 x s16>), [[IMPDEF_V3S16]]:_(<3 x s16>), [[IMPDEF_V3S16]]:_(<3 x s16>)
3775   CHECK: [[WIDE_CONCAT:%[0-9]+]]:_(<24 x s16>) = G_CONCAT_VECTORS [[BUILD0]]:_(<3 x s16>), [[BUILD1]]:_(<3 x s16>), [[SUB_INSERT_7_V3S16]]:_(<3 x s16>), [[IMPDEF_V3S16]]:_(<3 x s16>), [[IMPDEF_V3S16]]:_(<3 x s16>), [[IMPDEF_V3S16]]:_(<3 x s16>), [[IMPDEF_V3S16]]:_(<3 x s16>), [[IMPDEF_V3S16]]:_(<3 x s16>)
3776   CHECK: [[INSERT_V8_7_1:%[0-9]+]]:_(<8 x s16>), %{{[0-9]+}}:_(<8 x s16>), %{{[0-9]+}}:_(<8 x s16>) = G_UNMERGE_VALUES [[WIDE_CONCAT]]:_(<24 x s16>)
3777 
3778 
3779   CHECK: G_STORE [[INSERT_V8_7_0]]
3780   CHECK: G_STORE [[INSERT_V8_7_1]]
3781   )";
3782 
3783   // Check
3784   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3785 }
3786 
3787 // Test widen scalar of G_UNMERGE_VALUES
3788 TEST_F(AArch64GISelMITest, widenScalarUnmerge) {
3789   setUp();
3790   if (!TM)
3791     return;
3792 
3793   DefineLegalizerInfo(A, {});
3794 
3795   LLT S96{LLT::scalar(96)};
3796   LLT S64{LLT::scalar(64)};
3797   LLT S48{LLT::scalar(48)};
3798 
3799   auto Src = B.buildAnyExt(S96, Copies[0]);
3800   auto Unmerge = B.buildUnmerge(S48, Src);
3801 
3802   AInfo Info(MF->getSubtarget());
3803   DummyGISelObserver Observer;
3804   LegalizerHelper Helper(*MF, Info, Observer, B);
3805 
3806   // Perform Legalization
3807   B.setInsertPt(*EntryMBB, Unmerge->getIterator());
3808 
3809   // This should create unmerges to a GCD type (S16), then remerge to S48
3810   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3811             Helper.widenScalar(*Unmerge, 0, S64));
3812 
3813   const auto *CheckStr = R"(
3814   CHECK: [[COPY0:%[0-9]+]]:_(s64) = COPY
3815   CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY
3816   CHECK: [[COPY2:%[0-9]+]]:_(s64) = COPY
3817   CHECK: [[ANYEXT:%[0-9]+]]:_(s96) = G_ANYEXT [[COPY0]]
3818   CHECK: [[ANYEXT1:%[0-9]+]]:_(s192) = G_ANYEXT [[ANYEXT]]
3819   CHECK: [[UNMERGE:%[0-9]+]]:_(s64), [[UNMERGE1:%[0-9]+]]:_(s64), [[UNMERGE2:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[ANYEXT1]]
3820   CHECK: [[UNMERGE3:%[0-9]+]]:_(s16), [[UNMERGE4:%[0-9]+]]:_(s16), [[UNMERGE5:%[0-9]+]]:_(s16), [[UNMERGE6:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[UNMERGE]]
3821   CHECK: [[UNMERGE7:%[0-9]+]]:_(s16), [[UNMERGE8:%[0-9]+]]:_(s16), [[UNMERGE9:%[0-9]+]]:_(s16), [[UNMERGE10:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[UNMERGE1]]
3822   CHECK: [[UNMERGE11:%[0-9]+]]:_(s16), [[UNMERGE12:%[0-9]+]]:_(s16), [[UNMERGE13:%[0-9]+]]:_(s16), [[UNMERGE14:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[UNMERGE2]]
3823   CHECK: [[MERGE:%[0-9]+]]:_(s48) = G_MERGE_VALUES [[UNMERGE3]]:_(s16), [[UNMERGE4]]:_(s16), [[UNMERGE5]]:_(s16)
3824   CHECK: [[MERGE1:%[0-9]+]]:_(s48) = G_MERGE_VALUES [[UNMERGE6]]:_(s16), [[UNMERGE7]]:_(s16), [[UNMERGE8]]:_(s16)
3825   )";
3826 
3827   // Check
3828   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3829 }
3830 
3831 } // namespace
3832