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