xref: /llvm-project/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp (revision 98754e290908259f8d8eb3278e2021a7fbb9d37b)
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, FewerElementsAnd) {
884   setUp();
885   if (!TM)
886     return;
887 
888   const LLT V2S32 = LLT::vector(2, 32);
889   const LLT V5S32 = LLT::vector(5, 32);
890 
891   // Declare your legalization info
892   DefineLegalizerInfo(A, {
893     getActionDefinitionsBuilder(G_AND)
894       .legalFor({s32});
895   });
896 
897   auto Op0 = B.buildUndef(V5S32);
898   auto Op1 = B.buildUndef(V5S32);
899   auto And = B.buildAnd(V5S32, Op0, Op1);
900 
901   AInfo Info(MF->getSubtarget());
902   DummyGISelObserver Observer;
903   LegalizerHelper Helper(*MF, Info, Observer, B);
904   B.setInstr(*And);
905   EXPECT_TRUE(Helper.fewerElementsVector(*And, 0, V2S32) ==
906               LegalizerHelper::LegalizeResult::Legalized);
907 
908   auto CheckStr = R"(
909   CHECK: [[IMP_DEF0:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF
910   CHECK: [[IMP_DEF1:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF
911   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>)
912   CHECK: [[IMP_DEF2:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
913   CHECK: [[VECTOR0:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[VALUE0]]:_(s32), [[VALUE1]]:_(s32)
914   CHECK: [[VECTOR1:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[VALUE2]]:_(s32), [[VALUE3]]:_(s32)
915   CHECK: [[VECTOR2:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[VALUE4]]:_(s32), [[IMP_DEF2]]:_(s32)
916   CHECK: [[IMP_DEF3:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
917   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>)
918   CHECK: [[IMP_DEF4:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
919   CHECK: [[VECTOR3:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[VALUE5]]:_(s32), [[VALUE6]]:_(s32)
920   CHECK: [[VECTOR4:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[VALUE7]]:_(s32), [[VALUE8]]:_(s32)
921   CHECK: [[VECTOR5:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[VALUE9]]:_(s32), [[IMP_DEF4]]:_(s32)
922   CHECK: [[IMP_DEF5:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
923 
924   CHECK: [[AND0:%[0-9]+]]:_(<2 x s32>) = G_AND [[VECTOR0]]:_, [[VECTOR3]]:_
925   CHECK: [[AND1:%[0-9]+]]:_(<2 x s32>) = G_AND [[VECTOR1]]:_, [[VECTOR4]]:_
926   CHECK: [[AND2:%[0-9]+]]:_(<2 x s32>) = G_AND [[VECTOR2]]:_, [[VECTOR5]]:_
927   CHECK: [[IMP_DEF6:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
928 
929   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>)
930   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>)
931   CHECK: [[VECTOR8:%[0-9]+]]:_(<5 x s32>), [[VECTOR9:%[0-9]+]]:_(<5 x s32>) = G_UNMERGE_VALUES [[VECTOR7]]:_(<10 x s32>)
932   )";
933 
934   // Check
935   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
936 }
937 
938 TEST_F(AArch64GISelMITest, MoreElementsAnd) {
939   setUp();
940   if (!TM)
941     return;
942 
943   LLT s32 = LLT::scalar(32);
944   LLT v2s32 = LLT::vector(2, 32);
945   LLT v6s32 = LLT::vector(6, 32);
946 
947   LegalizerInfo LI;
948   LI.getActionDefinitionsBuilder(TargetOpcode::G_AND)
949     .legalFor({v6s32})
950     .clampMinNumElements(0, s32, 6);
951   LI.computeTables();
952 
953   DummyGISelObserver Observer;
954   LegalizerHelper Helper(*MF, LI, Observer, B);
955 
956   B.setInsertPt(*EntryMBB, EntryMBB->end());
957 
958   auto Val0 = B.buildBitcast(v2s32, Copies[0]);
959   auto Val1 = B.buildBitcast(v2s32, Copies[1]);
960 
961   auto And = B.buildAnd(v2s32, Val0, Val1);
962 
963   B.setInstr(*And);
964   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
965             Helper.moreElementsVector(*And, 0, v6s32));
966 
967   auto CheckStr = R"(
968   CHECK: [[BITCAST0:%[0-9]+]]:_(<2 x s32>) = G_BITCAST
969   CHECK: [[BITCAST1:%[0-9]+]]:_(<2 x s32>) = G_BITCAST
970   CHECK: [[IMP_DEF0:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
971   CHECK: [[CONCAT0:%[0-9]+]]:_(<6 x s32>) = G_CONCAT_VECTORS [[BITCAST0]]:_(<2 x s32>), [[IMP_DEF0]]:_(<2 x s32>), [[IMP_DEF0]]:_(<2 x s32>)
972   CHECK: [[IMP_DEF1:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
973   CHECK: [[CONCAT1:%[0-9]+]]:_(<6 x s32>) = G_CONCAT_VECTORS [[BITCAST1]]:_(<2 x s32>), [[IMP_DEF1]]:_(<2 x s32>), [[IMP_DEF1]]:_(<2 x s32>)
974   CHECK: [[AND:%[0-9]+]]:_(<6 x s32>) = G_AND [[CONCAT0]]:_, [[CONCAT1]]:_
975   CHECK: (<2 x s32>) = G_UNMERGE_VALUES [[AND]]:_(<6 x s32>)
976   )";
977 
978   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
979 }
980 
981 TEST_F(AArch64GISelMITest, FewerElementsPhi) {
982   setUp();
983   if (!TM)
984     return;
985 
986   LLT s1 = LLT::scalar(1);
987   LLT s32 = LLT::scalar(32);
988   LLT s64 = LLT::scalar(64);
989   LLT v2s32 = LLT::vector(2, 32);
990   LLT v5s32 = LLT::vector(5, 32);
991 
992   LegalizerInfo LI;
993   LI.getActionDefinitionsBuilder(TargetOpcode::G_PHI)
994     .legalFor({v2s32})
995     .clampMinNumElements(0, s32, 2);
996   LI.computeTables();
997 
998   LLT PhiTy = v5s32;
999   DummyGISelObserver Observer;
1000   LegalizerHelper Helper(*MF, LI, Observer, B);
1001   B.setMBB(*EntryMBB);
1002 
1003   MachineBasicBlock *MidMBB = MF->CreateMachineBasicBlock();
1004   MachineBasicBlock *EndMBB = MF->CreateMachineBasicBlock();
1005   MF->insert(MF->end(), MidMBB);
1006   MF->insert(MF->end(), EndMBB);
1007 
1008   EntryMBB->addSuccessor(MidMBB);
1009   EntryMBB->addSuccessor(EndMBB);
1010   MidMBB->addSuccessor(EndMBB);
1011 
1012   auto InitVal = B.buildUndef(PhiTy);
1013   auto InitOtherVal = B.buildConstant(s64, 999);
1014 
1015   auto ICmp = B.buildICmp(CmpInst::ICMP_EQ, s1, Copies[0], Copies[1]);
1016   B.buildBrCond(ICmp.getReg(0), *MidMBB);
1017   B.buildBr(*EndMBB);
1018 
1019 
1020   B.setMBB(*MidMBB);
1021   auto MidVal = B.buildUndef(PhiTy);
1022   auto MidOtherVal = B.buildConstant(s64, 345);
1023   B.buildBr(*EndMBB);
1024 
1025   B.setMBB(*EndMBB);
1026   auto Phi = B.buildInstr(TargetOpcode::G_PHI)
1027     .addDef(MRI->createGenericVirtualRegister(PhiTy))
1028     .addUse(InitVal.getReg(0))
1029     .addMBB(EntryMBB)
1030     .addUse(MidVal.getReg(0))
1031     .addMBB(MidMBB);
1032 
1033   // Insert another irrelevant phi to make sure the rebuild is inserted after
1034   // it.
1035   B.buildInstr(TargetOpcode::G_PHI)
1036     .addDef(MRI->createGenericVirtualRegister(s64))
1037     .addUse(InitOtherVal.getReg(0))
1038     .addMBB(EntryMBB)
1039     .addUse(MidOtherVal.getReg(0))
1040     .addMBB(MidMBB);
1041 
1042   // Add some use instruction after the phis.
1043   B.buildAnd(PhiTy, Phi.getReg(0), Phi.getReg(0));
1044 
1045   B.setInstr(*Phi);
1046   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1047             Helper.fewerElementsVector(*Phi, 0, v2s32));
1048 
1049   auto CheckStr = R"(
1050   CHECK: [[INITVAL:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF
1051   CHECK: [[EXTRACT0:%[0-9]+]]:_(<2 x s32>) = G_EXTRACT [[INITVAL]]:_(<5 x s32>), 0
1052   CHECK: [[EXTRACT1:%[0-9]+]]:_(<2 x s32>) = G_EXTRACT [[INITVAL]]:_(<5 x s32>), 64
1053   CHECK: [[EXTRACT2:%[0-9]+]]:_(s32) = G_EXTRACT [[INITVAL]]:_(<5 x s32>), 128
1054   CHECK: G_BRCOND
1055 
1056   CHECK: [[MIDVAL:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF
1057   CHECK: [[EXTRACT3:%[0-9]+]]:_(<2 x s32>) = G_EXTRACT [[MIDVAL]]:_(<5 x s32>), 0
1058   CHECK: [[EXTRACT4:%[0-9]+]]:_(<2 x s32>) = G_EXTRACT [[MIDVAL]]:_(<5 x s32>), 64
1059   CHECK: [[EXTRACT5:%[0-9]+]]:_(s32) = G_EXTRACT [[MIDVAL]]:_(<5 x s32>), 128
1060   CHECK: G_BR
1061 
1062   CHECK: [[PHI0:%[0-9]+]]:_(<2 x s32>) = G_PHI [[EXTRACT0]]:_(<2 x s32>), %bb.0, [[EXTRACT3]]:_(<2 x s32>), %bb.1
1063   CHECK: [[PHI1:%[0-9]+]]:_(<2 x s32>) = G_PHI [[EXTRACT1]]:_(<2 x s32>), %bb.0, [[EXTRACT4]]:_(<2 x s32>), %bb.1
1064   CHECK: [[PHI2:%[0-9]+]]:_(s32) = G_PHI [[EXTRACT2]]:_(s32), %bb.0, [[EXTRACT5]]:_(s32), %bb.1
1065 
1066   CHECK: [[OTHER_PHI:%[0-9]+]]:_(s64) = G_PHI
1067   CHECK: [[REBUILD_VAL_IMPDEF:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF
1068   CHECK: [[INSERT0:%[0-9]+]]:_(<5 x s32>) = G_INSERT [[REBUILD_VAL_IMPDEF]]:_, [[PHI0]]:_(<2 x s32>), 0
1069   CHECK: [[INSERT1:%[0-9]+]]:_(<5 x s32>) = G_INSERT [[INSERT0]]:_, [[PHI1]]:_(<2 x s32>), 64
1070   CHECK: [[INSERT2:%[0-9]+]]:_(<5 x s32>) = G_INSERT [[INSERT1]]:_, [[PHI2]]:_(s32), 128
1071   CHECK: [[USE_OP:%[0-9]+]]:_(<5 x s32>) = G_AND [[INSERT2]]:_, [[INSERT2]]:_
1072   )";
1073 
1074   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1075 }
1076 
1077 // FNEG expansion in terms of XOR
1078 TEST_F(AArch64GISelMITest, LowerFNEG) {
1079   setUp();
1080   if (!TM)
1081     return;
1082 
1083   // Declare your legalization info
1084   DefineLegalizerInfo(A, {
1085     getActionDefinitionsBuilder(G_FSUB).legalFor({s64});
1086   });
1087 
1088   // Build Instr. Make sure FMF are preserved.
1089   auto FAdd =
1090     B.buildInstr(TargetOpcode::G_FADD, {LLT::scalar(64)}, {Copies[0], Copies[1]},
1091                  MachineInstr::MIFlag::FmNsz);
1092 
1093   // Should not propagate the flags of src instruction.
1094   auto FNeg0 =
1095     B.buildInstr(TargetOpcode::G_FNEG, {LLT::scalar(64)}, {FAdd.getReg(0)},
1096                  {MachineInstr::MIFlag::FmArcp});
1097 
1098   // Preserve the one flag.
1099   auto FNeg1 =
1100     B.buildInstr(TargetOpcode::G_FNEG, {LLT::scalar(64)}, {Copies[0]},
1101                  MachineInstr::MIFlag::FmNoInfs);
1102 
1103   AInfo Info(MF->getSubtarget());
1104   DummyGISelObserver Observer;
1105   LegalizerHelper Helper(*MF, Info, Observer, B);
1106   // Perform Legalization
1107   B.setInstr(*FNeg0);
1108   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1109             Helper.lower(*FNeg0, 0, LLT::scalar(64)));
1110   B.setInstr(*FNeg1);
1111   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1112             Helper.lower(*FNeg1, 0, LLT::scalar(64)));
1113 
1114   auto CheckStr = R"(
1115   CHECK: [[FADD:%[0-9]+]]:_(s64) = nsz G_FADD %0:_, %1:_
1116   CHECK: [[CONST0:%[0-9]+]]:_(s64) = G_CONSTANT i64 -9223372036854775808
1117   CHECK: [[FSUB0:%[0-9]+]]:_(s64) = G_XOR [[FADD]]:_, [[CONST0]]:_
1118   CHECK: [[CONST1:%[0-9]+]]:_(s64) = G_CONSTANT i64 -9223372036854775808
1119   CHECK: [[FSUB1:%[0-9]+]]:_(s64) = G_XOR %0:_, [[CONST1]]:_
1120   )";
1121 
1122   // Check
1123   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1124 }
1125 
1126 TEST_F(AArch64GISelMITest, LowerMinMax) {
1127   setUp();
1128   if (!TM)
1129     return;
1130 
1131   LLT s64 = LLT::scalar(64);
1132   LLT v2s32 = LLT::vector(2, 32);
1133 
1134   DefineLegalizerInfo(A, {
1135     getActionDefinitionsBuilder({G_SMIN, G_SMAX, G_UMIN, G_UMAX})
1136       .lowerFor({s64, LLT::vector(2, s32)});
1137   });
1138 
1139   auto SMin = B.buildSMin(s64, Copies[0], Copies[1]);
1140   auto SMax = B.buildSMax(s64, Copies[0], Copies[1]);
1141   auto UMin = B.buildUMin(s64, Copies[0], Copies[1]);
1142   auto UMax = B.buildUMax(s64, Copies[0], Copies[1]);
1143 
1144   auto VecVal0 = B.buildBitcast(v2s32, Copies[0]);
1145   auto VecVal1 = B.buildBitcast(v2s32, Copies[1]);
1146 
1147   auto SMinV = B.buildSMin(v2s32, VecVal0, VecVal1);
1148   auto SMaxV = B.buildSMax(v2s32, VecVal0, VecVal1);
1149   auto UMinV = B.buildUMin(v2s32, VecVal0, VecVal1);
1150   auto UMaxV = B.buildUMax(v2s32, VecVal0, VecVal1);
1151 
1152   AInfo Info(MF->getSubtarget());
1153   DummyGISelObserver Observer;
1154   LegalizerHelper Helper(*MF, Info, Observer, B);
1155   B.setInstr(*SMin);
1156   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1157             Helper.lower(*SMin, 0, s64));
1158   B.setInstr(*SMax);
1159   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1160             Helper.lower(*SMax, 0, s64));
1161   B.setInstr(*UMin);
1162   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1163             Helper.lower(*UMin, 0, s64));
1164   B.setInstr(*UMax);
1165   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1166             Helper.lower(*UMax, 0, s64));
1167 
1168   B.setInstr(*SMinV);
1169   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1170             Helper.lower(*SMinV, 0, v2s32));
1171   B.setInstr(*SMaxV);
1172   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1173             Helper.lower(*SMaxV, 0, v2s32));
1174   B.setInstr(*UMinV);
1175   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1176             Helper.lower(*UMinV, 0, v2s32));
1177   B.setInstr(*UMaxV);
1178   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1179             Helper.lower(*UMaxV, 0, v2s32));
1180 
1181   auto CheckStr = R"(
1182   CHECK: [[CMP0:%[0-9]+]]:_(s1) = G_ICMP intpred(slt), %0:_(s64), %1:_
1183   CHECK: [[SMIN:%[0-9]+]]:_(s64) = G_SELECT [[CMP0]]:_(s1), %0:_, %1:_
1184 
1185   CHECK: [[CMP1:%[0-9]+]]:_(s1) = G_ICMP intpred(sgt), %0:_(s64), %1:_
1186   CHECK: [[SMAX:%[0-9]+]]:_(s64) = G_SELECT [[CMP1]]:_(s1), %0:_, %1:_
1187 
1188   CHECK: [[CMP2:%[0-9]+]]:_(s1) = G_ICMP intpred(ult), %0:_(s64), %1:_
1189   CHECK: [[UMIN:%[0-9]+]]:_(s64) = G_SELECT [[CMP2]]:_(s1), %0:_, %1:_
1190 
1191   CHECK: [[CMP3:%[0-9]+]]:_(s1) = G_ICMP intpred(ugt), %0:_(s64), %1:_
1192   CHECK: [[UMAX:%[0-9]+]]:_(s64) = G_SELECT [[CMP3]]:_(s1), %0:_, %1:_
1193 
1194   CHECK: [[VEC0:%[0-9]+]]:_(<2 x s32>) = G_BITCAST %0:_(s64)
1195   CHECK: [[VEC1:%[0-9]+]]:_(<2 x s32>) = G_BITCAST %1:_(s64)
1196 
1197   CHECK: [[VCMP0:%[0-9]+]]:_(<2 x s1>) = G_ICMP intpred(slt), [[VEC0]]:_(<2 x s32>), [[VEC1]]:_
1198   CHECK: [[SMINV:%[0-9]+]]:_(<2 x s32>) = G_SELECT [[VCMP0]]:_(<2 x s1>), [[VEC0]]:_, [[VEC1]]:_
1199 
1200   CHECK: [[VCMP1:%[0-9]+]]:_(<2 x s1>) = G_ICMP intpred(sgt), [[VEC0]]:_(<2 x s32>), [[VEC1]]:_
1201   CHECK: [[SMAXV:%[0-9]+]]:_(<2 x s32>) = G_SELECT [[VCMP1]]:_(<2 x s1>), [[VEC0]]:_, [[VEC1]]:_
1202 
1203   CHECK: [[VCMP2:%[0-9]+]]:_(<2 x s1>) = G_ICMP intpred(ult), [[VEC0]]:_(<2 x s32>), [[VEC1]]:_
1204   CHECK: [[UMINV:%[0-9]+]]:_(<2 x s32>) = G_SELECT [[VCMP2]]:_(<2 x s1>), [[VEC0]]:_, [[VEC1]]:_
1205 
1206   CHECK: [[VCMP3:%[0-9]+]]:_(<2 x s1>) = G_ICMP intpred(ugt), [[VEC0]]:_(<2 x s32>), [[VEC1]]:_
1207   CHECK: [[UMAXV:%[0-9]+]]:_(<2 x s32>) = G_SELECT [[VCMP3]]:_(<2 x s1>), [[VEC0]]:_, [[VEC1]]:_
1208   )";
1209 
1210   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1211 }
1212 
1213 TEST_F(AArch64GISelMITest, WidenScalarBuildVector) {
1214   setUp();
1215   if (!TM)
1216     return;
1217 
1218   LLT S32 = LLT::scalar(32);
1219   LLT S16 = LLT::scalar(16);
1220   LLT V2S16 = LLT::vector(2, S16);
1221   LLT V2S32 = LLT::vector(2, S32);
1222 
1223   DefineLegalizerInfo(A, {
1224     getActionDefinitionsBuilder({G_SMIN, G_SMAX, G_UMIN, G_UMAX})
1225       .lowerFor({s64, LLT::vector(2, s32)});
1226   });
1227 
1228   AInfo Info(MF->getSubtarget());
1229   DummyGISelObserver Observer;
1230   LegalizerHelper Helper(*MF, Info, Observer, B);
1231   B.setInsertPt(*EntryMBB, EntryMBB->end());
1232 
1233   Register Constant0 = B.buildConstant(S16, 1).getReg(0);
1234   Register Constant1 = B.buildConstant(S16, 2).getReg(0);
1235   auto BV0 = B.buildBuildVector(V2S16, {Constant0, Constant1});
1236   auto BV1 = B.buildBuildVector(V2S16, {Constant0, Constant1});
1237 
1238   B.setInstr(*BV0);
1239   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1240             Helper.widenScalar(*BV0, 0, V2S32));
1241   B.setInstr(*BV1);
1242   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1243             Helper.widenScalar(*BV1, 1, S32));
1244 
1245   auto CheckStr = R"(
1246   CHECK: [[K0:%[0-9]+]]:_(s16) = G_CONSTANT i16 1
1247   CHECK-NEXT: [[K1:%[0-9]+]]:_(s16) = G_CONSTANT i16 2
1248   CHECK-NEXT: [[EXT_K0_0:%[0-9]+]]:_(s32) = G_ANYEXT [[K0]]
1249   CHECK-NEXT: [[EXT_K1_0:%[0-9]+]]:_(s32) = G_ANYEXT [[K1]]
1250   CHECK-NEXT: [[BV0:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[EXT_K0_0]]:_(s32), [[EXT_K1_0]]:_(s32)
1251   CHECK-NEXT: [[BV0_TRUNC:%[0-9]+]]:_(<2 x s16>) = G_TRUNC [[BV0]]
1252 
1253   CHECK: [[EXT_K0_1:%[0-9]+]]:_(s32) = G_ANYEXT [[K0]]
1254   CHECK-NEXT: [[EXT_K1_1:%[0-9]+]]:_(s32) = G_ANYEXT [[K1]]
1255 
1256   CHECK-NEXT: [[BV1:%[0-9]+]]:_(<2 x s16>) = G_BUILD_VECTOR_TRUNC [[EXT_K0_1]]:_(s32), [[EXT_K1_1]]:_(s32)
1257   )";
1258 
1259   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1260 }
1261 
1262 TEST_F(AArch64GISelMITest, LowerMergeValues) {
1263   setUp();
1264   if (!TM)
1265     return;
1266 
1267   const LLT S32 = LLT::scalar(32);
1268   const LLT S24 = LLT::scalar(24);
1269   const LLT S21 = LLT::scalar(21);
1270   const LLT S16 = LLT::scalar(16);
1271   const LLT S9 = LLT::scalar(9);
1272   const LLT S8 = LLT::scalar(8);
1273   const LLT S3 = LLT::scalar(3);
1274 
1275   DefineLegalizerInfo(A, {
1276     getActionDefinitionsBuilder(G_UNMERGE_VALUES)
1277       .widenScalarIf(typeIs(1, LLT::scalar(3)), changeTo(1, LLT::scalar(9)));
1278   });
1279 
1280   AInfo Info(MF->getSubtarget());
1281   DummyGISelObserver Observer;
1282   LegalizerHelper Helper(*MF, Info, Observer, B);
1283   B.setInsertPt(*EntryMBB, EntryMBB->end());
1284 
1285   // 24 = 3 3 3   3 3 3   3 3
1286   //     => 9
1287   //
1288   // This can do 3 merges, but need an extra implicit_def.
1289   SmallVector<Register, 8> Merge0Ops;
1290   for (int I = 0; I != 8; ++I)
1291     Merge0Ops.push_back(B.buildConstant(S3, I).getReg(0));
1292 
1293   auto Merge0 = B.buildMerge(S24, Merge0Ops);
1294 
1295   // 21 = 3 3 3   3 3 3   3
1296   //     => 9, 2 extra implicit_def needed
1297   //
1298   SmallVector<Register, 8> Merge1Ops;
1299   for (int I = 0; I != 7; ++I)
1300     Merge1Ops.push_back(B.buildConstant(S3, I).getReg(0));
1301 
1302   auto Merge1 = B.buildMerge(S21, Merge1Ops);
1303 
1304   SmallVector<Register, 8> Merge2Ops;
1305   for (int I = 0; I != 2; ++I)
1306     Merge2Ops.push_back(B.buildConstant(S8, I).getReg(0));
1307 
1308   auto Merge2 = B.buildMerge(S16, Merge2Ops);
1309 
1310   B.setInstr(*Merge0);
1311   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1312             Helper.widenScalar(*Merge0, 1, S9));
1313   B.setInstr(*Merge1);
1314   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1315             Helper.widenScalar(*Merge1, 1, S9));
1316 
1317   // Request a source size greater than the original destination size.
1318   B.setInstr(*Merge2);
1319   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1320             Helper.widenScalar(*Merge2, 1, S32));
1321 
1322   auto CheckStr = R"(
1323   CHECK: [[K0:%[0-9]+]]:_(s3) = G_CONSTANT i3 0
1324   CHECK-NEXT: [[K1:%[0-9]+]]:_(s3) = G_CONSTANT i3 1
1325   CHECK-NEXT: [[K2:%[0-9]+]]:_(s3) = G_CONSTANT i3 2
1326   CHECK-NEXT: [[K3:%[0-9]+]]:_(s3) = G_CONSTANT i3 3
1327   CHECK-NEXT: [[K4:%[0-9]+]]:_(s3) = G_CONSTANT i3 -4
1328   CHECK-NEXT: [[K5:%[0-9]+]]:_(s3) = G_CONSTANT i3 -3
1329   CHECK-NEXT: [[K6:%[0-9]+]]:_(s3) = G_CONSTANT i3 -2
1330   CHECK-NEXT: [[K7:%[0-9]+]]:_(s3) = G_CONSTANT i3 -1
1331   CHECK-NEXT: [[IMPDEF0:%[0-9]+]]:_(s3) = G_IMPLICIT_DEF
1332   CHECK-NEXT: [[MERGE0:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K0]]:_(s3), [[K1]]:_(s3), [[K2]]:_(s3)
1333   CHECK-NEXT: [[MERGE1:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K3]]:_(s3), [[K4]]:_(s3), [[K5]]:_(s3)
1334   CHECK-NEXT: [[MERGE2:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K6]]:_(s3), [[K7]]:_(s3), [[IMPDEF0]]:_(s3)
1335   CHECK-NEXT: [[MERGE3:%[0-9]+]]:_(s27) = G_MERGE_VALUES [[MERGE0]]:_(s9), [[MERGE1]]:_(s9), [[MERGE2]]:_(s9)
1336   CHECK-NEXT: (s24) = G_TRUNC [[MERGE3]]:_(s27)
1337 
1338 
1339   CHECK: [[K8:%[0-9]+]]:_(s3) = G_CONSTANT i3 0
1340   CHECK-NEXT: [[K9:%[0-9]+]]:_(s3) = G_CONSTANT i3 1
1341   CHECK-NEXT: [[K10:%[0-9]+]]:_(s3) = G_CONSTANT i3 2
1342   CHECK-NEXT: [[K11:%[0-9]+]]:_(s3) = G_CONSTANT i3 3
1343   CHECK-NEXT: [[K12:%[0-9]+]]:_(s3) = G_CONSTANT i3 -4
1344   CHECK-NEXT: [[K13:%[0-9]+]]:_(s3) = G_CONSTANT i3 -3
1345   CHECK-NEXT: [[K14:%[0-9]+]]:_(s3) = G_CONSTANT i3 -2
1346   CHECK-NEXT: [[IMPDEF1:%[0-9]+]]:_(s3) = G_IMPLICIT_DEF
1347   CHECK-NEXT: [[MERGE4:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K8]]:_(s3), [[K9]]:_(s3), [[K10]]:_(s3)
1348   CHECK-NEXT: [[MERGE5:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K11]]:_(s3), [[K12]]:_(s3), [[K13]]:_(s3)
1349   CHECK-NEXT: [[MERGE6:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K14]]:_(s3), [[IMPDEF1]]:_(s3), [[IMPDEF1]]:_(s3)
1350   CHECK-NEXT: [[MERGE7:%[0-9]+]]:_(s27) = G_MERGE_VALUES [[MERGE4]]:_(s9), [[MERGE5]]:_(s9), [[MERGE6]]:_(s9)
1351   CHECK-NEXT: (s21) = G_TRUNC [[MERGE7]]:_(s27)
1352 
1353 
1354   CHECK: [[K15:%[0-9]+]]:_(s8) = G_CONSTANT i8 0
1355   CHECK-NEXT: [[K16:%[0-9]+]]:_(s8) = G_CONSTANT i8 1
1356   CHECK-NEXT: [[ZEXT_K15:[0-9]+]]:_(s32) = G_ZEXT [[K15]]:_(s8)
1357   CHECK-NEXT: [[ZEXT_K16:[0-9]+]]:_(s32) = G_ZEXT [[K16]]:_(s8)
1358   [[K16:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
1359   [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ZEXT_K16]]:_, [[K16]]:_(s32)
1360   [[OR:%[0-9]+]]:_(s32) = G_OR [[ZEXT_K16]]:_, [[SHL]]:_
1361   (s16) = G_TRUNC [[OR]]:_(s32)
1362   )";
1363 
1364   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1365 }
1366 
1367 TEST_F(AArch64GISelMITest, WidenScalarMergeValuesPointer) {
1368   setUp();
1369   if (!TM)
1370     return;
1371 
1372   DefineLegalizerInfo(A, {});
1373 
1374   AInfo Info(MF->getSubtarget());
1375   DummyGISelObserver Observer;
1376   LegalizerHelper Helper(*MF, Info, Observer, B);
1377   B.setInsertPt(*EntryMBB, EntryMBB->end());
1378 
1379   const LLT S32 = LLT::scalar(32);
1380   const LLT S64 = LLT::scalar(64);
1381   const LLT P0 = LLT::pointer(0, 64);
1382 
1383   auto Lo = B.buildTrunc(S32, Copies[0]);
1384   auto Hi = B.buildTrunc(S32, Copies[1]);
1385 
1386   auto Merge = B.buildMerge(P0, {Lo, Hi});
1387 
1388   B.setInstr(*Merge);
1389   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1390             Helper.widenScalar(*Merge, 1, S64));
1391 
1392   auto CheckStr = R"(
1393    CHECK: [[TRUNC0:%[0-9]+]]:_(s32) = G_TRUNC
1394    CHECK: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC
1395    CHECK: [[ZEXT_TRUNC0:%[0-9]+]]:_(s64) = G_ZEXT [[TRUNC0]]
1396    CHECK: [[ZEXT_TRUNC1:%[0-9]+]]:_(s64) = G_ZEXT [[TRUNC1]]
1397    CHECK: [[SHIFT_AMT:%[0-9]+]]:_(s64) = G_CONSTANT i64 32
1398    CHECK: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ZEXT_TRUNC1]]:_, [[SHIFT_AMT]]
1399    CHECK: [[OR:%[0-9]+]]:_(s64) = G_OR [[ZEXT_TRUNC0]]:_, [[SHL]]
1400    CHECK: [[INTTOPTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[OR]]:_(s64)
1401   )";
1402 
1403   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1404 }
1405 
1406 TEST_F(AArch64GISelMITest, WidenSEXTINREG) {
1407   setUp();
1408   if (!TM)
1409     return;
1410 
1411   // Declare your legalization info
1412   DefineLegalizerInfo(A, {
1413     getActionDefinitionsBuilder(G_SEXT_INREG).legalForTypeWithAnyImm({s64});
1414   });
1415   // Build Instr
1416   auto MIB = B.buildInstr(
1417       TargetOpcode::G_SEXT_INREG, {LLT::scalar(32)},
1418       {B.buildInstr(TargetOpcode::G_TRUNC, {LLT::scalar(32)}, {Copies[0]}),
1419        uint64_t(8)});
1420   AInfo Info(MF->getSubtarget());
1421   DummyGISelObserver Observer;
1422   LegalizerHelper Helper(*MF, Info, Observer, B);
1423   // Perform Legalization
1424   B.setInstr(*MIB);
1425   ASSERT_TRUE(Helper.widenScalar(*MIB, 0, LLT::scalar(64)) ==
1426               LegalizerHelper::LegalizeResult::Legalized);
1427 
1428   auto CheckStr = R"(
1429   CHECK: [[T0:%[0-9]+]]:_(s32) = G_TRUNC
1430   CHECK: [[T1:%[0-9]+]]:_(s64) = G_ANYEXT [[T0]]:_(s32)
1431   CHECK: [[T2:%[0-9]+]]:_(s64) = G_SEXT_INREG [[T1]]:_, 8
1432   CHECK: [[T3:%[0-9]+]]:_(s32) = G_TRUNC [[T2]]:_(s64)
1433   )";
1434 
1435   // Check
1436   ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1437 }
1438 
1439 TEST_F(AArch64GISelMITest, NarrowSEXTINREG) {
1440   setUp();
1441   if (!TM)
1442     return;
1443 
1444   // Declare your legalization info, these aren't actually relevant to the test.
1445   DefineLegalizerInfo(A, {
1446     getActionDefinitionsBuilder(G_SEXT_INREG).legalForTypeWithAnyImm({s64});
1447   });
1448   // Build Instr
1449   auto MIB = B.buildInstr(
1450       TargetOpcode::G_SEXT_INREG, {LLT::scalar(16)},
1451       {B.buildInstr(TargetOpcode::G_TRUNC, {LLT::scalar(16)}, {Copies[0]}),
1452        uint64_t(8)});
1453   AInfo Info(MF->getSubtarget());
1454   DummyGISelObserver Observer;
1455   LegalizerHelper Helper(*MF, Info, Observer, B);
1456   // Perform Legalization
1457   B.setInstr(*MIB);
1458   ASSERT_TRUE(Helper.narrowScalar(*MIB, 0, LLT::scalar(10)) ==
1459               LegalizerHelper::LegalizeResult::Legalized);
1460 
1461   auto CheckStr = R"(
1462   CHECK: [[T0:%[0-9]+]]:_(s16) = G_TRUNC
1463   CHECK: [[T1:%[0-9]+]]:_(s10) = G_TRUNC [[T0]]:_(s16)
1464   CHECK: [[T2:%[0-9]+]]:_(s10) = G_SEXT_INREG [[T1]]:_, 8
1465   CHECK: [[T3:%[0-9]+]]:_(s16) = G_SEXT [[T2]]:_(s10)
1466   )";
1467 
1468   // Check
1469   ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1470 }
1471 
1472 TEST_F(AArch64GISelMITest, NarrowSEXTINREG2) {
1473   setUp();
1474   if (!TM)
1475     return;
1476 
1477   // Declare your legalization info, these aren't actually relevant to the test.
1478   DefineLegalizerInfo(
1479       A, { getActionDefinitionsBuilder(G_SEXT_INREG).legalForTypeWithAnyImm({s64}); });
1480   // Build Instr
1481   auto MIB = B.buildInstr(
1482       TargetOpcode::G_SEXT_INREG, {LLT::scalar(32)},
1483       {B.buildInstr(TargetOpcode::G_TRUNC, {LLT::scalar(32)}, {Copies[0]}),
1484        uint64_t(9)});
1485   AInfo Info(MF->getSubtarget());
1486   DummyGISelObserver Observer;
1487   LegalizerHelper Helper(*MF, Info, Observer, B);
1488   // Perform Legalization
1489   B.setInstr(*MIB);
1490   ASSERT_TRUE(Helper.narrowScalar(*MIB, 0, LLT::scalar(8)) ==
1491               LegalizerHelper::LegalizeResult::Legalized);
1492 
1493   auto CheckStr = R"(
1494   CHECK: [[T0:%[0-9]+]]:_(s32) = G_TRUNC
1495   CHECK: [[T1:%[0-9]+]]:_(s8), [[T2:%[0-9]+]]:_(s8), [[T3:%[0-9]+]]:_(s8), [[T4:%[0-9]+]]:_(s8) = G_UNMERGE_VALUES [[T0]]:_(s32)
1496   CHECK: [[CST2:%[0-9]+]]:_(s8) = G_CONSTANT i8 7
1497   CHECK: [[T5:%[0-9]+]]:_(s8) = G_SEXT_INREG [[T2]]:_, 1
1498   CHECK: [[T6:%[0-9]+]]:_(s8) = G_ASHR [[T5]]:_, [[CST2]]:_
1499   CHECK: [[T7:%[0-9]+]]:_(s32) = G_MERGE_VALUES [[T1]]:_(s8), [[T5]]:_(s8), [[T6]]:_(s8), [[T6]]:_(s8)
1500   )";
1501 
1502   // Check
1503   ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
1504 }
1505 
1506 TEST_F(AArch64GISelMITest, LowerSEXTINREG) {
1507   setUp();
1508   if (!TM)
1509     return;
1510 
1511   // Declare your legalization info, these aren't actually relevant to the test.
1512   DefineLegalizerInfo(
1513       A, { getActionDefinitionsBuilder(G_SEXT_INREG).legalForTypeWithAnyImm({s64}); });
1514   // Build Instr
1515   auto MIB = B.buildInstr(
1516       TargetOpcode::G_SEXT_INREG, {LLT::scalar(32)},
1517       {B.buildInstr(TargetOpcode::G_TRUNC, {LLT::scalar(32)}, {Copies[0]}),
1518        uint64_t(8)});
1519   AInfo Info(MF->getSubtarget());
1520   DummyGISelObserver Observer;
1521   LegalizerHelper Helper(*MF, Info, Observer, B);
1522   // Perform Legalization
1523   B.setInstr(*MIB);
1524   ASSERT_TRUE(Helper.lower(*MIB, 0, LLT()) ==
1525               LegalizerHelper::LegalizeResult::Legalized);
1526 
1527   auto CheckStr = R"(
1528   CHECK: [[T1:%[0-9]+]]:_(s32) = G_TRUNC
1529   CHECK: [[CST:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
1530   CHECK: [[T2:%[0-9]+]]:_(s32) = G_SHL [[T1]]:_, [[CST]]:_
1531   CHECK: [[T3:%[0-9]+]]:_(s32) = G_ASHR [[T2]]:_, [[CST]]:_
1532   )";
1533 
1534   // Check
1535   ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
1536 }
1537 
1538 TEST_F(AArch64GISelMITest, LibcallFPExt) {
1539   setUp();
1540   if (!TM)
1541     return;
1542 
1543   // Declare your legalization info
1544   DefineLegalizerInfo(A, {
1545     getActionDefinitionsBuilder(G_FPEXT).libcallFor({{s32, s16}, {s128, s64}});
1546   });
1547 
1548   LLT S16{LLT::scalar(16)};
1549   LLT S32{LLT::scalar(32)};
1550   LLT S128{LLT::scalar(128)};
1551   auto MIBTrunc = B.buildTrunc(S16, Copies[0]);
1552   auto MIBFPExt1 =
1553       B.buildInstr(TargetOpcode::G_FPEXT, {S32}, {MIBTrunc});
1554 
1555   auto MIBFPExt2 =
1556       B.buildInstr(TargetOpcode::G_FPEXT, {S128}, {Copies[1]});
1557   AInfo Info(MF->getSubtarget());
1558   DummyGISelObserver Observer;
1559   LegalizerHelper Helper(*MF, Info, Observer, B);
1560   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1561               Helper.libcall(*MIBFPExt1));
1562 
1563   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1564               Helper.libcall(*MIBFPExt2));
1565   auto CheckStr = R"(
1566   CHECK: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC
1567   CHECK: $h0 = COPY [[TRUNC]]
1568   CHECK: BL &__gnu_h2f_ieee
1569   CHECK: $d0 = COPY
1570   CHECK: BL &__extenddftf2
1571   )";
1572 
1573   // Check
1574   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1575 }
1576 
1577 TEST_F(AArch64GISelMITest, LibcallFPTrunc) {
1578   setUp();
1579   if (!TM)
1580     return;
1581 
1582   // Declare your legalization info
1583   DefineLegalizerInfo(A, {
1584     getActionDefinitionsBuilder(G_FPTRUNC).libcallFor({{s16, s32}, {s64, s128}});
1585   });
1586 
1587   LLT S16{LLT::scalar(16)};
1588   LLT S32{LLT::scalar(32)};
1589   LLT S64{LLT::scalar(64)};
1590   LLT S128{LLT::scalar(128)};
1591   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
1592   auto MIBFPTrunc1 =
1593       B.buildInstr(TargetOpcode::G_FPTRUNC, {S16}, {MIBTrunc});
1594 
1595   auto MIBMerge = B.buildMerge(S128, {Copies[1], Copies[2]});
1596 
1597   auto MIBFPTrunc2 =
1598       B.buildInstr(TargetOpcode::G_FPTRUNC, {S64}, {MIBMerge});
1599   AInfo Info(MF->getSubtarget());
1600   DummyGISelObserver Observer;
1601   LegalizerHelper Helper(*MF, Info, Observer, B);
1602   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1603             Helper.libcall(*MIBFPTrunc1));
1604 
1605   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1606             Helper.libcall(*MIBFPTrunc2));
1607   auto CheckStr = R"(
1608   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
1609   CHECK: $s0 = COPY [[TRUNC]]
1610   CHECK: BL &__gnu_f2h_ieee
1611   CHECK: $q0 = COPY
1612   CHECK: BL &__trunctfdf2
1613   )";
1614 
1615   // Check
1616   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1617 }
1618 
1619 TEST_F(AArch64GISelMITest, LibcallSimple) {
1620   setUp();
1621   if (!TM)
1622     return;
1623 
1624   // Declare your legalization info
1625   DefineLegalizerInfo(A, {
1626     getActionDefinitionsBuilder(G_FADD).libcallFor({s16});
1627   });
1628 
1629   LLT S16{LLT::scalar(16)};
1630   auto MIBTrunc = B.buildTrunc(S16, Copies[0]);
1631   auto MIBFADD =
1632       B.buildInstr(TargetOpcode::G_FADD, {S16}, {MIBTrunc, MIBTrunc});
1633 
1634   AInfo Info(MF->getSubtarget());
1635   DummyGISelObserver Observer;
1636   LegalizerHelper Helper(*MF, Info, Observer, B);
1637   // Make sure we do not crash anymore
1638   EXPECT_EQ(LegalizerHelper::LegalizeResult::UnableToLegalize,
1639             Helper.libcall(*MIBFADD));
1640 }
1641 
1642 TEST_F(AArch64GISelMITest, LibcallSRem) {
1643   setUp();
1644   if (!TM)
1645     return;
1646 
1647   // Declare your legalization info
1648   DefineLegalizerInfo(A, {
1649     getActionDefinitionsBuilder(G_SREM).libcallFor({s32, s64, s128});
1650   });
1651 
1652   LLT S32{LLT::scalar(32)};
1653   LLT S64{LLT::scalar(64)};
1654   LLT S128{LLT::scalar(128)};
1655   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
1656   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
1657 
1658   auto MIBSRem32 =
1659       B.buildInstr(TargetOpcode::G_SREM, {S32}, {MIBTrunc, MIBTrunc});
1660   auto MIBSRem64 =
1661       B.buildInstr(TargetOpcode::G_SREM, {S64}, {Copies[0], Copies[0]});
1662   auto MIBSRem128 =
1663       B.buildInstr(TargetOpcode::G_SREM, {S128}, {MIBExt, MIBExt});
1664 
1665   AInfo Info(MF->getSubtarget());
1666   DummyGISelObserver Observer;
1667   LegalizerHelper Helper(*MF, Info, Observer, B);
1668 
1669   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1670             Helper.libcall(*MIBSRem32));
1671   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1672             Helper.libcall(*MIBSRem64));
1673   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1674             Helper.libcall(*MIBSRem128));
1675 
1676   auto CheckStr = R"(
1677   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
1678   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
1679   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
1680   CHECK: $w0 = COPY [[TRUNC]]
1681   CHECK: $w1 = COPY [[TRUNC]]
1682   CHECK: BL &__modsi3
1683   CHECK: $x0 = COPY [[COPY]]
1684   CHECK: $x1 = COPY [[COPY]]
1685   CHECK: BL &__moddi3
1686   CHECK: [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[ANYEXT]]
1687   CHECK: [[UV2:%[0-9]+]]:_(s64), [[UV3:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[ANYEXT]]
1688   CHECK: $x0 = COPY [[UV]]
1689   CHECK: $x1 = COPY [[UV1]]
1690   CHECK: $x2 = COPY [[UV2]]
1691   CHECK: $x3 = COPY [[UV3]]
1692   CHECK: BL &__modti3
1693   )";
1694 
1695   // Check
1696   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1697 }
1698 
1699 TEST_F(AArch64GISelMITest, LibcallURem) {
1700   setUp();
1701   if (!TM)
1702     return;
1703 
1704   // Declare your legalization info
1705   DefineLegalizerInfo(A, {
1706     getActionDefinitionsBuilder(G_UREM).libcallFor({s32, s64, s128});
1707   });
1708 
1709   LLT S32{LLT::scalar(32)};
1710   LLT S64{LLT::scalar(64)};
1711   LLT S128{LLT::scalar(128)};
1712   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
1713   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
1714 
1715   auto MIBURem32 =
1716       B.buildInstr(TargetOpcode::G_UREM, {S32}, {MIBTrunc, MIBTrunc});
1717   auto MIBURem64 =
1718       B.buildInstr(TargetOpcode::G_UREM, {S64}, {Copies[0], Copies[0]});
1719   auto MIBURem128 =
1720       B.buildInstr(TargetOpcode::G_UREM, {S128}, {MIBExt, MIBExt});
1721 
1722   AInfo Info(MF->getSubtarget());
1723   DummyGISelObserver Observer;
1724   LegalizerHelper Helper(*MF, Info, Observer, B);
1725 
1726   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1727             Helper.libcall(*MIBURem32));
1728   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1729             Helper.libcall(*MIBURem64));
1730   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1731             Helper.libcall(*MIBURem128));
1732 
1733   const auto *CheckStr = R"(
1734   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
1735   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
1736   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
1737   CHECK: $w0 = COPY [[TRUNC]]
1738   CHECK: $w1 = COPY [[TRUNC]]
1739   CHECK: BL &__umodsi3
1740   CHECK: $x0 = COPY [[COPY]]
1741   CHECK: $x1 = COPY [[COPY]]
1742   CHECK: BL &__umoddi3
1743   CHECK: [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[ANYEXT]]
1744   CHECK: [[UV2:%[0-9]+]]:_(s64), [[UV3:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[ANYEXT]]
1745   CHECK: $x0 = COPY [[UV]]
1746   CHECK: $x1 = COPY [[UV1]]
1747   CHECK: $x2 = COPY [[UV2]]
1748   CHECK: $x3 = COPY [[UV3]]
1749   CHECK: BL &__umodti3
1750   )";
1751 
1752   // Check
1753   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1754 }
1755 
1756 TEST_F(AArch64GISelMITest, LibcallCtlzZeroUndef) {
1757   setUp();
1758   if (!TM)
1759     return;
1760 
1761   // Declare your legalization info
1762   DefineLegalizerInfo(A, {
1763     getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF)
1764         .libcallFor({{s32, s32}, {s64, s64}, {s128, s128}});
1765   });
1766 
1767   LLT S32{LLT::scalar(32)};
1768   LLT S64{LLT::scalar(64)};
1769   LLT S128{LLT::scalar(128)};
1770   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
1771   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
1772 
1773   auto MIBCtlz32 =
1774       B.buildInstr(TargetOpcode::G_CTLZ_ZERO_UNDEF, {S32}, {MIBTrunc});
1775   auto MIBCtlz64 =
1776       B.buildInstr(TargetOpcode::G_CTLZ_ZERO_UNDEF, {S64}, {Copies[0]});
1777   auto MIBCtlz128 =
1778       B.buildInstr(TargetOpcode::G_CTLZ_ZERO_UNDEF, {S128}, {MIBExt});
1779 
1780   AInfo Info(MF->getSubtarget());
1781   DummyGISelObserver Observer;
1782   LegalizerHelper Helper(*MF, Info, Observer, B);
1783 
1784   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1785             Helper.libcall(*MIBCtlz32));
1786   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1787             Helper.libcall(*MIBCtlz64));
1788   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1789             Helper.libcall(*MIBCtlz128));
1790 
1791   const auto *CheckStr = R"(
1792   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
1793   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
1794   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
1795   CHECK: $w0 = COPY [[TRUNC]]
1796   CHECK: BL &__clzsi2
1797   CHECK: $x0 = COPY [[COPY]]
1798   CHECK: BL &__clzdi2
1799   CHECK: [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[ANYEXT]]
1800   CHECK: $x0 = COPY [[UV]]
1801   CHECK: $x1 = COPY [[UV1]]
1802   CHECK: BL &__clzti2
1803   )";
1804 
1805   // Check
1806   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1807 }
1808 
1809 TEST_F(AArch64GISelMITest, LibcallFAdd) {
1810   setUp();
1811   if (!TM)
1812     return;
1813 
1814   // Declare your legalization info
1815   DefineLegalizerInfo(A, {
1816     getActionDefinitionsBuilder(G_FADD).libcallFor({s32, s64, s128});
1817   });
1818 
1819   LLT S32{LLT::scalar(32)};
1820   LLT S64{LLT::scalar(64)};
1821   LLT S128{LLT::scalar(128)};
1822   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
1823   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
1824 
1825   auto MIBAdd32 =
1826       B.buildInstr(TargetOpcode::G_FADD, {S32}, {MIBTrunc, MIBTrunc});
1827   auto MIBAdd64 =
1828       B.buildInstr(TargetOpcode::G_FADD, {S64}, {Copies[0], Copies[0]});
1829   auto MIBAdd128 = B.buildInstr(TargetOpcode::G_FADD, {S128}, {MIBExt, MIBExt});
1830 
1831   AInfo Info(MF->getSubtarget());
1832   DummyGISelObserver Observer;
1833   LegalizerHelper Helper(*MF, Info, Observer, B);
1834 
1835   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1836             Helper.libcall(*MIBAdd32));
1837   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1838             Helper.libcall(*MIBAdd64));
1839   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1840             Helper.libcall(*MIBAdd128));
1841 
1842   const auto *CheckStr = R"(
1843   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
1844   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
1845   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
1846   CHECK: $s0 = COPY [[TRUNC]]
1847   CHECK: $s1 = COPY [[TRUNC]]
1848   CHECK: BL &__addsf3
1849   CHECK: $d0 = COPY [[COPY]]
1850   CHECK: $d1 = COPY [[COPY]]
1851   CHECK: BL &__adddf3
1852   CHECK: $q0 = COPY [[ANYEXT]]
1853   CHECK: $q1 = COPY [[ANYEXT]]
1854   CHECK: BL &__addtf3
1855   )";
1856 
1857   // Check
1858   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1859 }
1860 
1861 TEST_F(AArch64GISelMITest, LibcallFSub) {
1862   setUp();
1863   if (!TM)
1864     return;
1865 
1866   // Declare your legalization info
1867   DefineLegalizerInfo(A, {
1868     getActionDefinitionsBuilder(G_FSUB).libcallFor({s32, s64, s128});
1869   });
1870 
1871   LLT S32{LLT::scalar(32)};
1872   LLT S64{LLT::scalar(64)};
1873   LLT S128{LLT::scalar(128)};
1874   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
1875   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
1876 
1877   auto MIBSub32 =
1878       B.buildInstr(TargetOpcode::G_FSUB, {S32}, {MIBTrunc, MIBTrunc});
1879   auto MIBSub64 =
1880       B.buildInstr(TargetOpcode::G_FSUB, {S64}, {Copies[0], Copies[0]});
1881   auto MIBSub128 = B.buildInstr(TargetOpcode::G_FSUB, {S128}, {MIBExt, MIBExt});
1882 
1883   AInfo Info(MF->getSubtarget());
1884   DummyGISelObserver Observer;
1885   LegalizerHelper Helper(*MF, Info, Observer, B);
1886 
1887   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1888             Helper.libcall(*MIBSub32));
1889   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1890             Helper.libcall(*MIBSub64));
1891   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1892             Helper.libcall(*MIBSub128));
1893 
1894   const auto *CheckStr = R"(
1895   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
1896   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
1897   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
1898   CHECK: $s0 = COPY [[TRUNC]]
1899   CHECK: $s1 = COPY [[TRUNC]]
1900   CHECK: BL &__subsf3
1901   CHECK: $d0 = COPY [[COPY]]
1902   CHECK: $d1 = COPY [[COPY]]
1903   CHECK: BL &__subdf3
1904   CHECK: $q0 = COPY [[ANYEXT]]
1905   CHECK: $q1 = COPY [[ANYEXT]]
1906   CHECK: BL &__subtf3
1907   )";
1908 
1909   // Check
1910   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1911 }
1912 
1913 TEST_F(AArch64GISelMITest, LibcallFMul) {
1914   setUp();
1915   if (!TM)
1916     return;
1917 
1918   // Declare your legalization info
1919   DefineLegalizerInfo(A, {
1920     getActionDefinitionsBuilder(G_FMUL).libcallFor({s32, s64, s128});
1921   });
1922 
1923   LLT S32{LLT::scalar(32)};
1924   LLT S64{LLT::scalar(64)};
1925   LLT S128{LLT::scalar(128)};
1926   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
1927   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
1928 
1929   auto MIBMul32 =
1930       B.buildInstr(TargetOpcode::G_FMUL, {S32}, {MIBTrunc, MIBTrunc});
1931   auto MIBMul64 =
1932       B.buildInstr(TargetOpcode::G_FMUL, {S64}, {Copies[0], Copies[0]});
1933   auto MIBMul128 = B.buildInstr(TargetOpcode::G_FMUL, {S128}, {MIBExt, MIBExt});
1934 
1935   AInfo Info(MF->getSubtarget());
1936   DummyGISelObserver Observer;
1937   LegalizerHelper Helper(*MF, Info, Observer, B);
1938 
1939   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1940             Helper.libcall(*MIBMul32));
1941   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1942             Helper.libcall(*MIBMul64));
1943   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1944             Helper.libcall(*MIBMul128));
1945 
1946   const auto *CheckStr = R"(
1947   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
1948   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
1949   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
1950   CHECK: $s0 = COPY [[TRUNC]]
1951   CHECK: $s1 = COPY [[TRUNC]]
1952   CHECK: BL &__mulsf3
1953   CHECK: $d0 = COPY [[COPY]]
1954   CHECK: $d1 = COPY [[COPY]]
1955   CHECK: BL &__muldf3
1956   CHECK: $q0 = COPY [[ANYEXT]]
1957   CHECK: $q1 = COPY [[ANYEXT]]
1958   CHECK: BL &__multf3
1959   )";
1960 
1961   // Check
1962   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1963 }
1964 
1965 TEST_F(AArch64GISelMITest, LibcallFDiv) {
1966   setUp();
1967   if (!TM)
1968     return;
1969 
1970   // Declare your legalization info
1971   DefineLegalizerInfo(A, {
1972     getActionDefinitionsBuilder(G_FDIV).libcallFor({s32, s64, s128});
1973   });
1974 
1975   LLT S32{LLT::scalar(32)};
1976   LLT S64{LLT::scalar(64)};
1977   LLT S128{LLT::scalar(128)};
1978   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
1979   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
1980 
1981   auto MIBDiv32 =
1982       B.buildInstr(TargetOpcode::G_FDIV, {S32}, {MIBTrunc, MIBTrunc});
1983   auto MIBDiv64 =
1984       B.buildInstr(TargetOpcode::G_FDIV, {S64}, {Copies[0], Copies[0]});
1985   auto MIBDiv128 = B.buildInstr(TargetOpcode::G_FDIV, {S128}, {MIBExt, MIBExt});
1986 
1987   AInfo Info(MF->getSubtarget());
1988   DummyGISelObserver Observer;
1989   LegalizerHelper Helper(*MF, Info, Observer, B);
1990 
1991   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1992             Helper.libcall(*MIBDiv32));
1993   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1994             Helper.libcall(*MIBDiv64));
1995   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1996             Helper.libcall(*MIBDiv128));
1997 
1998   const auto *CheckStr = R"(
1999   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2000   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2001   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2002   CHECK: $s0 = COPY [[TRUNC]]
2003   CHECK: $s1 = COPY [[TRUNC]]
2004   CHECK: BL &__divsf3
2005   CHECK: $d0 = COPY [[COPY]]
2006   CHECK: $d1 = COPY [[COPY]]
2007   CHECK: BL &__divdf3
2008   CHECK: $q0 = COPY [[ANYEXT]]
2009   CHECK: $q1 = COPY [[ANYEXT]]
2010   CHECK: BL &__divtf3
2011   )";
2012 
2013   // Check
2014   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2015 }
2016 
2017 TEST_F(AArch64GISelMITest, LibcallFExp) {
2018   setUp();
2019   if (!TM)
2020     return;
2021 
2022   // Declare your legalization info
2023   DefineLegalizerInfo(A, {
2024     getActionDefinitionsBuilder(G_FEXP).libcallFor({s32, s64, s128});
2025   });
2026 
2027   LLT S32{LLT::scalar(32)};
2028   LLT S64{LLT::scalar(64)};
2029   LLT S128{LLT::scalar(128)};
2030   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2031   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2032 
2033   auto MIBExp32 = B.buildInstr(TargetOpcode::G_FEXP, {S32}, {MIBTrunc});
2034   auto MIBExp64 = B.buildInstr(TargetOpcode::G_FEXP, {S64}, {Copies[0]});
2035   auto MIBExp128 = B.buildInstr(TargetOpcode::G_FEXP, {S128}, {MIBExt});
2036 
2037   AInfo Info(MF->getSubtarget());
2038   DummyGISelObserver Observer;
2039   LegalizerHelper Helper(*MF, Info, Observer, B);
2040 
2041   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2042             Helper.libcall(*MIBExp32));
2043   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2044             Helper.libcall(*MIBExp64));
2045   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2046             Helper.libcall(*MIBExp128));
2047 
2048   const auto *CheckStr = R"(
2049   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2050   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2051   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2052   CHECK: $s0 = COPY [[TRUNC]]
2053   CHECK: BL &expf
2054   CHECK: $d0 = COPY [[COPY]]
2055   CHECK: BL &exp
2056   CHECK: $q0 = COPY [[ANYEXT]]
2057   CHECK: BL &expl
2058   )";
2059 
2060   // Check
2061   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2062 }
2063 
2064 TEST_F(AArch64GISelMITest, LibcallFExp2) {
2065   setUp();
2066   if (!TM)
2067     return;
2068 
2069   // Declare your legalization info
2070   DefineLegalizerInfo(A, {
2071     getActionDefinitionsBuilder(G_FEXP2).libcallFor({s32, s64, s128});
2072   });
2073 
2074   LLT S32{LLT::scalar(32)};
2075   LLT S64{LLT::scalar(64)};
2076   LLT S128{LLT::scalar(128)};
2077   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2078   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2079 
2080   auto MIBExp232 = B.buildInstr(TargetOpcode::G_FEXP2, {S32}, {MIBTrunc});
2081   auto MIBExp264 = B.buildInstr(TargetOpcode::G_FEXP2, {S64}, {Copies[0]});
2082   auto MIBExp2128 = B.buildInstr(TargetOpcode::G_FEXP2, {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(*MIBExp232));
2090   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2091             Helper.libcall(*MIBExp264));
2092   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2093             Helper.libcall(*MIBExp2128));
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: $s0 = COPY [[TRUNC]]
2100   CHECK: BL &exp2f
2101   CHECK: $d0 = COPY [[COPY]]
2102   CHECK: BL &exp2
2103   CHECK: $q0 = COPY [[ANYEXT]]
2104   CHECK: BL &exp2l
2105   )";
2106 
2107   // Check
2108   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2109 }
2110 
2111 TEST_F(AArch64GISelMITest, LibcallFRem) {
2112   setUp();
2113   if (!TM)
2114     return;
2115 
2116   // Declare your legalization info
2117   DefineLegalizerInfo(A, {
2118     getActionDefinitionsBuilder(G_FREM).libcallFor({s32, s64, s128});
2119   });
2120 
2121   LLT S32{LLT::scalar(32)};
2122   LLT S64{LLT::scalar(64)};
2123   LLT S128{LLT::scalar(128)};
2124   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2125   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2126 
2127   auto MIBFRem32 = B.buildInstr(TargetOpcode::G_FREM, {S32}, {MIBTrunc});
2128   auto MIBFRem64 = B.buildInstr(TargetOpcode::G_FREM, {S64}, {Copies[0]});
2129   auto MIBFRem128 = B.buildInstr(TargetOpcode::G_FREM, {S128}, {MIBExt});
2130 
2131   AInfo Info(MF->getSubtarget());
2132   DummyGISelObserver Observer;
2133   LegalizerHelper Helper(*MF, Info, Observer, B);
2134 
2135   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2136             Helper.libcall(*MIBFRem32));
2137   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2138             Helper.libcall(*MIBFRem64));
2139   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2140             Helper.libcall(*MIBFRem128));
2141 
2142   const auto *CheckStr = R"(
2143   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2144   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2145   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2146   CHECK: $s0 = COPY [[TRUNC]]
2147   CHECK: BL &fmodf
2148   CHECK: $d0 = COPY [[COPY]]
2149   CHECK: BL &fmod
2150   CHECK: $q0 = COPY [[ANYEXT]]
2151   CHECK: BL &fmodl
2152   )";
2153 
2154   // Check
2155   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2156 }
2157 
2158 TEST_F(AArch64GISelMITest, LibcallFPow) {
2159   setUp();
2160   if (!TM)
2161     return;
2162 
2163   // Declare your legalization info
2164   DefineLegalizerInfo(A, {
2165     getActionDefinitionsBuilder(G_FPOW).libcallFor({s32, s64, s128});
2166   });
2167 
2168   LLT S32{LLT::scalar(32)};
2169   LLT S64{LLT::scalar(64)};
2170   LLT S128{LLT::scalar(128)};
2171   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2172   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2173 
2174   auto MIBPow32 = B.buildInstr(TargetOpcode::G_FPOW, {S32}, {MIBTrunc});
2175   auto MIBPow64 = B.buildInstr(TargetOpcode::G_FPOW, {S64}, {Copies[0]});
2176   auto MIBPow128 = B.buildInstr(TargetOpcode::G_FPOW, {S128}, {MIBExt});
2177 
2178   AInfo Info(MF->getSubtarget());
2179   DummyGISelObserver Observer;
2180   LegalizerHelper Helper(*MF, Info, Observer, B);
2181 
2182   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2183             Helper.libcall(*MIBPow32));
2184   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2185             Helper.libcall(*MIBPow64));
2186   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2187             Helper.libcall(*MIBPow128));
2188 
2189   const auto *CheckStr = R"(
2190   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2191   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2192   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2193   CHECK: $s0 = COPY [[TRUNC]]
2194   CHECK: BL &powf
2195   CHECK: $d0 = COPY [[COPY]]
2196   CHECK: BL &pow
2197   CHECK: $q0 = COPY [[ANYEXT]]
2198   CHECK: BL &powl
2199   )";
2200 
2201   // Check
2202   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2203 }
2204 
2205 TEST_F(AArch64GISelMITest, LibcallFMa) {
2206   setUp();
2207   if (!TM)
2208     return;
2209 
2210   // Declare your legalization info
2211   DefineLegalizerInfo(A, {
2212     getActionDefinitionsBuilder(G_FMA).libcallFor({s32, s64, s128});
2213   });
2214 
2215   LLT S32{LLT::scalar(32)};
2216   LLT S64{LLT::scalar(64)};
2217   LLT S128{LLT::scalar(128)};
2218   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2219   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2220 
2221   auto MIBMa32 = B.buildInstr(TargetOpcode::G_FMA, {S32}, {MIBTrunc, MIBTrunc});
2222   auto MIBMa64 =
2223       B.buildInstr(TargetOpcode::G_FMA, {S64}, {Copies[0], Copies[0]});
2224   auto MIBMa128 = B.buildInstr(TargetOpcode::G_FMA, {S128}, {MIBExt, MIBExt});
2225 
2226   AInfo Info(MF->getSubtarget());
2227   DummyGISelObserver Observer;
2228   LegalizerHelper Helper(*MF, Info, Observer, B);
2229 
2230   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2231             Helper.libcall(*MIBMa32));
2232   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2233             Helper.libcall(*MIBMa64));
2234   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2235             Helper.libcall(*MIBMa128));
2236 
2237   const auto *CheckStr = R"(
2238   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2239   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2240   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2241   CHECK: $s0 = COPY [[TRUNC]]
2242   CHECK: BL &fmaf
2243   CHECK: $d0 = COPY [[COPY]]
2244   CHECK: BL &fma
2245   CHECK: $q0 = COPY [[ANYEXT]]
2246   CHECK: BL &fmal
2247   )";
2248 
2249   // Check
2250   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2251 }
2252 
2253 TEST_F(AArch64GISelMITest, LibcallFCeil) {
2254   setUp();
2255   if (!TM)
2256     return;
2257 
2258   // Declare your legalization info
2259   DefineLegalizerInfo(A, {
2260     getActionDefinitionsBuilder(G_FCEIL).libcallFor({s32, s64, s128});
2261   });
2262 
2263   LLT S32{LLT::scalar(32)};
2264   LLT S64{LLT::scalar(64)};
2265   LLT S128{LLT::scalar(128)};
2266   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2267   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2268 
2269   auto MIBCeil32 = B.buildInstr(TargetOpcode::G_FCEIL, {S32}, {MIBTrunc});
2270   auto MIBCeil64 = B.buildInstr(TargetOpcode::G_FCEIL, {S64}, {Copies[0]});
2271   auto MIBCeil128 = B.buildInstr(TargetOpcode::G_FCEIL, {S128}, {MIBExt});
2272 
2273   AInfo Info(MF->getSubtarget());
2274   DummyGISelObserver Observer;
2275   LegalizerHelper Helper(*MF, Info, Observer, B);
2276 
2277   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2278             Helper.libcall(*MIBCeil32));
2279   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2280             Helper.libcall(*MIBCeil64));
2281   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2282             Helper.libcall(*MIBCeil128));
2283 
2284   const auto *CheckStr = R"(
2285   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2286   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2287   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2288   CHECK: $s0 = COPY [[TRUNC]]
2289   CHECK: BL &ceilf
2290   CHECK: $d0 = COPY [[COPY]]
2291   CHECK: BL &ceil
2292   CHECK: $q0 = COPY [[ANYEXT]]
2293   CHECK: BL &ceill
2294   )";
2295 
2296   // Check
2297   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2298 }
2299 
2300 TEST_F(AArch64GISelMITest, LibcallFFloor) {
2301   setUp();
2302   if (!TM)
2303     return;
2304 
2305   // Declare your legalization info
2306   DefineLegalizerInfo(A, {
2307     getActionDefinitionsBuilder(G_FFLOOR).libcallFor({s32, s64, s128});
2308   });
2309 
2310   LLT S32{LLT::scalar(32)};
2311   LLT S64{LLT::scalar(64)};
2312   LLT S128{LLT::scalar(128)};
2313   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2314   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2315 
2316   auto MIBFloor32 = B.buildInstr(TargetOpcode::G_FFLOOR, {S32}, {MIBTrunc});
2317   auto MIBFloor64 = B.buildInstr(TargetOpcode::G_FFLOOR, {S64}, {Copies[0]});
2318   auto MIBFloor128 = B.buildInstr(TargetOpcode::G_FFLOOR, {S128}, {MIBExt});
2319 
2320   AInfo Info(MF->getSubtarget());
2321   DummyGISelObserver Observer;
2322   LegalizerHelper Helper(*MF, Info, Observer, B);
2323 
2324   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2325             Helper.libcall(*MIBFloor32));
2326   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2327             Helper.libcall(*MIBFloor64));
2328   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2329             Helper.libcall(*MIBFloor128));
2330 
2331   const auto *CheckStr = R"(
2332   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2333   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2334   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2335   CHECK: $s0 = COPY [[TRUNC]]
2336   CHECK: BL &floorf
2337   CHECK: $d0 = COPY [[COPY]]
2338   CHECK: BL &floor
2339   CHECK: $q0 = COPY [[ANYEXT]]
2340   CHECK: BL &floorl
2341   )";
2342 
2343   // Check
2344   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2345 }
2346 
2347 TEST_F(AArch64GISelMITest, LibcallFMinNum) {
2348   setUp();
2349   if (!TM)
2350     return;
2351 
2352   // Declare your legalization info
2353   DefineLegalizerInfo(A, {
2354     getActionDefinitionsBuilder(G_FMINNUM).libcallFor({s32, s64, s128});
2355   });
2356 
2357   LLT S32{LLT::scalar(32)};
2358   LLT S64{LLT::scalar(64)};
2359   LLT S128{LLT::scalar(128)};
2360   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2361   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2362 
2363   auto MIBMin32 = B.buildFMinNum(S32, MIBTrunc, MIBTrunc);
2364   auto MIBMin64 = B.buildFMinNum(S64, Copies[0], Copies[0]);
2365   auto MIBMin128 = B.buildFMinNum(S128, MIBExt, MIBExt);
2366 
2367   AInfo Info(MF->getSubtarget());
2368   DummyGISelObserver Observer;
2369   LegalizerHelper Helper(*MF, Info, Observer, B);
2370 
2371   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2372             Helper.libcall(*MIBMin32));
2373   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2374             Helper.libcall(*MIBMin64));
2375   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2376             Helper.libcall(*MIBMin128));
2377 
2378   const auto *CheckStr = R"(
2379   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2380   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2381   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2382   CHECK: $s0 = COPY [[TRUNC]]
2383   CHECK: $s1 = COPY [[TRUNC]]
2384   CHECK: BL &fminf
2385   CHECK: $d0 = COPY [[COPY]]
2386   CHECK: $d1 = COPY [[COPY]]
2387   CHECK: BL &fmin
2388   CHECK: $q0 = COPY [[ANYEXT]]
2389   CHECK: $q1 = COPY [[ANYEXT]]
2390   CHECK: BL &fminl
2391   )";
2392 
2393   // Check
2394   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2395 }
2396 
2397 TEST_F(AArch64GISelMITest, LibcallFMaxNum) {
2398   setUp();
2399   if (!TM)
2400     return;
2401 
2402   // Declare your legalization info
2403   DefineLegalizerInfo(A, {
2404     getActionDefinitionsBuilder(G_FMAXNUM).libcallFor({s32, s64, s128});
2405   });
2406 
2407   LLT S32{LLT::scalar(32)};
2408   LLT S64{LLT::scalar(64)};
2409   LLT S128{LLT::scalar(128)};
2410   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2411   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2412 
2413   auto MIBMax32 = B.buildFMaxNum(S32, MIBTrunc, MIBTrunc);
2414   auto MIBMax64 = B.buildFMaxNum(S64, Copies[0], Copies[0]);
2415   auto MIBMax128 = B.buildFMaxNum(S128, MIBExt, MIBExt);
2416 
2417   AInfo Info(MF->getSubtarget());
2418   DummyGISelObserver Observer;
2419   LegalizerHelper Helper(*MF, Info, Observer, B);
2420 
2421   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2422             Helper.libcall(*MIBMax32));
2423   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2424             Helper.libcall(*MIBMax64));
2425   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2426             Helper.libcall(*MIBMax128));
2427 
2428   const auto *CheckStr = R"(
2429   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2430   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2431   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2432   CHECK: $s0 = COPY [[TRUNC]]
2433   CHECK: $s1 = COPY [[TRUNC]]
2434   CHECK: BL &fmaxf
2435   CHECK: $d0 = COPY [[COPY]]
2436   CHECK: $d1 = COPY [[COPY]]
2437   CHECK: BL &fmax
2438   CHECK: $q0 = COPY [[ANYEXT]]
2439   CHECK: $q1 = COPY [[ANYEXT]]
2440   CHECK: BL &fmaxl
2441   )";
2442 
2443   // Check
2444   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2445 }
2446 
2447 TEST_F(AArch64GISelMITest, LibcallFSqrt) {
2448   setUp();
2449   if (!TM)
2450     return;
2451 
2452   // Declare your legalization info
2453   DefineLegalizerInfo(A, {
2454     getActionDefinitionsBuilder(G_FSQRT).libcallFor({s32, s64, s128});
2455   });
2456 
2457   LLT S32{LLT::scalar(32)};
2458   LLT S64{LLT::scalar(64)};
2459   LLT S128{LLT::scalar(128)};
2460   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2461   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2462 
2463   auto MIBSqrt32 = B.buildInstr(TargetOpcode::G_FSQRT, {S32}, {MIBTrunc});
2464   auto MIBSqrt64 = B.buildInstr(TargetOpcode::G_FSQRT, {S64}, {Copies[0]});
2465   auto MIBSqrt128 = B.buildInstr(TargetOpcode::G_FSQRT, {S128}, {MIBExt});
2466 
2467   AInfo Info(MF->getSubtarget());
2468   DummyGISelObserver Observer;
2469   LegalizerHelper Helper(*MF, Info, Observer, B);
2470 
2471   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2472             Helper.libcall(*MIBSqrt32));
2473   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2474             Helper.libcall(*MIBSqrt64));
2475   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2476             Helper.libcall(*MIBSqrt128));
2477 
2478   const auto *CheckStr = R"(
2479   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2480   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2481   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2482   CHECK: $s0 = COPY [[TRUNC]]
2483   CHECK: BL &sqrtf
2484   CHECK: $d0 = COPY [[COPY]]
2485   CHECK: BL &sqrt
2486   CHECK: $q0 = COPY [[ANYEXT]]
2487   CHECK: BL &sqrtl
2488   )";
2489 
2490   // Check
2491   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2492 }
2493 
2494 TEST_F(AArch64GISelMITest, LibcallFRint) {
2495   setUp();
2496   if (!TM)
2497     return;
2498 
2499   // Declare your legalization info
2500   DefineLegalizerInfo(A, {
2501     getActionDefinitionsBuilder(G_FRINT).libcallFor({s32, s64, s128});
2502   });
2503 
2504   LLT S32{LLT::scalar(32)};
2505   LLT S64{LLT::scalar(64)};
2506   LLT S128{LLT::scalar(128)};
2507   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2508   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2509 
2510   auto MIBRint32 = B.buildInstr(TargetOpcode::G_FRINT, {S32}, {MIBTrunc});
2511   auto MIBRint64 = B.buildInstr(TargetOpcode::G_FRINT, {S64}, {Copies[0]});
2512   auto MIBRint128 = B.buildInstr(TargetOpcode::G_FRINT, {S128}, {MIBExt});
2513 
2514   AInfo Info(MF->getSubtarget());
2515   DummyGISelObserver Observer;
2516   LegalizerHelper Helper(*MF, Info, Observer, B);
2517 
2518   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2519             Helper.libcall(*MIBRint32));
2520   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2521             Helper.libcall(*MIBRint64));
2522   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2523             Helper.libcall(*MIBRint128));
2524 
2525   const auto *CheckStr = R"(
2526   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2527   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2528   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2529   CHECK: $s0 = COPY [[TRUNC]]
2530   CHECK: BL &rintf
2531   CHECK: $d0 = COPY [[COPY]]
2532   CHECK: BL &rint
2533   CHECK: $q0 = COPY [[ANYEXT]]
2534   CHECK: BL &rintl
2535   )";
2536 
2537   // Check
2538   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2539 }
2540 
2541 TEST_F(AArch64GISelMITest, LibcallFNearbyInt) {
2542   setUp();
2543   if (!TM)
2544     return;
2545 
2546   // Declare your legalization info
2547   DefineLegalizerInfo(A, {
2548     getActionDefinitionsBuilder(G_FNEARBYINT).libcallFor({s32, s64, s128});
2549   });
2550 
2551   LLT S32{LLT::scalar(32)};
2552   LLT S64{LLT::scalar(64)};
2553   LLT S128{LLT::scalar(128)};
2554   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2555   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2556 
2557   auto MIBNearbyInt32 =
2558       B.buildInstr(TargetOpcode::G_FNEARBYINT, {S32}, {MIBTrunc});
2559   auto MIBNearbyInt64 =
2560       B.buildInstr(TargetOpcode::G_FNEARBYINT, {S64}, {Copies[0]});
2561   auto MIBNearbyInt128 =
2562       B.buildInstr(TargetOpcode::G_FNEARBYINT, {S128}, {MIBExt});
2563 
2564   AInfo Info(MF->getSubtarget());
2565   DummyGISelObserver Observer;
2566   LegalizerHelper Helper(*MF, Info, Observer, B);
2567 
2568   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2569             Helper.libcall(*MIBNearbyInt32));
2570   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2571             Helper.libcall(*MIBNearbyInt64));
2572   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2573             Helper.libcall(*MIBNearbyInt128));
2574 
2575   const auto *CheckStr = R"(
2576   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2577   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2578   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2579   CHECK: $s0 = COPY [[TRUNC]]
2580   CHECK: BL &nearbyintf
2581   CHECK: $d0 = COPY [[COPY]]
2582   CHECK: BL &nearbyint
2583   CHECK: $q0 = COPY [[ANYEXT]]
2584   CHECK: BL &nearbyintl
2585   )";
2586 
2587   // Check
2588   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2589 }
2590 
2591 TEST_F(AArch64GISelMITest, NarrowScalarExtract) {
2592   setUp();
2593   if (!TM)
2594     return;
2595 
2596   // Declare your legalization info
2597   DefineLegalizerInfo(A, {
2598     getActionDefinitionsBuilder(G_UNMERGE_VALUES).legalFor({{s32, s64}});
2599     getActionDefinitionsBuilder(G_EXTRACT).legalForTypeWithAnyImm({{s16, s32}});
2600   });
2601 
2602   LLT S16{LLT::scalar(16)};
2603   LLT S32{LLT::scalar(32)};
2604 
2605   auto MIBExtractS32 = B.buildExtract(S32, Copies[1], 32);
2606   auto MIBExtractS16 = B.buildExtract(S16, Copies[1], 0);
2607 
2608   AInfo Info(MF->getSubtarget());
2609   DummyGISelObserver Observer;
2610   LegalizerHelper Helper(*MF, Info, Observer, B);
2611 
2612   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2613             Helper.narrowScalar(*MIBExtractS32, 1, S32));
2614 
2615   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2616             Helper.narrowScalar(*MIBExtractS16, 1, S32));
2617 
2618   const auto *CheckStr = R"(
2619   CHECK: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES
2620   CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY [[UV1]]
2621   CHECK: [[UV3:%[0-9]+]]:_(s32), [[UV4:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES
2622   CHECK: [[EXTR:%[0-9]+]]:_(s16) = G_EXTRACT [[UV3]]:_(s32), 0
2623   CHECK: [[COPY:%[0-9]+]]:_(s16) = COPY [[EXTR]]
2624   )";
2625 
2626   // Check
2627   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2628 }
2629 
2630 TEST_F(AArch64GISelMITest, LowerInsert) {
2631   setUp();
2632   if (!TM)
2633     return;
2634 
2635   // Declare your legalization info
2636   DefineLegalizerInfo(A, { getActionDefinitionsBuilder(G_INSERT).lower(); });
2637 
2638   LLT S32{LLT::scalar(32)};
2639   LLT S64{LLT::scalar(64)};
2640   LLT P0{LLT::pointer(0, 64)};
2641   LLT P1{LLT::pointer(1, 32)};
2642   LLT V2S32{LLT::vector(2, 32)};
2643 
2644   auto TruncS32 = B.buildTrunc(S32, Copies[0]);
2645   auto IntToPtrP0 = B.buildIntToPtr(P0, Copies[0]);
2646   auto IntToPtrP1 = B.buildIntToPtr(P1, TruncS32);
2647   auto BitcastV2S32 = B.buildBitcast(V2S32, Copies[0]);
2648 
2649   auto InsertS64S32 = B.buildInsert(S64, Copies[0], TruncS32, 0);
2650   auto InsertS64P1 = B.buildInsert(S64, Copies[0], IntToPtrP1, 8);
2651   auto InsertP0S32 = B.buildInsert(P0, IntToPtrP0, TruncS32, 16);
2652   auto InsertP0P1 = B.buildInsert(P0, IntToPtrP0, IntToPtrP1, 4);
2653   auto InsertV2S32S32 = B.buildInsert(V2S32, BitcastV2S32, TruncS32, 32);
2654   auto InsertV2S32P1 = B.buildInsert(V2S32, BitcastV2S32, IntToPtrP1, 0);
2655 
2656   AInfo Info(MF->getSubtarget());
2657   DummyGISelObserver Observer;
2658   LegalizerHelper Helper(*MF, Info, Observer, B);
2659 
2660   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2661             Helper.lower(*InsertS64S32, 0, LLT{}));
2662 
2663   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2664             Helper.lower(*InsertS64P1, 0, LLT{}));
2665 
2666   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2667             Helper.lower(*InsertP0S32, 0, LLT{}));
2668 
2669   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2670             Helper.lower(*InsertP0P1, 0, LLT{}));
2671 
2672   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2673             Helper.lower(*InsertV2S32S32, 0, LLT{}));
2674 
2675   EXPECT_EQ(LegalizerHelper::LegalizeResult::UnableToLegalize,
2676             Helper.lower(*InsertV2S32P1, 0, LLT{}));
2677 
2678   const auto *CheckStr = R"(
2679   CHECK: [[S64:%[0-9]+]]:_(s64) = COPY
2680   CHECK: [[S32:%[0-9]+]]:_(s32) = G_TRUNC [[S64]]
2681   CHECK: [[P0:%[0-9]+]]:_(p0) = G_INTTOPTR [[S64]]
2682   CHECK: [[P1:%[0-9]+]]:_(p1) = G_INTTOPTR [[S32]]
2683   CHECK: [[V2S32:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[S64]]
2684   CHECK: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[S32]]
2685   CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT
2686   CHECK: [[AND:%[0-9]+]]:_(s64) = G_AND [[S64]]:_, [[C]]:_
2687   CHECK: [[OR:%[0-9]+]]:_(s64) = G_OR [[AND]]:_, [[ZEXT]]:_
2688 
2689   CHECK: [[PTRTOINT:%[0-9]+]]:_(s32) = G_PTRTOINT [[P1]]
2690   CHECK: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[PTRTOINT]]
2691   CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT
2692   CHECK: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ZEXT]]:_, [[C]]:_(s64)
2693   CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT
2694   CHECK: [[AND:%[0-9]+]]:_(s64) = G_AND [[S64]]:_, [[C]]:_
2695   CHECK: [[OR:%[0-9]+]]:_(s64) = G_OR [[AND]]:_, [[SHL]]:_
2696 
2697   CHECK: [[PTRTOINT:%[0-9]+]]:_(s64) = G_PTRTOINT [[P0]]
2698   CHECK: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[S32]]
2699   CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT
2700   CHECK: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ZEXT]]:_, [[C]]:_(s64)
2701   CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT
2702   CHECK: [[AND:%[0-9]+]]:_(s64) = G_AND [[PTRTOINT]]:_, [[C]]:_
2703   CHECK: [[OR:%[0-9]+]]:_(s64) = G_OR [[AND]]:_, [[SHL]]:_
2704   CHECK: [[INTTOPTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[OR]]
2705 
2706   CHECK: [[PTRTOINT:%[0-9]+]]:_(s64) = G_PTRTOINT [[P0]]
2707   CHECK: [[PTRTOINT1:%[0-9]+]]:_(s32) = G_PTRTOINT [[P1]]
2708   CHECK: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[PTRTOINT1]]
2709   CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT
2710   CHECK: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ZEXT]]:_, [[C]]:_(s64)
2711   CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT
2712   CHECK: [[AND:%[0-9]+]]:_(s64) = G_AND [[PTRTOINT]]:_, [[C]]:_
2713   CHECK: [[OR:%[0-9]+]]:_(s64) = G_OR [[AND]]:_, [[SHL]]:_
2714   CHECK: [[INTTOPTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[OR]]
2715 
2716   CHECK: [[BITCAST:%[0-9]+]]:_(s64) = G_BITCAST [[V2S32]]
2717   CHECK: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[S32]]
2718   CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT
2719   CHECK: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ZEXT]]:_, [[C]]:_(s64)
2720   CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT
2721   CHECK: [[AND:%[0-9]+]]:_(s64) = G_AND [[BITCAST]]:_, [[C]]:_
2722   CHECK: [[OR:%[0-9]+]]:_(s64) = G_OR [[AND]]:_, [[SHL]]:_
2723   CHECK: [[BITCAST:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[OR]]
2724   )";
2725 
2726   // Check
2727   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2728 }
2729 
2730 // Test lowering of G_FFLOOR
2731 TEST_F(AArch64GISelMITest, LowerFFloor) {
2732   setUp();
2733   if (!TM)
2734     return;
2735 
2736   // Declare your legalization info
2737   DefineLegalizerInfo(A, {});
2738   // Build Instr
2739   auto Floor = B.buildFFloor(LLT::scalar(64), Copies[0], MachineInstr::MIFlag::FmNoInfs);
2740   AInfo Info(MF->getSubtarget());
2741   DummyGISelObserver Observer;
2742   LegalizerHelper Helper(*MF, Info, Observer, B);
2743   // Perform Legalization
2744   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2745             Helper.lower(*Floor, 0, LLT()));
2746 
2747   auto CheckStr = R"(
2748   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2749   CHECK: [[TRUNC:%[0-9]+]]:_(s64) = ninf G_INTRINSIC_TRUNC [[COPY]]
2750   CHECK: [[ZERO:%[0-9]+]]:_(s64) = G_FCONSTANT double 0.000000e+00
2751   CHECK: [[CMP0:%[0-9]+]]:_(s1) = ninf G_FCMP floatpred(olt), [[COPY]]:_(s64), [[ZERO]]:_
2752   CHECK: [[CMP1:%[0-9]+]]:_(s1) = ninf G_FCMP floatpred(one), [[COPY]]:_(s64), [[TRUNC]]:_
2753   CHECK: [[AND:%[0-9]+]]:_(s1) = G_AND [[CMP0]]:_, [[CMP1]]:_
2754   CHECK: [[ITOFP:%[0-9]+]]:_(s64) = G_SITOFP [[AND]]
2755   = ninf G_FADD [[TRUNC]]:_, [[ITOFP]]:_
2756   )";
2757 
2758   // Check
2759   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2760 }
2761 
2762 // Test lowering of G_BSWAP
2763 TEST_F(AArch64GISelMITest, LowerBSWAP) {
2764   setUp();
2765   if (!TM)
2766     return;
2767 
2768   DefineLegalizerInfo(A, {});
2769 
2770   // Make sure vector lowering doesn't assert.
2771   auto Cast = B.buildBitcast(LLT::vector(2, 32), Copies[0]);
2772   auto BSwap = B.buildBSwap(LLT::vector(2, 32), Cast);
2773   AInfo Info(MF->getSubtarget());
2774   DummyGISelObserver Observer;
2775   LegalizerHelper Helper(*MF, Info, Observer, B);
2776   // Perform Legalization
2777   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2778             Helper.lower(*BSwap, 0, LLT()));
2779 
2780   auto CheckStr = R"(
2781   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2782   CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[COPY]]
2783   CHECK: [[K24:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
2784   CHECK: [[SPLAT24:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[K24]]:_(s32), [[K24]]:_(s32)
2785   CHECK: [[SHL0:%[0-9]+]]:_(<2 x s32>) = G_SHL [[VEC]]:_, [[SPLAT24]]
2786   CHECK: [[SHR0:%[0-9]+]]:_(<2 x s32>) = G_LSHR [[VEC]]:_, [[SPLAT24]]
2787   CHECK: [[OR0:%[0-9]+]]:_(<2 x s32>) = G_OR [[SHR0]]:_, [[SHL0]]:_
2788   CHECK: [[KMASK:%[0-9]+]]:_(s32) = G_CONSTANT i32 65280
2789   CHECK: [[SPLATMASK:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[KMASK]]:_(s32), [[KMASK]]:_(s32)
2790   CHECK: [[K8:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
2791   CHECK: [[SPLAT8:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[K8]]:_(s32), [[K8]]:_(s32)
2792   CHECK: [[AND0:%[0-9]+]]:_(<2 x s32>) = G_AND [[VEC]]:_, [[SPLATMASK]]:_
2793   CHECK: [[SHL1:%[0-9]+]]:_(<2 x s32>) = G_SHL [[AND0]]:_, [[SPLAT8]]
2794   CHECK: [[OR1:%[0-9]+]]:_(<2 x s32>) = G_OR [[OR0]]:_, [[SHL1]]:_
2795   CHECK: [[SHR1:%[0-9]+]]:_(<2 x s32>) = G_LSHR [[VEC]]:_, [[SPLAT8]]
2796   CHECK: [[AND1:%[0-9]+]]:_(<2 x s32>) = G_AND [[SHR1]]:_, [[SPLATMASK]]:_
2797   CHECK: [[BSWAP:%[0-9]+]]:_(<2 x s32>) = G_OR [[OR1]]:_, [[AND1]]:_
2798   )";
2799 
2800   // Check
2801   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2802 }
2803 
2804 // Test widening of G_UNMERGE_VALUES
2805 TEST_F(AArch64GISelMITest, WidenUnmerge) {
2806   setUp();
2807   if (!TM)
2808     return;
2809 
2810   DefineLegalizerInfo(A, {});
2811 
2812   // Check that widening G_UNMERGE_VALUES to a larger type than the source type
2813   // works as expected
2814   LLT P0{LLT::pointer(0, 64)};
2815   LLT S32{LLT::scalar(32)};
2816   LLT S96{LLT::scalar(96)};
2817 
2818   auto IntToPtr = B.buildIntToPtr(P0, Copies[0]);
2819   auto UnmergePtr = B.buildUnmerge(S32, IntToPtr);
2820   auto UnmergeScalar = B.buildUnmerge(S32, Copies[0]);
2821 
2822   AInfo Info(MF->getSubtarget());
2823   DummyGISelObserver Observer;
2824   LegalizerHelper Helper(*MF, Info, Observer, B);
2825 
2826   // Perform Legalization
2827   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2828             Helper.widenScalar(*UnmergePtr, 0, S96));
2829 
2830   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2831             Helper.widenScalar(*UnmergeScalar, 0, S96));
2832 
2833   const auto *CheckStr = R"(
2834   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2835   CHECK: [[PTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[COPY]]
2836   CHECK: [[INT:%[0-9]+]]:_(s64) = G_PTRTOINT [[PTR]]
2837   CHECK: [[ANYEXT:%[0-9]+]]:_(s96) = G_ANYEXT [[INT]]
2838   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[ANYEXT]]
2839   CHECK: [[C:%[0-9]+]]:_(s96) = G_CONSTANT i96 32
2840   CHECK: [[LSHR:%[0-9]+]]:_(s96) = G_LSHR [[ANYEXT]]:_, [[C]]
2841   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[LSHR]]
2842   CHECK: [[ANYEXT:%[0-9]+]]:_(s96) = G_ANYEXT [[COPY]]
2843   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[ANYEXT]]
2844   CHECK: [[C:%[0-9]+]]:_(s96) = G_CONSTANT i96 32
2845   CHECK: [[LSHR:%[0-9]+]]:_(s96) = G_LSHR [[ANYEXT]]:_, [[C]]
2846   CHECK: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC [[LSHR]]
2847   )";
2848 
2849   // Check
2850   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2851 }
2852 
2853 TEST_F(AArch64GISelMITest, BitcastLoad) {
2854   setUp();
2855   if (!TM)
2856     return;
2857 
2858   LLT P0 = LLT::pointer(0, 64);
2859   LLT S32 = LLT::scalar(32);
2860   LLT V4S8 = LLT::vector(4, 8);
2861   auto Ptr = B.buildUndef(P0);
2862 
2863   DefineLegalizerInfo(A, {});
2864 
2865   MachineMemOperand *MMO = B.getMF().getMachineMemOperand(
2866       MachinePointerInfo(), MachineMemOperand::MOLoad, 4, Align(4));
2867   auto Load = B.buildLoad(V4S8, Ptr, *MMO);
2868 
2869   AInfo Info(MF->getSubtarget());
2870   DummyGISelObserver Observer;
2871   B.setInsertPt(*EntryMBB, Load->getIterator());
2872   LegalizerHelper Helper(*MF, Info, Observer, B);
2873   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2874             Helper.bitcast(*Load, 0, S32));
2875 
2876   auto CheckStr = R"(
2877   CHECK: [[PTR:%[0-9]+]]:_(p0) = G_IMPLICIT_DEF
2878   CHECK: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD
2879   CHECK: [[CAST:%[0-9]+]]:_(<4 x s8>) = G_BITCAST [[LOAD]]
2880 
2881   )";
2882 
2883   // Check
2884   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2885 }
2886 
2887 TEST_F(AArch64GISelMITest, BitcastStore) {
2888   setUp();
2889   if (!TM)
2890     return;
2891 
2892   LLT P0 = LLT::pointer(0, 64);
2893   LLT S32 = LLT::scalar(32);
2894   LLT V4S8 = LLT::vector(4, 8);
2895   auto Ptr = B.buildUndef(P0);
2896 
2897   DefineLegalizerInfo(A, {});
2898 
2899   MachineMemOperand *MMO = B.getMF().getMachineMemOperand(
2900       MachinePointerInfo(), MachineMemOperand::MOStore, 4, Align(4));
2901   auto Val = B.buildUndef(V4S8);
2902   auto Store = B.buildStore(Val, Ptr, *MMO);
2903 
2904   AInfo Info(MF->getSubtarget());
2905   DummyGISelObserver Observer;
2906   LegalizerHelper Helper(*MF, Info, Observer, B);
2907   B.setInsertPt(*EntryMBB, Store->getIterator());
2908   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2909             Helper.bitcast(*Store, 0, S32));
2910 
2911   auto CheckStr = R"(
2912   CHECK: [[VAL:%[0-9]+]]:_(<4 x s8>) = G_IMPLICIT_DEF
2913   CHECK: [[CAST:%[0-9]+]]:_(s32) = G_BITCAST [[VAL]]
2914   CHECK: G_STORE [[CAST]]
2915   )";
2916 
2917   // Check
2918   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2919 }
2920 
2921 TEST_F(AArch64GISelMITest, BitcastSelect) {
2922   setUp();
2923   if (!TM)
2924     return;
2925 
2926   LLT S1 = LLT::scalar(1);
2927   LLT S32 = LLT::scalar(32);
2928   LLT V4S8 = LLT::vector(4, 8);
2929 
2930   DefineLegalizerInfo(A, {});
2931 
2932   auto Cond = B.buildUndef(S1);
2933   auto Val0 = B.buildConstant(V4S8, 123);
2934   auto Val1 = B.buildConstant(V4S8, 99);
2935 
2936   auto Select = B.buildSelect(V4S8, Cond, Val0, Val1);
2937 
2938   AInfo Info(MF->getSubtarget());
2939   DummyGISelObserver Observer;
2940   LegalizerHelper Helper(*MF, Info, Observer, B);
2941   B.setInsertPt(*EntryMBB, Select->getIterator());
2942   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2943             Helper.bitcast(*Select, 0, S32));
2944 
2945   auto CheckStr = R"(
2946   CHECK: [[VAL0:%[0-9]+]]:_(<4 x s8>) = G_BUILD_VECTOR
2947   CHECK: [[VAL1:%[0-9]+]]:_(<4 x s8>) = G_BUILD_VECTOR
2948   CHECK: [[CAST0:%[0-9]+]]:_(s32) = G_BITCAST [[VAL0]]
2949   CHECK: [[CAST1:%[0-9]+]]:_(s32) = G_BITCAST [[VAL1]]
2950   CHECK: [[SELECT:%[0-9]+]]:_(s32) = G_SELECT %{{[0-9]+}}:_(s1), [[CAST0]]:_, [[CAST1]]:_
2951   CHECK: [[CAST2:%[0-9]+]]:_(<4 x s8>) = G_BITCAST [[SELECT]]
2952   )";
2953 
2954   // Check
2955   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2956 
2957   // Doesn't make sense
2958   auto VCond = B.buildUndef(LLT::vector(4, 1));
2959   auto VSelect = B.buildSelect(V4S8, VCond, Val0, Val1);
2960 
2961   B.setInsertPt(*EntryMBB, VSelect->getIterator());
2962   EXPECT_EQ(LegalizerHelper::LegalizeResult::UnableToLegalize,
2963             Helper.bitcast(*VSelect, 0, S32));
2964   EXPECT_EQ(LegalizerHelper::LegalizeResult::UnableToLegalize,
2965             Helper.bitcast(*VSelect, 1, LLT::scalar(4)));
2966 }
2967 
2968 TEST_F(AArch64GISelMITest, BitcastBitOps) {
2969   setUp();
2970   if (!TM)
2971     return;
2972 
2973   LLT S32 = LLT::scalar(32);
2974   LLT V4S8 = LLT::vector(4, 8);
2975 
2976   DefineLegalizerInfo(A, {});
2977 
2978   auto Val0 = B.buildConstant(V4S8, 123);
2979   auto Val1 = B.buildConstant(V4S8, 99);
2980   auto And = B.buildAnd(V4S8, Val0, Val1);
2981   auto Or = B.buildOr(V4S8, Val0, Val1);
2982   auto Xor = B.buildXor(V4S8, Val0, Val1);
2983 
2984   AInfo Info(MF->getSubtarget());
2985   DummyGISelObserver Observer;
2986   LegalizerHelper Helper(*MF, Info, Observer, B);
2987   B.setInsertPt(*EntryMBB, And->getIterator());
2988   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2989             Helper.bitcast(*And, 0, S32));
2990 
2991   B.setInsertPt(*EntryMBB, Or->getIterator());
2992   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2993             Helper.bitcast(*Or, 0, S32));
2994 
2995   B.setInsertPt(*EntryMBB, Xor->getIterator());
2996   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2997             Helper.bitcast(*Xor, 0, S32));
2998 
2999   auto CheckStr = R"(
3000   CHECK: [[VAL0:%[0-9]+]]:_(<4 x s8>) = G_BUILD_VECTOR
3001   CHECK: [[VAL1:%[0-9]+]]:_(<4 x s8>) = G_BUILD_VECTOR
3002   CHECK: [[CAST0:%[0-9]+]]:_(s32) = G_BITCAST [[VAL0]]
3003   CHECK: [[CAST1:%[0-9]+]]:_(s32) = G_BITCAST [[VAL1]]
3004   CHECK: [[AND:%[0-9]+]]:_(s32) = G_AND [[CAST0]]:_, [[CAST1]]:_
3005   CHECK: [[CAST_AND:%[0-9]+]]:_(<4 x s8>) = G_BITCAST [[AND]]
3006   CHECK: [[CAST2:%[0-9]+]]:_(s32) = G_BITCAST [[VAL0]]
3007   CHECK: [[CAST3:%[0-9]+]]:_(s32) = G_BITCAST [[VAL1]]
3008   CHECK: [[OR:%[0-9]+]]:_(s32) = G_OR [[CAST2]]:_, [[CAST3]]:_
3009   CHECK: [[CAST_OR:%[0-9]+]]:_(<4 x s8>) = G_BITCAST [[OR]]
3010   CHECK: [[CAST4:%[0-9]+]]:_(s32) = G_BITCAST [[VAL0]]
3011   CHECK: [[CAST5:%[0-9]+]]:_(s32) = G_BITCAST [[VAL1]]
3012   CHECK: [[XOR:%[0-9]+]]:_(s32) = G_XOR [[CAST4]]:_, [[CAST5]]:_
3013   CHECK: [[CAST_XOR:%[0-9]+]]:_(<4 x s8>) = G_BITCAST [[XOR]]
3014   )";
3015 
3016   // Check
3017   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3018 }
3019 
3020 TEST_F(AArch64GISelMITest, CreateLibcall) {
3021   setUp();
3022   if (!TM)
3023     return;
3024 
3025   DefineLegalizerInfo(A, {});
3026 
3027   AInfo Info(MF->getSubtarget());
3028   DummyGISelObserver Observer;
3029 
3030   LLVMContext &Ctx = MF->getFunction().getContext();
3031   auto *RetTy = Type::getVoidTy(Ctx);
3032 
3033   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3034             createLibcall(B, "abort", {{}, RetTy}, {}, CallingConv::C));
3035 
3036   auto CheckStr = R"(
3037   CHECK: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
3038   CHECK: BL &abort
3039   CHECK: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
3040   )";
3041 
3042   // Check
3043   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3044 }
3045 
3046 // Test narrowing of G_IMPLICIT_DEF
3047 TEST_F(AArch64GISelMITest, NarrowImplicitDef) {
3048   setUp();
3049   if (!TM)
3050     return;
3051 
3052   DefineLegalizerInfo(A, {});
3053 
3054   // Make sure that G_IMPLICIT_DEF can be narrowed if the original size is not a
3055   // multiple of narrow size
3056   LLT S32{LLT::scalar(32)};
3057   LLT S48{LLT::scalar(48)};
3058   LLT S64{LLT::scalar(64)};
3059   LLT V2S64{{LLT::vector(2, 64)}};
3060 
3061   auto Implicit1 = B.buildUndef(S64);
3062   auto Implicit2 = B.buildUndef(S64);
3063   auto Implicit3 = B.buildUndef(V2S64);
3064   auto Implicit4 = B.buildUndef(V2S64);
3065 
3066   AInfo Info(MF->getSubtarget());
3067   DummyGISelObserver Observer;
3068   LegalizerHelper Helper(*MF, Info, Observer, B);
3069 
3070   // Perform Legalization
3071 
3072   B.setInsertPt(*EntryMBB, Implicit1->getIterator());
3073   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3074             Helper.narrowScalar(*Implicit1, 0, S48));
3075 
3076   B.setInsertPt(*EntryMBB, Implicit2->getIterator());
3077   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3078             Helper.narrowScalar(*Implicit2, 0, S32));
3079 
3080   B.setInsertPt(*EntryMBB, Implicit3->getIterator());
3081   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3082             Helper.narrowScalar(*Implicit3, 0, S48));
3083 
3084   B.setInsertPt(*EntryMBB, Implicit4->getIterator());
3085   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3086             Helper.narrowScalar(*Implicit4, 0, S32));
3087 
3088   const auto *CheckStr = R"(
3089   CHECK: [[DEF:%[0-9]+]]:_(s48) = G_IMPLICIT_DEF
3090   CHECK: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[DEF]]
3091 
3092   CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
3093   CHECK: [[DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
3094   CHECK: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[DEF]]:_(s32), [[DEF1]]
3095 
3096   CHECK: [[DEF:%[0-9]+]]:_(<2 x s48>) = G_IMPLICIT_DEF
3097   CHECK: [[ANYEXT:%[0-9]+]]:_(<2 x s64>) = G_ANYEXT [[DEF]]
3098 
3099   CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
3100   CHECK: [[DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
3101   CHECK: [[DEF2:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
3102   CHECK: [[DEF3:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
3103   CHECK: [[BV:%[0-9]+]]:_(<2 x s64>) = G_BUILD_VECTOR [[DEF]]:_(s32), [[DEF1]]:_(s32), [[DEF2]]:_(s32), [[DEF3]]:_(s32)
3104   )";
3105 
3106   // Check
3107   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3108 }
3109 
3110 // Test widening of G_FREEZE
3111 TEST_F(AArch64GISelMITest, WidenFreeze) {
3112   setUp();
3113   if (!TM)
3114     return;
3115 
3116   DefineLegalizerInfo(A, {});
3117 
3118   // Make sure that G_FREEZE is widened with anyext
3119   LLT S64{LLT::scalar(64)};
3120   LLT S128{LLT::scalar(128)};
3121   LLT V2S32{LLT::vector(2, 32)};
3122   LLT V2S64{LLT::vector(2, 64)};
3123 
3124   auto Vector = B.buildBitcast(V2S32, Copies[0]);
3125 
3126   auto FreezeScalar = B.buildInstr(TargetOpcode::G_FREEZE, {S64}, {Copies[0]});
3127   auto FreezeVector = B.buildInstr(TargetOpcode::G_FREEZE, {V2S32}, {Vector});
3128 
3129   AInfo Info(MF->getSubtarget());
3130   DummyGISelObserver Observer;
3131   LegalizerHelper Helper(*MF, Info, Observer, B);
3132 
3133   // Perform Legalization
3134 
3135   B.setInsertPt(*EntryMBB, FreezeScalar->getIterator());
3136   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3137             Helper.widenScalar(*FreezeScalar, 0, S128));
3138 
3139   B.setInsertPt(*EntryMBB, FreezeVector->getIterator());
3140   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3141             Helper.widenScalar(*FreezeVector, 0, V2S64));
3142 
3143   const auto *CheckStr = R"(
3144   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
3145   CHECK: [[BITCAST:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[COPY]]
3146 
3147   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT [[COPY]]
3148   CHECK: [[FREEZE:%[0-9]+]]:_(s128) = G_FREEZE [[ANYEXT]]
3149   CHECK: [[TRUNC:%[0-9]+]]:_(s64) = G_TRUNC [[FREEZE]]
3150 
3151   CHECK: [[ANYEXT1:%[0-9]+]]:_(<2 x s64>) = G_ANYEXT [[BITCAST]]
3152   CHECK: [[FREEZE1:%[0-9]+]]:_(<2 x s64>) = G_FREEZE [[ANYEXT1]]
3153   CHECK: [[TRUNC1:%[0-9]+]]:_(<2 x s32>) = G_TRUNC [[FREEZE1]]
3154   )";
3155 
3156   // Check
3157   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3158 }
3159 
3160 // Test narrowing of G_FREEZE
3161 TEST_F(AArch64GISelMITest, NarrowFreeze) {
3162   setUp();
3163   if (!TM)
3164     return;
3165 
3166   DefineLegalizerInfo(A, {});
3167 
3168   // Make sure that G_FREEZE is narrowed using unmerge/extract
3169   LLT S16{LLT::scalar(16)};
3170   LLT S32{LLT::scalar(32)};
3171   LLT S33{LLT::scalar(33)};
3172   LLT S64{LLT::scalar(64)};
3173   LLT V2S16{LLT::vector(2, 16)};
3174   LLT V2S32{LLT::vector(2, 32)};
3175 
3176   auto Trunc = B.buildTrunc(S33, {Copies[0]});
3177   auto Vector = B.buildBitcast(V2S32, Copies[0]);
3178 
3179   auto FreezeScalar = B.buildInstr(TargetOpcode::G_FREEZE, {S64}, {Copies[0]});
3180   auto FreezeOdd = B.buildInstr(TargetOpcode::G_FREEZE, {S33}, {Trunc});
3181   auto FreezeVector = B.buildInstr(TargetOpcode::G_FREEZE, {V2S32}, {Vector});
3182   auto FreezeVector1 = B.buildInstr(TargetOpcode::G_FREEZE, {V2S32}, {Vector});
3183 
3184   AInfo Info(MF->getSubtarget());
3185   DummyGISelObserver Observer;
3186   LegalizerHelper Helper(*MF, Info, Observer, B);
3187 
3188   // Perform Legalization
3189 
3190   B.setInsertPt(*EntryMBB, FreezeScalar->getIterator());
3191   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3192             Helper.narrowScalar(*FreezeScalar, 0, S32));
3193 
3194   B.setInsertPt(*EntryMBB, FreezeOdd->getIterator());
3195   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3196             Helper.narrowScalar(*FreezeOdd, 0, S32));
3197 
3198   B.setInsertPt(*EntryMBB, FreezeVector->getIterator());
3199   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3200             Helper.narrowScalar(*FreezeVector, 0, V2S16));
3201 
3202   B.setInsertPt(*EntryMBB, FreezeVector1->getIterator());
3203   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3204             Helper.narrowScalar(*FreezeVector1, 0, S16));
3205 
3206   const auto *CheckStr = R"(
3207   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
3208   CHECK: [[TRUNC:%[0-9]+]]:_(s33) = G_TRUNC [[COPY]]
3209   CHECK: [[BITCAST:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[COPY]]
3210 
3211   CHECK: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[COPY]]
3212   CHECK: [[FREEZE:%[0-9]+]]:_(s32) = G_FREEZE [[UV]]
3213   CHECK: [[FREEZE1:%[0-9]+]]:_(s32) = G_FREEZE [[UV1]]
3214   CHECK: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[FREEZE]]:_(s32), [[FREEZE1]]
3215 
3216   CHECK: (s1) = G_UNMERGE_VALUES [[TRUNC]]:_(s33)
3217   CHECK: [[UNDEF:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF
3218   CHECK: [[MV1:%[0-9]+]]:_(s32) = G_MERGE_VALUES
3219   CHECK: [[MV2:%[0-9]+]]:_(s32) = G_MERGE_VALUES
3220   CHECK: [[UNDEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
3221   CHECK: [[FREEZE2:%[0-9]+]]:_(s32) = G_FREEZE [[MV1]]
3222   CHECK: [[FREEZE3:%[0-9]+]]:_(s32) = G_FREEZE [[MV2]]
3223   CHECK: [[UNDEF2:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
3224   CHECK: [[MV3:%[0-9]+]]:_(s1056) = G_MERGE_VALUES [[FREEZE2]]:_(s32), [[FREEZE3]]:_(s32), [[UNDEF2]]
3225   CHECK: [[TRUNC1:%[0-9]+]]:_(s33) = G_TRUNC [[MV3]]
3226 
3227   CHECK: [[BITCAST1:%[0-9]+]]:_(s64) = G_BITCAST [[BITCAST]]
3228   CHECK: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[BITCAST1]]
3229   CHECK: [[FREEZE4:%[0-9]+]]:_(s32) = G_FREEZE [[UV2]]
3230   CHECK: [[FREEZE5:%[0-9]+]]:_(s32) = G_FREEZE [[UV3]]
3231   CHECK: [[MV4:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[FREEZE4]]:_(s32), [[FREEZE5]]:_(s32)
3232   CHECK: [[BITCAST2:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[MV4]]
3233 
3234   CHECK: [[BITCAST3:%[0-9]+]]:_(s64) = G_BITCAST [[BITCAST]]
3235   CHECK: [[UV4:%[0-9]+]]:_(s16), [[UV5:%[0-9]+]]:_(s16), [[UV6:%[0-9]+]]:_(s16), [[UV7:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[BITCAST3]]
3236   CHECK: [[FREEZE6:%[0-9]+]]:_(s16) = G_FREEZE [[UV4]]
3237   CHECK: [[FREEZE7:%[0-9]+]]:_(s16) = G_FREEZE [[UV5]]
3238   CHECK: [[FREEZE8:%[0-9]+]]:_(s16) = G_FREEZE [[UV6]]
3239   CHECK: [[FREEZE9:%[0-9]+]]:_(s16) = G_FREEZE [[UV7]]
3240   CHECK: [[MV5:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[FREEZE6]]:_(s16), [[FREEZE7]]:_(s16), [[FREEZE8]]:_(s16), [[FREEZE9]]
3241   CHECK: [[BITCAST3:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[MV5]]
3242   )";
3243 
3244   // Check
3245   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3246 }
3247 
3248 // Test fewer elements of G_FREEZE
3249 TEST_F(AArch64GISelMITest, FewerElementsFreeze) {
3250   setUp();
3251   if (!TM)
3252     return;
3253 
3254   DefineLegalizerInfo(A, {});
3255 
3256   LLT S32{LLT::scalar(32)};
3257   LLT V2S16{LLT::vector(2, 16)};
3258   LLT V2S32{LLT::vector(2, 32)};
3259   LLT V4S16{LLT::vector(4, 16)};
3260 
3261   auto Vector1 = B.buildBitcast(V2S32, Copies[0]);
3262   auto Vector2 = B.buildBitcast(V4S16, Copies[0]);
3263 
3264   auto FreezeVector1 = B.buildInstr(TargetOpcode::G_FREEZE, {V2S32}, {Vector1});
3265   auto FreezeVector2 = B.buildInstr(TargetOpcode::G_FREEZE, {V4S16}, {Vector2});
3266 
3267   AInfo Info(MF->getSubtarget());
3268   DummyGISelObserver Observer;
3269   LegalizerHelper Helper(*MF, Info, Observer, B);
3270 
3271   // Perform Legalization
3272 
3273   B.setInsertPt(*EntryMBB, FreezeVector1->getIterator());
3274   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3275             Helper.fewerElementsVector(*FreezeVector1, 0, S32));
3276 
3277   B.setInsertPt(*EntryMBB, FreezeVector2->getIterator());
3278   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3279             Helper.fewerElementsVector(*FreezeVector2, 0, V2S16));
3280 
3281   const auto *CheckStr = R"(
3282   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
3283   CHECK: [[BITCAST:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[COPY]]
3284   CHECK: [[BITCAST1:%[0-9]+]]:_(<4 x s16>) = G_BITCAST [[COPY]]
3285 
3286   CHECK: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[BITCAST]]
3287   CHECK: [[FREEZE:%[0-9]+]]:_(s32) = G_FREEZE [[UV]]
3288   CHECK: [[FREEZE1:%[0-9]+]]:_(s32) = G_FREEZE [[UV1]]
3289   CHECK: [[MV:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[FREEZE]]:_(s32), [[FREEZE1]]
3290 
3291   CHECK: [[UV:%[0-9]+]]:_(<2 x s16>), [[UV1:%[0-9]+]]:_(<2 x s16>) = G_UNMERGE_VALUES [[BITCAST1]]
3292   CHECK: [[FREEZE2:%[0-9]+]]:_(<2 x s16>) = G_FREEZE [[UV]]
3293   CHECK: [[FREEZE3:%[0-9]+]]:_(<2 x s16>) = G_FREEZE [[UV1]]
3294   CHECK: [[MV:%[0-9]+]]:_(<4 x s16>) = G_CONCAT_VECTORS [[FREEZE2]]:_(<2 x s16>), [[FREEZE3]]
3295   )";
3296 
3297   // Check
3298   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3299 }
3300 
3301 // Test more elements of G_FREEZE
3302 TEST_F(AArch64GISelMITest, MoreElementsFreeze) {
3303   setUp();
3304   if (!TM)
3305     return;
3306 
3307   DefineLegalizerInfo(A, {});
3308 
3309   LLT V2S32{LLT::vector(2, 32)};
3310   LLT V4S32{LLT::vector(4, 32)};
3311 
3312   auto Vector1 = B.buildBitcast(V2S32, Copies[0]);
3313   auto FreezeVector1 = B.buildInstr(TargetOpcode::G_FREEZE, {V2S32}, {Vector1});
3314 
3315   AInfo Info(MF->getSubtarget());
3316   DummyGISelObserver Observer;
3317   LegalizerHelper Helper(*MF, Info, Observer, B);
3318 
3319   // Perform Legalization
3320   B.setInsertPt(*EntryMBB, FreezeVector1->getIterator());
3321   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3322             Helper.moreElementsVector(*FreezeVector1, 0, V4S32));
3323 
3324   const auto *CheckStr = R"(
3325   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
3326   CHECK: [[BITCAST:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[COPY]]
3327   CHECK: [[UNDEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
3328   CHECK: [[CV:%[0-9]+]]:_(<4 x s32>) = G_CONCAT_VECTORS [[BITCAST]]:_(<2 x s32>), [[UNDEF]]
3329   CHECK: [[FREEZE:%[0-9]+]]:_(<4 x s32>) = G_FREEZE [[CV]]
3330   CHECK: [[EXTR0:%[0-9]+]]:_(<2 x s32>), [[EXTR1:%[0-9]+]]:_(<2 x s32>) = G_UNMERGE_VALUES [[FREEZE]]:_(<4 x s32>)
3331   )";
3332 
3333   // Check
3334   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3335 }
3336 
3337 // Test fewer elements of G_INSERT_VECTOR_ELEMENT
3338 TEST_F(AArch64GISelMITest, FewerElementsInsertVectorElt) {
3339   setUp();
3340   if (!TM)
3341     return;
3342 
3343   DefineLegalizerInfo(A, {});
3344 
3345   LLT P0{LLT::pointer(0, 64)};
3346   LLT S64{LLT::scalar(64)};
3347   LLT S16{LLT::scalar(16)};
3348   LLT V2S16{LLT::vector(2, 16)};
3349   LLT V3S16{LLT::vector(3, 16)};
3350   LLT V8S16{LLT::vector(8, 16)};
3351 
3352   auto Ptr0 = B.buildIntToPtr(P0, Copies[0]);
3353   auto VectorV8 = B.buildLoad(V8S16, Ptr0, MachinePointerInfo(), Align(8));
3354   auto Value = B.buildTrunc(S16, Copies[1]);
3355 
3356   auto Seven = B.buildConstant(S64, 7);
3357   auto InsertV8Constant7_0 =
3358       B.buildInsertVectorElement(V8S16, VectorV8, Value, Seven);
3359   auto InsertV8Constant7_1 =
3360       B.buildInsertVectorElement(V8S16, VectorV8, Value, Seven);
3361 
3362   B.buildStore(InsertV8Constant7_0, Ptr0, MachinePointerInfo(), Align(8),
3363                MachineMemOperand::MOVolatile);
3364   B.buildStore(InsertV8Constant7_1, Ptr0, MachinePointerInfo(), Align(8),
3365                MachineMemOperand::MOVolatile);
3366 
3367   AInfo Info(MF->getSubtarget());
3368   DummyGISelObserver Observer;
3369   LegalizerHelper Helper(*MF, Info, Observer, B);
3370 
3371   // Perform Legalization
3372   B.setInsertPt(*EntryMBB, InsertV8Constant7_0->getIterator());
3373 
3374   // This should index the high element of the 4th piece of an unmerge.
3375   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3376             Helper.fewerElementsVector(*InsertV8Constant7_0, 0, V2S16));
3377 
3378   // This case requires extracting an intermediate vector type into the target
3379   // v4s16.
3380   B.setInsertPt(*EntryMBB, InsertV8Constant7_1->getIterator());
3381   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3382             Helper.fewerElementsVector(*InsertV8Constant7_1, 0, V3S16));
3383 
3384   const auto *CheckStr = R"(
3385   CHECK: [[COPY0:%[0-9]+]]:_(s64) = COPY
3386   CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY
3387   CHECK: [[COPY2:%[0-9]+]]:_(s64) = COPY
3388   CHECK: [[PTR0:%[0-9]+]]:_(p0) = G_INTTOPTR [[COPY0]]
3389   CHECK: [[VEC8:%[0-9]+]]:_(<8 x s16>) = G_LOAD [[PTR0]]:_(p0) :: (load 16, align 8)
3390   CHECK: [[INSERT_VAL:%[0-9]+]]:_(s16) = G_TRUNC [[COPY1]]
3391 
3392 
3393   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]]
3394   CHECK: [[ONE:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
3395   CHECK: [[SUB_INSERT_7:%[0-9]+]]:_(<2 x s16>) = G_INSERT_VECTOR_ELT [[UNMERGE3]]:_, [[INSERT_VAL]]:_(s16), [[ONE]]
3396   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>)
3397 
3398 
3399   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>)
3400   CHECK: [[IMPDEF_S16:%[0-9]+]]:_(s16) = G_IMPLICIT_DEF
3401   CHECK: [[BUILD0:%[0-9]+]]:_(<3 x s16>) = G_BUILD_VECTOR [[UNMERGE1_0]]:_(s16), [[UNMERGE1_1]]:_(s16), [[UNMERGE1_2]]:_(s16)
3402   CHECK: [[BUILD1:%[0-9]+]]:_(<3 x s16>) = G_BUILD_VECTOR [[UNMERGE1_3]]:_(s16), [[UNMERGE1_4]]:_(s16), [[UNMERGE1_5]]:_(s16)
3403   CHECK: [[BUILD2:%[0-9]+]]:_(<3 x s16>) = G_BUILD_VECTOR [[UNMERGE1_6]]:_(s16), [[UNMERGE1_7]]:_(s16), [[IMPDEF_S16]]:_(s16)
3404   CHECK: [[IMPDEF_V3S16:%[0-9]+]]:_(<3 x s16>) = G_IMPLICIT_DEF
3405   CHECK: [[ONE_1:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
3406   CHECK: [[SUB_INSERT_7_V3S16:%[0-9]+]]:_(<3 x s16>) = G_INSERT_VECTOR_ELT [[BUILD2]]:_, [[INSERT_VAL]]:_(s16), [[ONE_1]]
3407 
3408   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>)
3409   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>)
3410   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>)
3411 
3412 
3413   CHECK: G_STORE [[INSERT_V8_7_0]]
3414   CHECK: G_STORE [[INSERT_V8_7_1]]
3415   )";
3416 
3417   // Check
3418   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3419 }
3420 
3421 // Test widen scalar of G_UNMERGE_VALUES
3422 TEST_F(AArch64GISelMITest, widenScalarUnmerge) {
3423   setUp();
3424   if (!TM)
3425     return;
3426 
3427   DefineLegalizerInfo(A, {});
3428 
3429   LLT S96{LLT::scalar(96)};
3430   LLT S64{LLT::scalar(64)};
3431   LLT S48{LLT::scalar(48)};
3432 
3433   auto Src = B.buildAnyExt(S96, Copies[0]);
3434   auto Unmerge = B.buildUnmerge(S48, Src);
3435 
3436   AInfo Info(MF->getSubtarget());
3437   DummyGISelObserver Observer;
3438   LegalizerHelper Helper(*MF, Info, Observer, B);
3439 
3440   // Perform Legalization
3441   B.setInsertPt(*EntryMBB, Unmerge->getIterator());
3442 
3443   // This should create unmerges to a GCD type (S16), then remerge to S48
3444   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3445             Helper.widenScalar(*Unmerge, 0, S64));
3446 
3447   const auto *CheckStr = R"(
3448   CHECK: [[COPY0:%[0-9]+]]:_(s64) = COPY
3449   CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY
3450   CHECK: [[COPY2:%[0-9]+]]:_(s64) = COPY
3451   CHECK: [[ANYEXT:%[0-9]+]]:_(s96) = G_ANYEXT [[COPY0]]
3452   CHECK: [[ANYEXT1:%[0-9]+]]:_(s192) = G_ANYEXT [[ANYEXT]]
3453   CHECK: [[UNMERGE:%[0-9]+]]:_(s64), [[UNMERGE1:%[0-9]+]]:_(s64), [[UNMERGE2:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[ANYEXT1]]
3454   CHECK: [[UNMERGE3:%[0-9]+]]:_(s16), [[UNMERGE4:%[0-9]+]]:_(s16), [[UNMERGE5:%[0-9]+]]:_(s16), [[UNMERGE6:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[UNMERGE]]
3455   CHECK: [[UNMERGE7:%[0-9]+]]:_(s16), [[UNMERGE8:%[0-9]+]]:_(s16), [[UNMERGE9:%[0-9]+]]:_(s16), [[UNMERGE10:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[UNMERGE1]]
3456   CHECK: [[UNMERGE11:%[0-9]+]]:_(s16), [[UNMERGE12:%[0-9]+]]:_(s16), [[UNMERGE13:%[0-9]+]]:_(s16), [[UNMERGE14:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[UNMERGE2]]
3457   CHECK: [[MERGE:%[0-9]+]]:_(s48) = G_MERGE_VALUES [[UNMERGE3]]:_(s16), [[UNMERGE4]]:_(s16), [[UNMERGE5]]:_(s16)
3458   CHECK: [[MERGE1:%[0-9]+]]:_(s48) = G_MERGE_VALUES [[UNMERGE6]]:_(s16), [[UNMERGE7]]:_(s16), [[UNMERGE8]]:_(s16)
3459   )";
3460 
3461   // Check
3462   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3463 }
3464 
3465 } // namespace
3466