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