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