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