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