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