xref: /llvm-project/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp (revision f95a5fbe7ce1ddc890868a2b4720b4561af672cf)
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   Register 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   Register 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   Register 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   Register 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, WidenUMULOCondition) {
1041   setUp();
1042   if (!TM)
1043     return;
1044 
1045   // Declare your legalization info
1046   DefineLegalizerInfo(A, {
1047     getActionDefinitionsBuilder(G_ADD).legalFor({{s16, s16}});
1048   });
1049 
1050   LLT s32 = LLT::scalar(32);
1051   LLT s64 = LLT::scalar(64);
1052 
1053   auto UMulo =
1054     B.buildInstr(TargetOpcode::G_UMULO, {s64, LLT::scalar(1)},
1055                  {Copies[0], Copies[1]});
1056   AInfo Info(MF->getSubtarget());
1057   DummyGISelObserver Observer;
1058   LegalizerHelper Helper(*MF, Info, Observer, B);
1059 
1060   B.setInstrAndDebugLoc(*UMulo);
1061   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1062             Helper.widenScalar(*UMulo, 1, s32));
1063 
1064   auto CheckStr = R"(
1065   CHECK: [[COPY0:%[0-9]+]]:_(s64) = COPY
1066   CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY
1067   CHECK: [[ADD:%[0-9]+]]:_(s64), [[OVERFLOW:%[0-9]+]]:_(s32) = G_UMULO [[COPY0]]:_, [[COPY1]]:_
1068   CHECK: {{[0-9]+}}:_(s1) = G_TRUNC [[OVERFLOW]]
1069   )";
1070 
1071   // Check
1072   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1073 }
1074 
1075 TEST_F(AArch64GISelMITest, NarrowUADDO) {
1076   setUp();
1077   if (!TM)
1078     return;
1079 
1080   LLT S1 = LLT::scalar(1);
1081   LLT S32 = LLT::scalar(32);
1082   LLT S96 = LLT::scalar(96);
1083   DefineLegalizerInfo(A, {
1084     getActionDefinitionsBuilder({G_UADDO, G_UADDE})
1085         .legalFor({{LLT::scalar(32), LLT::scalar(1)}});
1086   });
1087 
1088   auto Op0 = B.buildUndef(S96);
1089   auto Op1 = B.buildUndef(S96);
1090   auto UADDO = B.buildUAddo(S96, S1, Op0, Op1);
1091 
1092   AInfo Info(MF->getSubtarget());
1093   DummyGISelObserver Observer;
1094   LegalizerHelper Helper(*MF, Info, Observer, B);
1095   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1096             Helper.narrowScalar(*UADDO, 0, S32));
1097 
1098   const char *CheckStr = R"(
1099   CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
1100   CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
1101   CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]]
1102   CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]]
1103   CHECK: [[UADDO0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_UADDO [[OP0_0]]:_, [[OP1_0]]:_
1104   CHECK: [[UADDO1:%[0-9]+]]:_(s32), [[CARRY1:%[0-9]+]]:_(s1) = G_UADDE [[OP0_1]]:_, [[OP1_1]]:_, [[CARRY0]]:_
1105   CHECK: [[UADDO2:%[0-9]+]]:_(s32), [[CARRY2:%[0-9]+]]:_(s1) = G_UADDE [[OP0_2]]:_, [[OP1_2]]:_, [[CARRY1]]:_
1106   CHECK: [[UADDO:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[UADDO0]]:_(s32), [[UADDO1]]:_(s32), [[UADDO2]]:_(s32)
1107   )";
1108 
1109   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1110 }
1111 
1112 TEST_F(AArch64GISelMITest, NarrowUSUBO) {
1113   setUp();
1114   if (!TM)
1115     return;
1116 
1117   LLT S1 = LLT::scalar(1);
1118   LLT S32 = LLT::scalar(32);
1119   LLT S96 = LLT::scalar(96);
1120   DefineLegalizerInfo(A, {
1121     getActionDefinitionsBuilder({G_USUBO, G_USUBE})
1122         .legalFor({{LLT::scalar(32), LLT::scalar(1)}});
1123   });
1124 
1125   auto Op0 = B.buildUndef(S96);
1126   auto Op1 = B.buildUndef(S96);
1127   auto USUBO = B.buildUSubo(S96, S1, Op0, Op1);
1128 
1129   AInfo Info(MF->getSubtarget());
1130   DummyGISelObserver Observer;
1131   LegalizerHelper Helper(*MF, Info, Observer, B);
1132   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1133             Helper.narrowScalar(*USUBO, 0, S32));
1134 
1135   const char *CheckStr = R"(
1136   CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
1137   CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
1138   CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]]
1139   CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]]
1140   CHECK: [[USUBO0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_USUBO [[OP0_0]]:_, [[OP1_0]]:_
1141   CHECK: [[USUBO1:%[0-9]+]]:_(s32), [[CARRY1:%[0-9]+]]:_(s1) = G_USUBE [[OP0_1]]:_, [[OP1_1]]:_, [[CARRY0]]:_
1142   CHECK: [[USUBO2:%[0-9]+]]:_(s32), [[CARRY2:%[0-9]+]]:_(s1) = G_USUBE [[OP0_2]]:_, [[OP1_2]]:_, [[CARRY1]]:_
1143   CHECK: [[USUBO:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[USUBO0]]:_(s32), [[USUBO1]]:_(s32), [[USUBO2]]:_(s32)
1144   )";
1145 
1146   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1147 }
1148 
1149 TEST_F(AArch64GISelMITest, NarrowSADDO) {
1150   setUp();
1151   if (!TM)
1152     return;
1153 
1154   LLT S1 = LLT::scalar(1);
1155   LLT S32 = LLT::scalar(32);
1156   LLT S96 = LLT::scalar(96);
1157   DefineLegalizerInfo(A, {
1158     getActionDefinitionsBuilder({G_UADDO, G_UADDE, G_SADDE})
1159         .legalFor({{LLT::scalar(32), LLT::scalar(1)}});
1160   });
1161 
1162   auto Op0 = B.buildUndef(S96);
1163   auto Op1 = B.buildUndef(S96);
1164   auto SADDO = B.buildSAddo(S96, S1, Op0, Op1);
1165 
1166   AInfo Info(MF->getSubtarget());
1167   DummyGISelObserver Observer;
1168   LegalizerHelper Helper(*MF, Info, Observer, B);
1169   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1170             Helper.narrowScalar(*SADDO, 0, S32));
1171 
1172   const char *CheckStr = R"(
1173   CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
1174   CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
1175   CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]]
1176   CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]]
1177   CHECK: [[SADDO0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_UADDO [[OP0_0]]:_, [[OP1_0]]:_
1178   CHECK: [[SADDO1:%[0-9]+]]:_(s32), [[CARRY1:%[0-9]+]]:_(s1) = G_UADDE [[OP0_1]]:_, [[OP1_1]]:_, [[CARRY0]]:_
1179   CHECK: [[SADDO2:%[0-9]+]]:_(s32), [[CARRY2:%[0-9]+]]:_(s1) = G_SADDE [[OP0_2]]:_, [[OP1_2]]:_, [[CARRY1]]:_
1180   CHECK: [[SADDO:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[SADDO0]]:_(s32), [[SADDO1]]:_(s32), [[SADDO2]]:_(s32)
1181   )";
1182 
1183   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1184 }
1185 
1186 TEST_F(AArch64GISelMITest, NarrowSSUBO) {
1187   setUp();
1188   if (!TM)
1189     return;
1190 
1191   LLT S1 = LLT::scalar(1);
1192   LLT S32 = LLT::scalar(32);
1193   LLT S96 = LLT::scalar(96);
1194   DefineLegalizerInfo(A, {
1195     getActionDefinitionsBuilder({G_USUBO, G_USUBE, G_SSUBE})
1196         .legalFor({{LLT::scalar(32), LLT::scalar(1)}});
1197   });
1198 
1199   auto Op0 = B.buildUndef(S96);
1200   auto Op1 = B.buildUndef(S96);
1201   auto SSUBO = B.buildSSubo(S96, S1, Op0, Op1);
1202 
1203   AInfo Info(MF->getSubtarget());
1204   DummyGISelObserver Observer;
1205   LegalizerHelper Helper(*MF, Info, Observer, B);
1206   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1207             Helper.narrowScalar(*SSUBO, 0, S32));
1208 
1209   const char *CheckStr = R"(
1210   CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
1211   CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
1212   CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]]
1213   CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]]
1214   CHECK: [[SSUBO0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_USUBO [[OP0_0]]:_, [[OP1_0]]:_
1215   CHECK: [[SSUBO1:%[0-9]+]]:_(s32), [[CARRY1:%[0-9]+]]:_(s1) = G_USUBE [[OP0_1]]:_, [[OP1_1]]:_, [[CARRY0]]:_
1216   CHECK: [[SSUBO2:%[0-9]+]]:_(s32), [[CARRY2:%[0-9]+]]:_(s1) = G_SSUBE [[OP0_2]]:_, [[OP1_2]]:_, [[CARRY1]]:_
1217   CHECK: [[SSUBO:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[SSUBO0]]:_(s32), [[SSUBO1]]:_(s32), [[SSUBO2]]:_(s32)
1218   )";
1219 
1220   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1221 }
1222 
1223 TEST_F(AArch64GISelMITest, NarrowUADDE) {
1224   setUp();
1225   if (!TM)
1226     return;
1227 
1228   LLT S1 = LLT::scalar(1);
1229   LLT S32 = LLT::scalar(32);
1230   LLT S96 = LLT::scalar(96);
1231   DefineLegalizerInfo(A, {
1232     getActionDefinitionsBuilder(G_UADDE).legalFor(
1233         {{LLT::scalar(32), LLT::scalar(1)}});
1234   });
1235 
1236   auto Op0 = B.buildUndef(S96);
1237   auto Op1 = B.buildUndef(S96);
1238   auto Op2 = B.buildUndef(S1);
1239   auto UADDE = B.buildUAdde(S96, S1, Op0, Op1, Op2);
1240 
1241   AInfo Info(MF->getSubtarget());
1242   DummyGISelObserver Observer;
1243   LegalizerHelper Helper(*MF, Info, Observer, B);
1244   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1245             Helper.narrowScalar(*UADDE, 0, S32));
1246 
1247   const char *CheckStr = R"(
1248   CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
1249   CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
1250   CHECK: [[IMP_DEF2:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF
1251   CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]]
1252   CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]]
1253   CHECK: [[UADDE0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_UADDE [[OP0_0]]:_, [[OP1_0]]:_, [[IMP_DEF2]]:_
1254   CHECK: [[UADDE1:%[0-9]+]]:_(s32), [[CARRY1:%[0-9]+]]:_(s1) = G_UADDE [[OP0_1]]:_, [[OP1_1]]:_, [[CARRY0]]:_
1255   CHECK: [[UADDE2:%[0-9]+]]:_(s32), [[CARRY2:%[0-9]+]]:_(s1) = G_UADDE [[OP0_2]]:_, [[OP1_2]]:_, [[CARRY1]]:_
1256   CHECK: [[UADDE:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[UADDE0]]:_(s32), [[UADDE1]]:_(s32), [[UADDE2]]:_(s32)
1257   )";
1258 
1259   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1260 }
1261 
1262 TEST_F(AArch64GISelMITest, NarrowUSUBE) {
1263   setUp();
1264   if (!TM)
1265     return;
1266 
1267   LLT S1 = LLT::scalar(1);
1268   LLT S32 = LLT::scalar(32);
1269   LLT S96 = LLT::scalar(96);
1270   DefineLegalizerInfo(A, {
1271     getActionDefinitionsBuilder(G_USUBE).legalFor(
1272         {{LLT::scalar(32), LLT::scalar(1)}});
1273   });
1274 
1275   auto Op0 = B.buildUndef(S96);
1276   auto Op1 = B.buildUndef(S96);
1277   auto Op2 = B.buildUndef(S1);
1278   auto USUBE = B.buildUSube(S96, S1, Op0, Op1, Op2);
1279 
1280   AInfo Info(MF->getSubtarget());
1281   DummyGISelObserver Observer;
1282   LegalizerHelper Helper(*MF, Info, Observer, B);
1283   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1284             Helper.narrowScalar(*USUBE, 0, S32));
1285 
1286   const char *CheckStr = R"(
1287   CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
1288   CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
1289   CHECK: [[IMP_DEF2:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF
1290   CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]]
1291   CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]]
1292   CHECK: [[USUBE0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_USUBE [[OP0_0]]:_, [[OP1_0]]:_, [[IMP_DEF2]]:_
1293   CHECK: [[USUBE1:%[0-9]+]]:_(s32), [[CARRY1:%[0-9]+]]:_(s1) = G_USUBE [[OP0_1]]:_, [[OP1_1]]:_, [[CARRY0]]:_
1294   CHECK: [[USUBE2:%[0-9]+]]:_(s32), [[CARRY2:%[0-9]+]]:_(s1) = G_USUBE [[OP0_2]]:_, [[OP1_2]]:_, [[CARRY1]]:_
1295   CHECK: [[USUBE:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[USUBE0]]:_(s32), [[USUBE1]]:_(s32), [[USUBE2]]:_(s32)
1296   )";
1297 
1298   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1299 }
1300 
1301 TEST_F(AArch64GISelMITest, NarrowSADDE) {
1302   setUp();
1303   if (!TM)
1304     return;
1305 
1306   LLT S1 = LLT::scalar(1);
1307   LLT S32 = LLT::scalar(32);
1308   LLT S96 = LLT::scalar(96);
1309   DefineLegalizerInfo(A, {
1310     getActionDefinitionsBuilder({G_SADDE, G_UADDE})
1311         .legalFor({{LLT::scalar(32), LLT::scalar(1)}});
1312   });
1313 
1314   auto Op0 = B.buildUndef(S96);
1315   auto Op1 = B.buildUndef(S96);
1316   auto Op2 = B.buildUndef(S1);
1317   auto SADDE = B.buildSAdde(S96, S1, Op0, Op1, Op2);
1318 
1319   AInfo Info(MF->getSubtarget());
1320   DummyGISelObserver Observer;
1321   LegalizerHelper Helper(*MF, Info, Observer, B);
1322   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1323             Helper.narrowScalar(*SADDE, 0, S32));
1324 
1325   const char *CheckStr = R"(
1326   CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
1327   CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
1328   CHECK: [[IMP_DEF2:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF
1329   CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]]
1330   CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]]
1331   CHECK: [[SADDE0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_UADDE [[OP0_0]]:_, [[OP1_0]]:_, [[IMP_DEF2]]:_
1332   CHECK: [[SADDE1:%[0-9]+]]:_(s32), [[CARRY1:%[0-9]+]]:_(s1) = G_UADDE [[OP0_1]]:_, [[OP1_1]]:_, [[CARRY0]]:_
1333   CHECK: [[SADDE2:%[0-9]+]]:_(s32), [[CARRY2:%[0-9]+]]:_(s1) = G_SADDE [[OP0_2]]:_, [[OP1_2]]:_, [[CARRY1]]:_
1334   CHECK: [[SADDE:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[SADDE0]]:_(s32), [[SADDE1]]:_(s32), [[SADDE2]]:_(s32)
1335   )";
1336 
1337   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1338 }
1339 
1340 TEST_F(AArch64GISelMITest, NarrowSSUBE) {
1341   setUp();
1342   if (!TM)
1343     return;
1344 
1345   LLT S1 = LLT::scalar(1);
1346   LLT S32 = LLT::scalar(32);
1347   LLT S96 = LLT::scalar(96);
1348   DefineLegalizerInfo(A, {
1349     getActionDefinitionsBuilder({G_SSUBE, G_USUBE})
1350         .legalFor({{LLT::scalar(32), LLT::scalar(1)}});
1351   });
1352 
1353   auto Op0 = B.buildUndef(S96);
1354   auto Op1 = B.buildUndef(S96);
1355   auto Op2 = B.buildUndef(S1);
1356   auto SSUBE = B.buildSSube(S96, S1, Op0, Op1, Op2);
1357 
1358   AInfo Info(MF->getSubtarget());
1359   DummyGISelObserver Observer;
1360   LegalizerHelper Helper(*MF, Info, Observer, B);
1361   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1362             Helper.narrowScalar(*SSUBE, 0, S32));
1363 
1364   const char *CheckStr = R"(
1365   CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
1366   CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
1367   CHECK: [[IMP_DEF2:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF
1368   CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]]
1369   CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]]
1370   CHECK: [[SSUBE0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_USUBE [[OP0_0]]:_, [[OP1_0]]:_, [[IMP_DEF2]]:_
1371   CHECK: [[SSUBE1:%[0-9]+]]:_(s32), [[CARRY1:%[0-9]+]]:_(s1) = G_USUBE [[OP0_1]]:_, [[OP1_1]]:_, [[CARRY0]]:_
1372   CHECK: [[SSUBE2:%[0-9]+]]:_(s32), [[CARRY2:%[0-9]+]]:_(s1) = G_SSUBE [[OP0_2]]:_, [[OP1_2]]:_, [[CARRY1]]:_
1373   CHECK: [[SSUBE:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[SSUBE0]]:_(s32), [[SSUBE1]]:_(s32), [[SSUBE2]]:_(s32)
1374   )";
1375 
1376   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1377 }
1378 
1379 TEST_F(AArch64GISelMITest, FewerElementsAnd) {
1380   setUp();
1381   if (!TM)
1382     return;
1383 
1384   const LLT V2S32 = LLT::fixed_vector(2, 32);
1385   const LLT V5S32 = LLT::fixed_vector(5, 32);
1386 
1387   // Declare your legalization info
1388   DefineLegalizerInfo(A, {
1389     getActionDefinitionsBuilder(G_AND)
1390       .legalFor({s32});
1391   });
1392 
1393   auto Op0 = B.buildUndef(V5S32);
1394   auto Op1 = B.buildUndef(V5S32);
1395   auto And = B.buildAnd(V5S32, Op0, Op1);
1396 
1397   AInfo Info(MF->getSubtarget());
1398   DummyGISelObserver Observer;
1399   LegalizerHelper Helper(*MF, Info, Observer, B);
1400   B.setInstr(*And);
1401   EXPECT_TRUE(Helper.fewerElementsVector(*And, 0, V2S32) ==
1402               LegalizerHelper::LegalizeResult::Legalized);
1403 
1404   auto CheckStr = R"(
1405   CHECK: [[IMP_DEF0:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF
1406   CHECK: [[IMP_DEF1:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF
1407   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>)
1408   CHECK: [[VECTOR0:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[VALUE0]]:_(s32), [[VALUE1]]:_(s32)
1409   CHECK: [[VECTOR1:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[VALUE2]]:_(s32), [[VALUE3]]:_(s32)
1410   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>)
1411   CHECK: [[VECTOR2:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[VALUE5]]:_(s32), [[VALUE6]]:_(s32)
1412   CHECK: [[VECTOR3:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[VALUE7]]:_(s32), [[VALUE8]]:_(s32)
1413   CHECK: [[AND0:%[0-9]+]]:_(<2 x s32>) = G_AND [[VECTOR0]]:_, [[VECTOR2]]:_
1414   CHECK: [[AND1:%[0-9]+]]:_(<2 x s32>) = G_AND [[VECTOR1]]:_, [[VECTOR3]]:_
1415   CHECK: [[AND2:%[0-9]+]]:_(s32) = G_AND [[VALUE4]]:_, [[VALUE9]]:_
1416   CHECK: [[AND0_E0:%[0-9]+]]:_(s32), [[AND0_E1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[AND0]]:_(<2 x s32>)
1417   CHECK: [[AND1_E0:%[0-9]+]]:_(s32), [[AND1_E1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[AND1]]:_(<2 x s32>)
1418   CHECK: [[RESULT:%[0-9]+]]:_(<5 x s32>) = G_BUILD_VECTOR [[AND0_E0]]:_(s32), [[AND0_E1]]:_(s32), [[AND1_E0]]:_(s32), [[AND1_E1]]:_(s32), [[AND2]]:_(s32)
1419   )";
1420 
1421   // Check
1422   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1423 }
1424 
1425 TEST_F(AArch64GISelMITest, MoreElementsAnd) {
1426   setUp();
1427   if (!TM)
1428     return;
1429 
1430   LLT s32 = LLT::scalar(32);
1431   LLT v2s32 = LLT::fixed_vector(2, 32);
1432   LLT v6s32 = LLT::fixed_vector(6, 32);
1433 
1434   LegalizerInfo LI;
1435   LI.getActionDefinitionsBuilder(TargetOpcode::G_AND)
1436     .legalFor({v6s32})
1437     .clampMinNumElements(0, s32, 6);
1438   LI.getLegacyLegalizerInfo().computeTables();
1439 
1440   DummyGISelObserver Observer;
1441   LegalizerHelper Helper(*MF, LI, Observer, B);
1442 
1443   B.setInsertPt(*EntryMBB, EntryMBB->end());
1444 
1445   auto Val0 = B.buildBitcast(v2s32, Copies[0]);
1446   auto Val1 = B.buildBitcast(v2s32, Copies[1]);
1447 
1448   auto And = B.buildAnd(v2s32, Val0, Val1);
1449 
1450   B.setInstr(*And);
1451   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1452             Helper.moreElementsVector(*And, 0, v6s32));
1453 
1454   auto CheckStr = R"(
1455   CHECK: [[BITCAST0:%[0-9]+]]:_(<2 x s32>) = G_BITCAST
1456   CHECK: [[BITCAST1:%[0-9]+]]:_(<2 x s32>) = G_BITCAST
1457 
1458   CHECK: [[BITCAST0_E0:%[0-9]+]]:_(s32), [[BITCAST0_E1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[BITCAST0]]:_(<2 x s32>)
1459   CHECK: [[IMP_DEF0:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
1460   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)
1461 
1462   CHECK: [[BITCAST1_E0:%[0-9]+]]:_(s32), [[BITCAST1_E1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[BITCAST1]]:_(<2 x s32>)
1463   CHECK: [[IMP_DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
1464   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)
1465 
1466   CHECK: [[AND:%[0-9]+]]:_(<6 x s32>) = G_AND [[BITCAST0_LARGE]]:_, [[BITCAST1_LARGE]]:_
1467 
1468   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>)
1469   CHECK: (<2 x s32>) = G_BUILD_VECTOR [[AND_E0]]:_(s32), [[AND_E1]]:_(s32)
1470   )";
1471 
1472   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1473 }
1474 
1475 TEST_F(AArch64GISelMITest, FewerElementsPhi) {
1476   setUp();
1477   if (!TM)
1478     return;
1479 
1480   LLT s1 = LLT::scalar(1);
1481   LLT s32 = LLT::scalar(32);
1482   LLT s64 = LLT::scalar(64);
1483   LLT v2s32 = LLT::fixed_vector(2, 32);
1484   LLT v5s32 = LLT::fixed_vector(5, 32);
1485 
1486   LegalizerInfo LI;
1487   LI.getActionDefinitionsBuilder(TargetOpcode::G_PHI)
1488     .legalFor({v2s32})
1489     .clampMinNumElements(0, s32, 2);
1490   LI.getLegacyLegalizerInfo().computeTables();
1491 
1492   LLT PhiTy = v5s32;
1493   DummyGISelObserver Observer;
1494   LegalizerHelper Helper(*MF, LI, Observer, B);
1495   B.setMBB(*EntryMBB);
1496 
1497   MachineBasicBlock *MidMBB = MF->CreateMachineBasicBlock();
1498   MachineBasicBlock *EndMBB = MF->CreateMachineBasicBlock();
1499   MF->insert(MF->end(), MidMBB);
1500   MF->insert(MF->end(), EndMBB);
1501 
1502   EntryMBB->addSuccessor(MidMBB);
1503   EntryMBB->addSuccessor(EndMBB);
1504   MidMBB->addSuccessor(EndMBB);
1505 
1506   auto InitVal = B.buildUndef(PhiTy);
1507   auto InitOtherVal = B.buildConstant(s64, 999);
1508 
1509   auto ICmp = B.buildICmp(CmpInst::ICMP_EQ, s1, Copies[0], Copies[1]);
1510   B.buildBrCond(ICmp.getReg(0), *MidMBB);
1511   B.buildBr(*EndMBB);
1512 
1513 
1514   B.setMBB(*MidMBB);
1515   auto MidVal = B.buildUndef(PhiTy);
1516   auto MidOtherVal = B.buildConstant(s64, 345);
1517   B.buildBr(*EndMBB);
1518 
1519   B.setMBB(*EndMBB);
1520   auto Phi = B.buildInstr(TargetOpcode::G_PHI)
1521     .addDef(MRI->createGenericVirtualRegister(PhiTy))
1522     .addUse(InitVal.getReg(0))
1523     .addMBB(EntryMBB)
1524     .addUse(MidVal.getReg(0))
1525     .addMBB(MidMBB);
1526 
1527   // Insert another irrelevant phi to make sure the rebuild is inserted after
1528   // it.
1529   B.buildInstr(TargetOpcode::G_PHI)
1530     .addDef(MRI->createGenericVirtualRegister(s64))
1531     .addUse(InitOtherVal.getReg(0))
1532     .addMBB(EntryMBB)
1533     .addUse(MidOtherVal.getReg(0))
1534     .addMBB(MidMBB);
1535 
1536   // Add some use instruction after the phis.
1537   B.buildAnd(PhiTy, Phi.getReg(0), Phi.getReg(0));
1538 
1539   B.setInstr(*Phi);
1540   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1541             Helper.fewerElementsVector(*Phi, 0, v2s32));
1542 
1543   auto CheckStr = R"(
1544   CHECK: [[INITVAL:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF
1545   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>)
1546   CHECK: [[INITVAL_E01:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[INITVAL_E0]]:_(s32), [[INITVAL_E1]]:_(s32)
1547   CHECK: [[INITVAL_E23:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[INITVAL_E2]]:_(s32), [[INITVAL_E3]]:_(s32)
1548   CHECK: G_BRCOND
1549 
1550   CHECK: [[MIDVAL:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF
1551   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>)
1552   CHECK: [[MIDVAL_E01:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[MIDVAL_E0]]:_(s32), [[MIDVAL_E1]]:_(s32)
1553   CHECK: [[MIDVAL_E23:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[MIDVAL_E2]]:_(s32), [[MIDVAL_E3]]:_(s32)
1554   CHECK: G_BR
1555 
1556   CHECK: [[PHI0:%[0-9]+]]:_(<2 x s32>) = G_PHI [[INITVAL_E01]]:_(<2 x s32>), %bb.0, [[MIDVAL_E01]]:_(<2 x s32>), %bb.1
1557   CHECK: [[PHI1:%[0-9]+]]:_(<2 x s32>) = G_PHI [[INITVAL_E23]]:_(<2 x s32>), %bb.0, [[MIDVAL_E23]]:_(<2 x s32>), %bb.1
1558   CHECK: [[PHI2:%[0-9]+]]:_(s32) = G_PHI [[INITVAL_E4]]:_(s32), %bb.0, [[MIDVAL_E4]]:_(s32), %bb.1
1559   CHECK: [[UNMERGE0:%[0-9]+]]:_(s32), [[UNMERGE1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[PHI0]]:_(<2 x s32>)
1560   CHECK: [[UNMERGE2:%[0-9]+]]:_(s32), [[UNMERGE3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[PHI1]]:_(<2 x s32>)
1561   CHECK: [[BV:%[0-9]+]]:_(<5 x s32>) = G_BUILD_VECTOR [[UNMERGE0]]:_(s32), [[UNMERGE1]]:_(s32), [[UNMERGE2]]:_(s32), [[UNMERGE3]]:_(s32), [[PHI2]]:_(s32)
1562 
1563   CHECK: [[OTHER_PHI:%[0-9]+]]:_(s64) = G_PHI
1564 
1565   CHECK: [[USE_OP:%[0-9]+]]:_(<5 x s32>) = G_AND [[BV]]:_, [[BV]]:_
1566   )";
1567 
1568   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1569 }
1570 
1571 // FNEG expansion in terms of XOR
1572 TEST_F(AArch64GISelMITest, LowerFNEG) {
1573   setUp();
1574   if (!TM)
1575     return;
1576 
1577   // Declare your legalization info
1578   DefineLegalizerInfo(A, {
1579     getActionDefinitionsBuilder(G_FSUB).legalFor({s64});
1580   });
1581 
1582   // Build Instr. Make sure FMF are preserved.
1583   auto FAdd =
1584     B.buildInstr(TargetOpcode::G_FADD, {LLT::scalar(64)}, {Copies[0], Copies[1]},
1585                  MachineInstr::MIFlag::FmNsz);
1586 
1587   // Should not propagate the flags of src instruction.
1588   auto FNeg0 =
1589     B.buildInstr(TargetOpcode::G_FNEG, {LLT::scalar(64)}, {FAdd.getReg(0)},
1590                  {MachineInstr::MIFlag::FmArcp});
1591 
1592   // Preserve the one flag.
1593   auto FNeg1 =
1594     B.buildInstr(TargetOpcode::G_FNEG, {LLT::scalar(64)}, {Copies[0]},
1595                  MachineInstr::MIFlag::FmNoInfs);
1596 
1597   AInfo Info(MF->getSubtarget());
1598   DummyGISelObserver Observer;
1599   LegalizerHelper Helper(*MF, Info, Observer, B);
1600   // Perform Legalization
1601   B.setInstr(*FNeg0);
1602   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1603             Helper.lower(*FNeg0, 0, LLT::scalar(64)));
1604   B.setInstr(*FNeg1);
1605   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1606             Helper.lower(*FNeg1, 0, LLT::scalar(64)));
1607 
1608   auto CheckStr = R"(
1609   CHECK: [[FADD:%[0-9]+]]:_(s64) = nsz G_FADD %0:_, %1:_
1610   CHECK: [[CONST0:%[0-9]+]]:_(s64) = G_CONSTANT i64 -9223372036854775808
1611   CHECK: [[FSUB0:%[0-9]+]]:_(s64) = G_XOR [[FADD]]:_, [[CONST0]]:_
1612   CHECK: [[CONST1:%[0-9]+]]:_(s64) = G_CONSTANT i64 -9223372036854775808
1613   CHECK: [[FSUB1:%[0-9]+]]:_(s64) = G_XOR %0:_, [[CONST1]]:_
1614   )";
1615 
1616   // Check
1617   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1618 }
1619 
1620 TEST_F(AArch64GISelMITest, LowerMinMax) {
1621   setUp();
1622   if (!TM)
1623     return;
1624 
1625   LLT s64 = LLT::scalar(64);
1626   LLT v2s32 = LLT::fixed_vector(2, 32);
1627 
1628   DefineLegalizerInfo(A, {
1629     getActionDefinitionsBuilder({G_SMIN, G_SMAX, G_UMIN, G_UMAX})
1630         .lowerFor({s64, LLT::fixed_vector(2, s32)});
1631   });
1632 
1633   auto SMin = B.buildSMin(s64, Copies[0], Copies[1]);
1634   auto SMax = B.buildSMax(s64, Copies[0], Copies[1]);
1635   auto UMin = B.buildUMin(s64, Copies[0], Copies[1]);
1636   auto UMax = B.buildUMax(s64, Copies[0], Copies[1]);
1637 
1638   auto VecVal0 = B.buildBitcast(v2s32, Copies[0]);
1639   auto VecVal1 = B.buildBitcast(v2s32, Copies[1]);
1640 
1641   auto SMinV = B.buildSMin(v2s32, VecVal0, VecVal1);
1642   auto SMaxV = B.buildSMax(v2s32, VecVal0, VecVal1);
1643   auto UMinV = B.buildUMin(v2s32, VecVal0, VecVal1);
1644   auto UMaxV = B.buildUMax(v2s32, VecVal0, VecVal1);
1645 
1646   AInfo Info(MF->getSubtarget());
1647   DummyGISelObserver Observer;
1648   LegalizerHelper Helper(*MF, Info, Observer, B);
1649   B.setInstr(*SMin);
1650   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1651             Helper.lower(*SMin, 0, s64));
1652   B.setInstr(*SMax);
1653   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1654             Helper.lower(*SMax, 0, s64));
1655   B.setInstr(*UMin);
1656   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1657             Helper.lower(*UMin, 0, s64));
1658   B.setInstr(*UMax);
1659   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1660             Helper.lower(*UMax, 0, s64));
1661 
1662   B.setInstr(*SMinV);
1663   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1664             Helper.lower(*SMinV, 0, v2s32));
1665   B.setInstr(*SMaxV);
1666   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1667             Helper.lower(*SMaxV, 0, v2s32));
1668   B.setInstr(*UMinV);
1669   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1670             Helper.lower(*UMinV, 0, v2s32));
1671   B.setInstr(*UMaxV);
1672   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1673             Helper.lower(*UMaxV, 0, v2s32));
1674 
1675   auto CheckStr = R"(
1676   CHECK: [[CMP0:%[0-9]+]]:_(s1) = G_ICMP intpred(slt), %0:_(s64), %1:_
1677   CHECK: [[SMIN:%[0-9]+]]:_(s64) = G_SELECT [[CMP0]]:_(s1), %0:_, %1:_
1678 
1679   CHECK: [[CMP1:%[0-9]+]]:_(s1) = G_ICMP intpred(sgt), %0:_(s64), %1:_
1680   CHECK: [[SMAX:%[0-9]+]]:_(s64) = G_SELECT [[CMP1]]:_(s1), %0:_, %1:_
1681 
1682   CHECK: [[CMP2:%[0-9]+]]:_(s1) = G_ICMP intpred(ult), %0:_(s64), %1:_
1683   CHECK: [[UMIN:%[0-9]+]]:_(s64) = G_SELECT [[CMP2]]:_(s1), %0:_, %1:_
1684 
1685   CHECK: [[CMP3:%[0-9]+]]:_(s1) = G_ICMP intpred(ugt), %0:_(s64), %1:_
1686   CHECK: [[UMAX:%[0-9]+]]:_(s64) = G_SELECT [[CMP3]]:_(s1), %0:_, %1:_
1687 
1688   CHECK: [[VEC0:%[0-9]+]]:_(<2 x s32>) = G_BITCAST %0:_(s64)
1689   CHECK: [[VEC1:%[0-9]+]]:_(<2 x s32>) = G_BITCAST %1:_(s64)
1690 
1691   CHECK: [[VCMP0:%[0-9]+]]:_(<2 x s1>) = G_ICMP intpred(slt), [[VEC0]]:_(<2 x s32>), [[VEC1]]:_
1692   CHECK: [[SMINV:%[0-9]+]]:_(<2 x s32>) = G_SELECT [[VCMP0]]:_(<2 x s1>), [[VEC0]]:_, [[VEC1]]:_
1693 
1694   CHECK: [[VCMP1:%[0-9]+]]:_(<2 x s1>) = G_ICMP intpred(sgt), [[VEC0]]:_(<2 x s32>), [[VEC1]]:_
1695   CHECK: [[SMAXV:%[0-9]+]]:_(<2 x s32>) = G_SELECT [[VCMP1]]:_(<2 x s1>), [[VEC0]]:_, [[VEC1]]:_
1696 
1697   CHECK: [[VCMP2:%[0-9]+]]:_(<2 x s1>) = G_ICMP intpred(ult), [[VEC0]]:_(<2 x s32>), [[VEC1]]:_
1698   CHECK: [[UMINV:%[0-9]+]]:_(<2 x s32>) = G_SELECT [[VCMP2]]:_(<2 x s1>), [[VEC0]]:_, [[VEC1]]:_
1699 
1700   CHECK: [[VCMP3:%[0-9]+]]:_(<2 x s1>) = G_ICMP intpred(ugt), [[VEC0]]:_(<2 x s32>), [[VEC1]]:_
1701   CHECK: [[UMAXV:%[0-9]+]]:_(<2 x s32>) = G_SELECT [[VCMP3]]:_(<2 x s1>), [[VEC0]]:_, [[VEC1]]:_
1702   )";
1703 
1704   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1705 }
1706 
1707 TEST_F(AArch64GISelMITest, WidenScalarBuildVector) {
1708   setUp();
1709   if (!TM)
1710     return;
1711 
1712   LLT S32 = LLT::scalar(32);
1713   LLT S16 = LLT::scalar(16);
1714   LLT V2S16 = LLT::fixed_vector(2, S16);
1715   LLT V2S32 = LLT::fixed_vector(2, S32);
1716 
1717   DefineLegalizerInfo(A, {
1718     getActionDefinitionsBuilder({G_SMIN, G_SMAX, G_UMIN, G_UMAX})
1719         .lowerFor({s64, LLT::fixed_vector(2, s32)});
1720   });
1721 
1722   AInfo Info(MF->getSubtarget());
1723   DummyGISelObserver Observer;
1724   LegalizerHelper Helper(*MF, Info, Observer, B);
1725   B.setInsertPt(*EntryMBB, EntryMBB->end());
1726 
1727   Register Constant0 = B.buildConstant(S16, 1).getReg(0);
1728   Register Constant1 = B.buildConstant(S16, 2).getReg(0);
1729   auto BV0 = B.buildBuildVector(V2S16, {Constant0, Constant1});
1730   auto BV1 = B.buildBuildVector(V2S16, {Constant0, Constant1});
1731 
1732   B.setInstr(*BV0);
1733   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1734             Helper.widenScalar(*BV0, 0, V2S32));
1735   B.setInstr(*BV1);
1736   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1737             Helper.widenScalar(*BV1, 1, S32));
1738 
1739   auto CheckStr = R"(
1740   CHECK: [[K0:%[0-9]+]]:_(s16) = G_CONSTANT i16 1
1741   CHECK-NEXT: [[K1:%[0-9]+]]:_(s16) = G_CONSTANT i16 2
1742   CHECK-NEXT: [[EXT_K0_0:%[0-9]+]]:_(s32) = G_ANYEXT [[K0]]
1743   CHECK-NEXT: [[EXT_K1_0:%[0-9]+]]:_(s32) = G_ANYEXT [[K1]]
1744   CHECK-NEXT: [[BV0:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[EXT_K0_0]]:_(s32), [[EXT_K1_0]]:_(s32)
1745   CHECK-NEXT: [[BV0_TRUNC:%[0-9]+]]:_(<2 x s16>) = G_TRUNC [[BV0]]
1746 
1747   CHECK: [[EXT_K0_1:%[0-9]+]]:_(s32) = G_ANYEXT [[K0]]
1748   CHECK-NEXT: [[EXT_K1_1:%[0-9]+]]:_(s32) = G_ANYEXT [[K1]]
1749 
1750   CHECK-NEXT: [[BV1:%[0-9]+]]:_(<2 x s16>) = G_BUILD_VECTOR_TRUNC [[EXT_K0_1]]:_(s32), [[EXT_K1_1]]:_(s32)
1751   )";
1752 
1753   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1754 }
1755 
1756 TEST_F(AArch64GISelMITest, LowerMergeValues) {
1757   setUp();
1758   if (!TM)
1759     return;
1760 
1761   const LLT S32 = LLT::scalar(32);
1762   const LLT S24 = LLT::scalar(24);
1763   const LLT S21 = LLT::scalar(21);
1764   const LLT S16 = LLT::scalar(16);
1765   const LLT S9 = LLT::scalar(9);
1766   const LLT S8 = LLT::scalar(8);
1767   const LLT S3 = LLT::scalar(3);
1768 
1769   DefineLegalizerInfo(A, {
1770     getActionDefinitionsBuilder(G_UNMERGE_VALUES)
1771       .widenScalarIf(typeIs(1, LLT::scalar(3)), changeTo(1, LLT::scalar(9)));
1772   });
1773 
1774   AInfo Info(MF->getSubtarget());
1775   DummyGISelObserver Observer;
1776   LegalizerHelper Helper(*MF, Info, Observer, B);
1777   B.setInsertPt(*EntryMBB, EntryMBB->end());
1778 
1779   // 24 = 3 3 3   3 3 3   3 3
1780   //     => 9
1781   //
1782   // This can do 3 merges, but need an extra implicit_def.
1783   SmallVector<Register, 8> Merge0Ops;
1784   for (int I = 0; I != 8; ++I)
1785     Merge0Ops.push_back(B.buildConstant(S3, I).getReg(0));
1786 
1787   auto Merge0 = B.buildMergeLikeInstr(S24, Merge0Ops);
1788 
1789   // 21 = 3 3 3   3 3 3   3
1790   //     => 9, 2 extra implicit_def needed
1791   //
1792   SmallVector<Register, 8> Merge1Ops;
1793   for (int I = 0; I != 7; ++I)
1794     Merge1Ops.push_back(B.buildConstant(S3, I).getReg(0));
1795 
1796   auto Merge1 = B.buildMergeLikeInstr(S21, Merge1Ops);
1797 
1798   SmallVector<Register, 8> Merge2Ops;
1799   for (int I = 0; I != 2; ++I)
1800     Merge2Ops.push_back(B.buildConstant(S8, I).getReg(0));
1801 
1802   auto Merge2 = B.buildMergeLikeInstr(S16, Merge2Ops);
1803 
1804   B.setInstr(*Merge0);
1805   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1806             Helper.widenScalar(*Merge0, 1, S9));
1807   B.setInstr(*Merge1);
1808   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1809             Helper.widenScalar(*Merge1, 1, S9));
1810 
1811   // Request a source size greater than the original destination size.
1812   B.setInstr(*Merge2);
1813   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1814             Helper.widenScalar(*Merge2, 1, S32));
1815 
1816   auto CheckStr = R"(
1817   CHECK: [[K0:%[0-9]+]]:_(s3) = G_CONSTANT i3 0
1818   CHECK-NEXT: [[K1:%[0-9]+]]:_(s3) = G_CONSTANT i3 1
1819   CHECK-NEXT: [[K2:%[0-9]+]]:_(s3) = G_CONSTANT i3 2
1820   CHECK-NEXT: [[K3:%[0-9]+]]:_(s3) = G_CONSTANT i3 3
1821   CHECK-NEXT: [[K4:%[0-9]+]]:_(s3) = G_CONSTANT i3 -4
1822   CHECK-NEXT: [[K5:%[0-9]+]]:_(s3) = G_CONSTANT i3 -3
1823   CHECK-NEXT: [[K6:%[0-9]+]]:_(s3) = G_CONSTANT i3 -2
1824   CHECK-NEXT: [[K7:%[0-9]+]]:_(s3) = G_CONSTANT i3 -1
1825   CHECK-NEXT: [[IMPDEF0:%[0-9]+]]:_(s3) = G_IMPLICIT_DEF
1826   CHECK-NEXT: [[MERGE0:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K0]]:_(s3), [[K1]]:_(s3), [[K2]]:_(s3)
1827   CHECK-NEXT: [[MERGE1:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K3]]:_(s3), [[K4]]:_(s3), [[K5]]:_(s3)
1828   CHECK-NEXT: [[MERGE2:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K6]]:_(s3), [[K7]]:_(s3), [[IMPDEF0]]:_(s3)
1829   CHECK-NEXT: [[MERGE3:%[0-9]+]]:_(s27) = G_MERGE_VALUES [[MERGE0]]:_(s9), [[MERGE1]]:_(s9), [[MERGE2]]:_(s9)
1830   CHECK-NEXT: (s24) = G_TRUNC [[MERGE3]]:_(s27)
1831 
1832 
1833   CHECK: [[K8:%[0-9]+]]:_(s3) = G_CONSTANT i3 0
1834   CHECK-NEXT: [[K9:%[0-9]+]]:_(s3) = G_CONSTANT i3 1
1835   CHECK-NEXT: [[K10:%[0-9]+]]:_(s3) = G_CONSTANT i3 2
1836   CHECK-NEXT: [[K11:%[0-9]+]]:_(s3) = G_CONSTANT i3 3
1837   CHECK-NEXT: [[K12:%[0-9]+]]:_(s3) = G_CONSTANT i3 -4
1838   CHECK-NEXT: [[K13:%[0-9]+]]:_(s3) = G_CONSTANT i3 -3
1839   CHECK-NEXT: [[K14:%[0-9]+]]:_(s3) = G_CONSTANT i3 -2
1840   CHECK-NEXT: [[IMPDEF1:%[0-9]+]]:_(s3) = G_IMPLICIT_DEF
1841   CHECK-NEXT: [[MERGE4:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K8]]:_(s3), [[K9]]:_(s3), [[K10]]:_(s3)
1842   CHECK-NEXT: [[MERGE5:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K11]]:_(s3), [[K12]]:_(s3), [[K13]]:_(s3)
1843   CHECK-NEXT: [[MERGE6:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K14]]:_(s3), [[IMPDEF1]]:_(s3), [[IMPDEF1]]:_(s3)
1844   CHECK-NEXT: [[MERGE7:%[0-9]+]]:_(s27) = G_MERGE_VALUES [[MERGE4]]:_(s9), [[MERGE5]]:_(s9), [[MERGE6]]:_(s9)
1845   CHECK-NEXT: (s21) = G_TRUNC [[MERGE7]]:_(s27)
1846 
1847 
1848   CHECK: [[K15:%[0-9]+]]:_(s8) = G_CONSTANT i8 0
1849   CHECK-NEXT: [[K16:%[0-9]+]]:_(s8) = G_CONSTANT i8 1
1850   CHECK-NEXT: [[ZEXT_K15:[0-9]+]]:_(s32) = G_ZEXT [[K15]]:_(s8)
1851   CHECK-NEXT: [[ZEXT_K16:[0-9]+]]:_(s32) = G_ZEXT [[K16]]:_(s8)
1852   [[K16:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
1853   [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ZEXT_K16]]:_, [[K16]]:_(s32)
1854   [[OR:%[0-9]+]]:_(s32) = G_OR [[ZEXT_K16]]:_, [[SHL]]:_
1855   (s16) = G_TRUNC [[OR]]:_(s32)
1856   )";
1857 
1858   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1859 }
1860 
1861 TEST_F(AArch64GISelMITest, WidenScalarMergeValuesPointer) {
1862   setUp();
1863   if (!TM)
1864     return;
1865 
1866   DefineLegalizerInfo(A, {});
1867 
1868   AInfo Info(MF->getSubtarget());
1869   DummyGISelObserver Observer;
1870   LegalizerHelper Helper(*MF, Info, Observer, B);
1871   B.setInsertPt(*EntryMBB, EntryMBB->end());
1872 
1873   const LLT S32 = LLT::scalar(32);
1874   const LLT S64 = LLT::scalar(64);
1875   const LLT P0 = LLT::pointer(0, 64);
1876 
1877   auto Lo = B.buildTrunc(S32, Copies[0]);
1878   auto Hi = B.buildTrunc(S32, Copies[1]);
1879 
1880   auto Merge = B.buildMergeLikeInstr(P0, {Lo, Hi});
1881 
1882   B.setInstr(*Merge);
1883   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
1884             Helper.widenScalar(*Merge, 1, S64));
1885 
1886   auto CheckStr = R"(
1887    CHECK: [[TRUNC0:%[0-9]+]]:_(s32) = G_TRUNC
1888    CHECK: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC
1889    CHECK: [[ZEXT_TRUNC0:%[0-9]+]]:_(s64) = G_ZEXT [[TRUNC0]]
1890    CHECK: [[ZEXT_TRUNC1:%[0-9]+]]:_(s64) = G_ZEXT [[TRUNC1]]
1891    CHECK: [[SHIFT_AMT:%[0-9]+]]:_(s64) = G_CONSTANT i64 32
1892    CHECK: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ZEXT_TRUNC1]]:_, [[SHIFT_AMT]]
1893    CHECK: [[OR:%[0-9]+]]:_(s64) = G_OR [[ZEXT_TRUNC0]]:_, [[SHL]]
1894    CHECK: [[INTTOPTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[OR]]:_(s64)
1895   )";
1896 
1897   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1898 }
1899 
1900 TEST_F(AArch64GISelMITest, WidenSEXTINREG) {
1901   setUp();
1902   if (!TM)
1903     return;
1904 
1905   // Declare your legalization info
1906   DefineLegalizerInfo(A, {
1907     getActionDefinitionsBuilder(G_SEXT_INREG).legalForTypeWithAnyImm({s64});
1908   });
1909   // Build Instr
1910   auto MIB = B.buildInstr(
1911       TargetOpcode::G_SEXT_INREG, {LLT::scalar(32)},
1912       {B.buildInstr(TargetOpcode::G_TRUNC, {LLT::scalar(32)}, {Copies[0]}),
1913        uint64_t(8)});
1914   AInfo Info(MF->getSubtarget());
1915   DummyGISelObserver Observer;
1916   LegalizerHelper Helper(*MF, Info, Observer, B);
1917   // Perform Legalization
1918   B.setInstr(*MIB);
1919   ASSERT_TRUE(Helper.widenScalar(*MIB, 0, LLT::scalar(64)) ==
1920               LegalizerHelper::LegalizeResult::Legalized);
1921 
1922   auto CheckStr = R"(
1923   CHECK: [[T0:%[0-9]+]]:_(s32) = G_TRUNC
1924   CHECK: [[T1:%[0-9]+]]:_(s64) = G_ANYEXT [[T0]]:_(s32)
1925   CHECK: [[T2:%[0-9]+]]:_(s64) = G_SEXT_INREG [[T1]]:_, 8
1926   CHECK: [[T3:%[0-9]+]]:_(s32) = G_TRUNC [[T2]]:_(s64)
1927   )";
1928 
1929   // Check
1930   ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1931 }
1932 
1933 TEST_F(AArch64GISelMITest, NarrowSEXTINREG) {
1934   setUp();
1935   if (!TM)
1936     return;
1937 
1938   // Declare your legalization info, these aren't actually relevant to the test.
1939   DefineLegalizerInfo(A, {
1940     getActionDefinitionsBuilder(G_SEXT_INREG).legalForTypeWithAnyImm({s64});
1941   });
1942   // Build Instr
1943   auto MIB = B.buildInstr(
1944       TargetOpcode::G_SEXT_INREG, {LLT::scalar(16)},
1945       {B.buildInstr(TargetOpcode::G_TRUNC, {LLT::scalar(16)}, {Copies[0]}),
1946        uint64_t(8)});
1947   AInfo Info(MF->getSubtarget());
1948   DummyGISelObserver Observer;
1949   LegalizerHelper Helper(*MF, Info, Observer, B);
1950   // Perform Legalization
1951   B.setInstr(*MIB);
1952   ASSERT_TRUE(Helper.narrowScalar(*MIB, 0, LLT::scalar(10)) ==
1953               LegalizerHelper::LegalizeResult::Legalized);
1954 
1955   auto CheckStr = R"(
1956   CHECK: [[T0:%[0-9]+]]:_(s16) = G_TRUNC
1957   CHECK: [[T1:%[0-9]+]]:_(s10) = G_TRUNC [[T0]]:_(s16)
1958   CHECK: [[T2:%[0-9]+]]:_(s10) = G_SEXT_INREG [[T1]]:_, 8
1959   CHECK: [[T3:%[0-9]+]]:_(s16) = G_SEXT [[T2]]:_(s10)
1960   )";
1961 
1962   // Check
1963   ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1964 }
1965 
1966 TEST_F(AArch64GISelMITest, NarrowSEXTINREG2) {
1967   setUp();
1968   if (!TM)
1969     return;
1970 
1971   // Declare your legalization info, these aren't actually relevant to the test.
1972   DefineLegalizerInfo(
1973       A, { getActionDefinitionsBuilder(G_SEXT_INREG).legalForTypeWithAnyImm({s64}); });
1974   // Build Instr
1975   auto MIB = B.buildInstr(
1976       TargetOpcode::G_SEXT_INREG, {LLT::scalar(32)},
1977       {B.buildInstr(TargetOpcode::G_TRUNC, {LLT::scalar(32)}, {Copies[0]}),
1978        uint64_t(9)});
1979   AInfo Info(MF->getSubtarget());
1980   DummyGISelObserver Observer;
1981   LegalizerHelper Helper(*MF, Info, Observer, B);
1982   // Perform Legalization
1983   B.setInstr(*MIB);
1984   ASSERT_TRUE(Helper.narrowScalar(*MIB, 0, LLT::scalar(8)) ==
1985               LegalizerHelper::LegalizeResult::Legalized);
1986 
1987   auto CheckStr = R"(
1988   CHECK: [[T0:%[0-9]+]]:_(s32) = G_TRUNC
1989   CHECK: [[T1:%[0-9]+]]:_(s8), [[T2:%[0-9]+]]:_(s8), [[T3:%[0-9]+]]:_(s8), [[T4:%[0-9]+]]:_(s8) = G_UNMERGE_VALUES [[T0]]:_(s32)
1990   CHECK: [[CST2:%[0-9]+]]:_(s8) = G_CONSTANT i8 7
1991   CHECK: [[T5:%[0-9]+]]:_(s8) = G_SEXT_INREG [[T2]]:_, 1
1992   CHECK: [[T6:%[0-9]+]]:_(s8) = G_ASHR [[T5]]:_, [[CST2]]:_
1993   CHECK: [[T7:%[0-9]+]]:_(s32) = G_MERGE_VALUES [[T1]]:_(s8), [[T5]]:_(s8), [[T6]]:_(s8), [[T6]]:_(s8)
1994   )";
1995 
1996   // Check
1997   ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
1998 }
1999 
2000 TEST_F(AArch64GISelMITest, LowerSEXTINREG) {
2001   setUp();
2002   if (!TM)
2003     return;
2004 
2005   // Declare your legalization info, these aren't actually relevant to the test.
2006   DefineLegalizerInfo(
2007       A, { getActionDefinitionsBuilder(G_SEXT_INREG).legalForTypeWithAnyImm({s64}); });
2008   // Build Instr
2009   auto MIB = B.buildInstr(
2010       TargetOpcode::G_SEXT_INREG, {LLT::scalar(32)},
2011       {B.buildInstr(TargetOpcode::G_TRUNC, {LLT::scalar(32)}, {Copies[0]}),
2012        uint64_t(8)});
2013   AInfo Info(MF->getSubtarget());
2014   DummyGISelObserver Observer;
2015   LegalizerHelper Helper(*MF, Info, Observer, B);
2016   // Perform Legalization
2017   B.setInstr(*MIB);
2018   ASSERT_TRUE(Helper.lower(*MIB, 0, LLT()) ==
2019               LegalizerHelper::LegalizeResult::Legalized);
2020 
2021   auto CheckStr = R"(
2022   CHECK: [[T1:%[0-9]+]]:_(s32) = G_TRUNC
2023   CHECK: [[CST:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
2024   CHECK: [[T2:%[0-9]+]]:_(s32) = G_SHL [[T1]]:_, [[CST]]:_
2025   CHECK: [[T3:%[0-9]+]]:_(s32) = G_ASHR [[T2]]:_, [[CST]]:_
2026   )";
2027 
2028   // Check
2029   ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
2030 }
2031 
2032 TEST_F(AArch64GISelMITest, LibcallFPExt) {
2033   setUp();
2034   if (!TM)
2035     return;
2036 
2037   // Declare your legalization info
2038   DefineLegalizerInfo(A, {
2039     getActionDefinitionsBuilder(G_FPEXT).libcallFor({{s32, s16}, {s128, s64}});
2040   });
2041 
2042   LLT S16{LLT::scalar(16)};
2043   LLT S32{LLT::scalar(32)};
2044   LLT S128{LLT::scalar(128)};
2045   auto MIBTrunc = B.buildTrunc(S16, Copies[0]);
2046   auto MIBFPExt1 =
2047       B.buildInstr(TargetOpcode::G_FPEXT, {S32}, {MIBTrunc});
2048 
2049   auto MIBFPExt2 =
2050       B.buildInstr(TargetOpcode::G_FPEXT, {S128}, {Copies[1]});
2051   AInfo Info(MF->getSubtarget());
2052   DummyGISelObserver Observer;
2053   LegalizerHelper Helper(*MF, Info, Observer, B);
2054   LostDebugLocObserver DummyLocObserver("");
2055   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2056               Helper.libcall(*MIBFPExt1, DummyLocObserver));
2057 
2058   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2059               Helper.libcall(*MIBFPExt2, DummyLocObserver));
2060   auto CheckStr = R"(
2061   CHECK: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC
2062   CHECK: $h0 = COPY [[TRUNC]]
2063   CHECK: BL &__gnu_h2f_ieee
2064   CHECK: $d0 = COPY
2065   CHECK: BL &__extenddftf2
2066   )";
2067 
2068   // Check
2069   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2070 }
2071 
2072 TEST_F(AArch64GISelMITest, LibcallFPTrunc) {
2073   setUp();
2074   if (!TM)
2075     return;
2076 
2077   // Declare your legalization info
2078   DefineLegalizerInfo(A, {
2079     getActionDefinitionsBuilder(G_FPTRUNC).libcallFor({{s16, s32}, {s64, s128}});
2080   });
2081 
2082   LLT S16{LLT::scalar(16)};
2083   LLT S32{LLT::scalar(32)};
2084   LLT S64{LLT::scalar(64)};
2085   LLT S128{LLT::scalar(128)};
2086   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2087   auto MIBFPTrunc1 =
2088       B.buildInstr(TargetOpcode::G_FPTRUNC, {S16}, {MIBTrunc});
2089 
2090   auto MIBMerge = B.buildMergeLikeInstr(S128, {Copies[1], Copies[2]});
2091 
2092   auto MIBFPTrunc2 =
2093       B.buildInstr(TargetOpcode::G_FPTRUNC, {S64}, {MIBMerge});
2094   AInfo Info(MF->getSubtarget());
2095   DummyGISelObserver Observer;
2096   LostDebugLocObserver DummyLocObserver("");
2097   LegalizerHelper Helper(*MF, Info, Observer, B);
2098   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2099             Helper.libcall(*MIBFPTrunc1, DummyLocObserver));
2100 
2101   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2102             Helper.libcall(*MIBFPTrunc2, DummyLocObserver));
2103   auto CheckStr = R"(
2104   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2105   CHECK: $s0 = COPY [[TRUNC]]
2106   CHECK: BL &__gnu_f2h_ieee
2107   CHECK: $q0 = COPY
2108   CHECK: BL &__trunctfdf2
2109   )";
2110 
2111   // Check
2112   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2113 }
2114 
2115 TEST_F(AArch64GISelMITest, LibcallSimple) {
2116   setUp();
2117   if (!TM)
2118     return;
2119 
2120   // Declare your legalization info
2121   DefineLegalizerInfo(A, {
2122     getActionDefinitionsBuilder(G_FADD).libcallFor({s16});
2123   });
2124 
2125   LLT S16{LLT::scalar(16)};
2126   auto MIBTrunc = B.buildTrunc(S16, Copies[0]);
2127   auto MIBFADD =
2128       B.buildInstr(TargetOpcode::G_FADD, {S16}, {MIBTrunc, MIBTrunc});
2129 
2130   AInfo Info(MF->getSubtarget());
2131   DummyGISelObserver Observer;
2132   LostDebugLocObserver DummyLocObserver("");
2133   LegalizerHelper Helper(*MF, Info, Observer, B);
2134   // Make sure we do not crash anymore
2135   EXPECT_EQ(LegalizerHelper::LegalizeResult::UnableToLegalize,
2136             Helper.libcall(*MIBFADD, DummyLocObserver));
2137 }
2138 
2139 TEST_F(AArch64GISelMITest, LibcallMul) {
2140   setUp();
2141   if (!TM)
2142     return;
2143 
2144   // Declare your legalization info
2145   DefineLegalizerInfo(A, {
2146     getActionDefinitionsBuilder(G_MUL).libcallFor({s32, s64, s128});
2147   });
2148 
2149   LLT S32{LLT::scalar(32)};
2150   LLT S64{LLT::scalar(64)};
2151   LLT S128{LLT::scalar(128)};
2152   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2153   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2154 
2155   auto MIBMul32 =
2156       B.buildInstr(TargetOpcode::G_MUL, {S32}, {MIBTrunc, MIBTrunc});
2157   auto MIBMul64 =
2158       B.buildInstr(TargetOpcode::G_MUL, {S64}, {Copies[0], Copies[0]});
2159   auto MIBMul128 =
2160       B.buildInstr(TargetOpcode::G_MUL, {S128}, {MIBExt, MIBExt});
2161 
2162   AInfo Info(MF->getSubtarget());
2163   DummyGISelObserver Observer;
2164   LostDebugLocObserver DummyLocObserver("");
2165   LegalizerHelper Helper(*MF, Info, Observer, B);
2166 
2167   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2168             Helper.libcall(*MIBMul32, DummyLocObserver));
2169   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2170             Helper.libcall(*MIBMul64, DummyLocObserver));
2171   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2172             Helper.libcall(*MIBMul128, DummyLocObserver));
2173 
2174   auto CheckStr = R"(
2175   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2176   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2177   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2178   CHECK: $w0 = COPY [[TRUNC]]
2179   CHECK: $w1 = COPY [[TRUNC]]
2180   CHECK: BL &__mulsi3
2181   CHECK: $x0 = COPY [[COPY]]
2182   CHECK: $x1 = COPY [[COPY]]
2183   CHECK: BL &__muldi3
2184   CHECK: [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[ANYEXT]]
2185   CHECK: [[UV2:%[0-9]+]]:_(s64), [[UV3:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[ANYEXT]]
2186   CHECK: $x0 = COPY [[UV]]
2187   CHECK: $x1 = COPY [[UV1]]
2188   CHECK: $x2 = COPY [[UV2]]
2189   CHECK: $x3 = COPY [[UV3]]
2190   CHECK: BL &__multi3
2191   )";
2192 
2193   // Check
2194   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2195 }
2196 
2197 TEST_F(AArch64GISelMITest, LibcallSRem) {
2198   setUp();
2199   if (!TM)
2200     return;
2201 
2202   // Declare your legalization info
2203   DefineLegalizerInfo(A, {
2204     getActionDefinitionsBuilder(G_SREM).libcallFor({s32, s64, s128});
2205   });
2206 
2207   LLT S32{LLT::scalar(32)};
2208   LLT S64{LLT::scalar(64)};
2209   LLT S128{LLT::scalar(128)};
2210   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2211   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2212 
2213   auto MIBSRem32 =
2214       B.buildInstr(TargetOpcode::G_SREM, {S32}, {MIBTrunc, MIBTrunc});
2215   auto MIBSRem64 =
2216       B.buildInstr(TargetOpcode::G_SREM, {S64}, {Copies[0], Copies[0]});
2217   auto MIBSRem128 =
2218       B.buildInstr(TargetOpcode::G_SREM, {S128}, {MIBExt, MIBExt});
2219 
2220   AInfo Info(MF->getSubtarget());
2221   DummyGISelObserver Observer;
2222   LostDebugLocObserver DummyLocObserver("");
2223   LegalizerHelper Helper(*MF, Info, Observer, B);
2224 
2225   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2226             Helper.libcall(*MIBSRem32, DummyLocObserver));
2227   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2228             Helper.libcall(*MIBSRem64, DummyLocObserver));
2229   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2230             Helper.libcall(*MIBSRem128, DummyLocObserver));
2231 
2232   auto CheckStr = R"(
2233   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2234   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2235   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2236   CHECK: $w0 = COPY [[TRUNC]]
2237   CHECK: $w1 = COPY [[TRUNC]]
2238   CHECK: BL &__modsi3
2239   CHECK: $x0 = COPY [[COPY]]
2240   CHECK: $x1 = COPY [[COPY]]
2241   CHECK: BL &__moddi3
2242   CHECK: [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[ANYEXT]]
2243   CHECK: [[UV2:%[0-9]+]]:_(s64), [[UV3:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[ANYEXT]]
2244   CHECK: $x0 = COPY [[UV]]
2245   CHECK: $x1 = COPY [[UV1]]
2246   CHECK: $x2 = COPY [[UV2]]
2247   CHECK: $x3 = COPY [[UV3]]
2248   CHECK: BL &__modti3
2249   )";
2250 
2251   // Check
2252   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2253 }
2254 
2255 TEST_F(AArch64GISelMITest, LibcallURem) {
2256   setUp();
2257   if (!TM)
2258     return;
2259 
2260   // Declare your legalization info
2261   DefineLegalizerInfo(A, {
2262     getActionDefinitionsBuilder(G_UREM).libcallFor({s32, s64, s128});
2263   });
2264 
2265   LLT S32{LLT::scalar(32)};
2266   LLT S64{LLT::scalar(64)};
2267   LLT S128{LLT::scalar(128)};
2268   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2269   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2270 
2271   auto MIBURem32 =
2272       B.buildInstr(TargetOpcode::G_UREM, {S32}, {MIBTrunc, MIBTrunc});
2273   auto MIBURem64 =
2274       B.buildInstr(TargetOpcode::G_UREM, {S64}, {Copies[0], Copies[0]});
2275   auto MIBURem128 =
2276       B.buildInstr(TargetOpcode::G_UREM, {S128}, {MIBExt, MIBExt});
2277 
2278   AInfo Info(MF->getSubtarget());
2279   DummyGISelObserver Observer;
2280   LostDebugLocObserver DummyLocObserver("");
2281   LegalizerHelper Helper(*MF, Info, Observer, B);
2282 
2283   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2284             Helper.libcall(*MIBURem32, DummyLocObserver));
2285   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2286             Helper.libcall(*MIBURem64, DummyLocObserver));
2287   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2288             Helper.libcall(*MIBURem128, DummyLocObserver));
2289 
2290   const auto *CheckStr = R"(
2291   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2292   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2293   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2294   CHECK: $w0 = COPY [[TRUNC]]
2295   CHECK: $w1 = COPY [[TRUNC]]
2296   CHECK: BL &__umodsi3
2297   CHECK: $x0 = COPY [[COPY]]
2298   CHECK: $x1 = COPY [[COPY]]
2299   CHECK: BL &__umoddi3
2300   CHECK: [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[ANYEXT]]
2301   CHECK: [[UV2:%[0-9]+]]:_(s64), [[UV3:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[ANYEXT]]
2302   CHECK: $x0 = COPY [[UV]]
2303   CHECK: $x1 = COPY [[UV1]]
2304   CHECK: $x2 = COPY [[UV2]]
2305   CHECK: $x3 = COPY [[UV3]]
2306   CHECK: BL &__umodti3
2307   )";
2308 
2309   // Check
2310   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2311 }
2312 
2313 TEST_F(AArch64GISelMITest, LibcallCtlzZeroUndef) {
2314   setUp();
2315   if (!TM)
2316     return;
2317 
2318   // Declare your legalization info
2319   DefineLegalizerInfo(A, {
2320     getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF)
2321         .libcallFor({{s32, s32}, {s64, s64}, {s128, s128}});
2322   });
2323 
2324   LLT S32{LLT::scalar(32)};
2325   LLT S64{LLT::scalar(64)};
2326   LLT S128{LLT::scalar(128)};
2327   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2328   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2329 
2330   auto MIBCtlz32 =
2331       B.buildInstr(TargetOpcode::G_CTLZ_ZERO_UNDEF, {S32}, {MIBTrunc});
2332   auto MIBCtlz64 =
2333       B.buildInstr(TargetOpcode::G_CTLZ_ZERO_UNDEF, {S64}, {Copies[0]});
2334   auto MIBCtlz128 =
2335       B.buildInstr(TargetOpcode::G_CTLZ_ZERO_UNDEF, {S128}, {MIBExt});
2336 
2337   AInfo Info(MF->getSubtarget());
2338   DummyGISelObserver Observer;
2339   LostDebugLocObserver DummyLocObserver("");
2340   LegalizerHelper Helper(*MF, Info, Observer, B);
2341 
2342   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2343             Helper.libcall(*MIBCtlz32, DummyLocObserver));
2344   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2345             Helper.libcall(*MIBCtlz64, DummyLocObserver));
2346   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2347             Helper.libcall(*MIBCtlz128, DummyLocObserver));
2348 
2349   const auto *CheckStr = R"(
2350   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2351   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2352   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2353   CHECK: $w0 = COPY [[TRUNC]]
2354   CHECK: BL &__clzsi2
2355   CHECK: $x0 = COPY [[COPY]]
2356   CHECK: BL &__clzdi2
2357   CHECK: [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[ANYEXT]]
2358   CHECK: $x0 = COPY [[UV]]
2359   CHECK: $x1 = COPY [[UV1]]
2360   CHECK: BL &__clzti2
2361   )";
2362 
2363   // Check
2364   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2365 }
2366 
2367 TEST_F(AArch64GISelMITest, LibcallFAdd) {
2368   setUp();
2369   if (!TM)
2370     return;
2371 
2372   // Declare your legalization info
2373   DefineLegalizerInfo(A, {
2374     getActionDefinitionsBuilder(G_FADD).libcallFor({s32, s64, s128});
2375   });
2376 
2377   LLT S32{LLT::scalar(32)};
2378   LLT S64{LLT::scalar(64)};
2379   LLT S128{LLT::scalar(128)};
2380   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2381   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2382 
2383   auto MIBAdd32 =
2384       B.buildInstr(TargetOpcode::G_FADD, {S32}, {MIBTrunc, MIBTrunc});
2385   auto MIBAdd64 =
2386       B.buildInstr(TargetOpcode::G_FADD, {S64}, {Copies[0], Copies[0]});
2387   auto MIBAdd128 = B.buildInstr(TargetOpcode::G_FADD, {S128}, {MIBExt, MIBExt});
2388 
2389   AInfo Info(MF->getSubtarget());
2390   DummyGISelObserver Observer;
2391   LostDebugLocObserver DummyLocObserver("");
2392   LegalizerHelper Helper(*MF, Info, Observer, B);
2393 
2394   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2395             Helper.libcall(*MIBAdd32, DummyLocObserver));
2396   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2397             Helper.libcall(*MIBAdd64, DummyLocObserver));
2398   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2399             Helper.libcall(*MIBAdd128, DummyLocObserver));
2400 
2401   const auto *CheckStr = R"(
2402   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2403   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2404   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2405   CHECK: $s0 = COPY [[TRUNC]]
2406   CHECK: $s1 = COPY [[TRUNC]]
2407   CHECK: BL &__addsf3
2408   CHECK: $d0 = COPY [[COPY]]
2409   CHECK: $d1 = COPY [[COPY]]
2410   CHECK: BL &__adddf3
2411   CHECK: $q0 = COPY [[ANYEXT]]
2412   CHECK: $q1 = COPY [[ANYEXT]]
2413   CHECK: BL &__addtf3
2414   )";
2415 
2416   // Check
2417   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2418 }
2419 
2420 TEST_F(AArch64GISelMITest, LibcallFSub) {
2421   setUp();
2422   if (!TM)
2423     return;
2424 
2425   // Declare your legalization info
2426   DefineLegalizerInfo(A, {
2427     getActionDefinitionsBuilder(G_FSUB).libcallFor({s32, s64, s128});
2428   });
2429 
2430   LLT S32{LLT::scalar(32)};
2431   LLT S64{LLT::scalar(64)};
2432   LLT S128{LLT::scalar(128)};
2433   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2434   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2435 
2436   auto MIBSub32 =
2437       B.buildInstr(TargetOpcode::G_FSUB, {S32}, {MIBTrunc, MIBTrunc});
2438   auto MIBSub64 =
2439       B.buildInstr(TargetOpcode::G_FSUB, {S64}, {Copies[0], Copies[0]});
2440   auto MIBSub128 = B.buildInstr(TargetOpcode::G_FSUB, {S128}, {MIBExt, MIBExt});
2441 
2442   AInfo Info(MF->getSubtarget());
2443   DummyGISelObserver Observer;
2444   LostDebugLocObserver DummyLocObserver("");
2445   LegalizerHelper Helper(*MF, Info, Observer, B);
2446 
2447   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2448             Helper.libcall(*MIBSub32, DummyLocObserver));
2449   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2450             Helper.libcall(*MIBSub64, DummyLocObserver));
2451   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2452             Helper.libcall(*MIBSub128, DummyLocObserver));
2453 
2454   const auto *CheckStr = R"(
2455   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2456   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2457   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2458   CHECK: $s0 = COPY [[TRUNC]]
2459   CHECK: $s1 = COPY [[TRUNC]]
2460   CHECK: BL &__subsf3
2461   CHECK: $d0 = COPY [[COPY]]
2462   CHECK: $d1 = COPY [[COPY]]
2463   CHECK: BL &__subdf3
2464   CHECK: $q0 = COPY [[ANYEXT]]
2465   CHECK: $q1 = COPY [[ANYEXT]]
2466   CHECK: BL &__subtf3
2467   )";
2468 
2469   // Check
2470   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2471 }
2472 
2473 TEST_F(AArch64GISelMITest, LibcallFMul) {
2474   setUp();
2475   if (!TM)
2476     return;
2477 
2478   // Declare your legalization info
2479   DefineLegalizerInfo(A, {
2480     getActionDefinitionsBuilder(G_FMUL).libcallFor({s32, s64, s128});
2481   });
2482 
2483   LLT S32{LLT::scalar(32)};
2484   LLT S64{LLT::scalar(64)};
2485   LLT S128{LLT::scalar(128)};
2486   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2487   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2488 
2489   auto MIBMul32 =
2490       B.buildInstr(TargetOpcode::G_FMUL, {S32}, {MIBTrunc, MIBTrunc});
2491   auto MIBMul64 =
2492       B.buildInstr(TargetOpcode::G_FMUL, {S64}, {Copies[0], Copies[0]});
2493   auto MIBMul128 = B.buildInstr(TargetOpcode::G_FMUL, {S128}, {MIBExt, MIBExt});
2494 
2495   AInfo Info(MF->getSubtarget());
2496   DummyGISelObserver Observer;
2497   LegalizerHelper Helper(*MF, Info, Observer, B);
2498   LostDebugLocObserver DummyLocObserver("");
2499 
2500   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2501             Helper.libcall(*MIBMul32, DummyLocObserver));
2502   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2503             Helper.libcall(*MIBMul64, DummyLocObserver));
2504   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2505             Helper.libcall(*MIBMul128, DummyLocObserver));
2506 
2507   const auto *CheckStr = R"(
2508   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2509   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2510   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2511   CHECK: $s0 = COPY [[TRUNC]]
2512   CHECK: $s1 = COPY [[TRUNC]]
2513   CHECK: BL &__mulsf3
2514   CHECK: $d0 = COPY [[COPY]]
2515   CHECK: $d1 = COPY [[COPY]]
2516   CHECK: BL &__muldf3
2517   CHECK: $q0 = COPY [[ANYEXT]]
2518   CHECK: $q1 = COPY [[ANYEXT]]
2519   CHECK: BL &__multf3
2520   )";
2521 
2522   // Check
2523   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2524 }
2525 
2526 TEST_F(AArch64GISelMITest, LibcallFDiv) {
2527   setUp();
2528   if (!TM)
2529     return;
2530 
2531   // Declare your legalization info
2532   DefineLegalizerInfo(A, {
2533     getActionDefinitionsBuilder(G_FDIV).libcallFor({s32, s64, s128});
2534   });
2535 
2536   LLT S32{LLT::scalar(32)};
2537   LLT S64{LLT::scalar(64)};
2538   LLT S128{LLT::scalar(128)};
2539   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2540   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2541 
2542   auto MIBDiv32 =
2543       B.buildInstr(TargetOpcode::G_FDIV, {S32}, {MIBTrunc, MIBTrunc});
2544   auto MIBDiv64 =
2545       B.buildInstr(TargetOpcode::G_FDIV, {S64}, {Copies[0], Copies[0]});
2546   auto MIBDiv128 = B.buildInstr(TargetOpcode::G_FDIV, {S128}, {MIBExt, MIBExt});
2547 
2548   AInfo Info(MF->getSubtarget());
2549   DummyGISelObserver Observer;
2550   LostDebugLocObserver DummyLocObserver("");
2551   LegalizerHelper Helper(*MF, Info, Observer, B);
2552 
2553   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2554             Helper.libcall(*MIBDiv32, DummyLocObserver));
2555   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2556             Helper.libcall(*MIBDiv64, DummyLocObserver));
2557   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2558             Helper.libcall(*MIBDiv128, DummyLocObserver));
2559 
2560   const auto *CheckStr = R"(
2561   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2562   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2563   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2564   CHECK: $s0 = COPY [[TRUNC]]
2565   CHECK: $s1 = COPY [[TRUNC]]
2566   CHECK: BL &__divsf3
2567   CHECK: $d0 = COPY [[COPY]]
2568   CHECK: $d1 = COPY [[COPY]]
2569   CHECK: BL &__divdf3
2570   CHECK: $q0 = COPY [[ANYEXT]]
2571   CHECK: $q1 = COPY [[ANYEXT]]
2572   CHECK: BL &__divtf3
2573   )";
2574 
2575   // Check
2576   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2577 }
2578 
2579 TEST_F(AArch64GISelMITest, LibcallFExp) {
2580   setUp();
2581   if (!TM)
2582     return;
2583 
2584   // Declare your legalization info
2585   DefineLegalizerInfo(A, {
2586     getActionDefinitionsBuilder(G_FEXP).libcallFor({s32, s64, s128});
2587   });
2588 
2589   LLT S32{LLT::scalar(32)};
2590   LLT S64{LLT::scalar(64)};
2591   LLT S128{LLT::scalar(128)};
2592   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2593   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2594 
2595   auto MIBExp32 = B.buildInstr(TargetOpcode::G_FEXP, {S32}, {MIBTrunc});
2596   auto MIBExp64 = B.buildInstr(TargetOpcode::G_FEXP, {S64}, {Copies[0]});
2597   auto MIBExp128 = B.buildInstr(TargetOpcode::G_FEXP, {S128}, {MIBExt});
2598 
2599   AInfo Info(MF->getSubtarget());
2600   DummyGISelObserver Observer;
2601   LostDebugLocObserver DummyLocObserver("");
2602   LegalizerHelper Helper(*MF, Info, Observer, B);
2603 
2604   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2605             Helper.libcall(*MIBExp32, DummyLocObserver));
2606   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2607             Helper.libcall(*MIBExp64, DummyLocObserver));
2608   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2609             Helper.libcall(*MIBExp128, DummyLocObserver));
2610 
2611   const auto *CheckStr = R"(
2612   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2613   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2614   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2615   CHECK: $s0 = COPY [[TRUNC]]
2616   CHECK: BL &expf
2617   CHECK: $d0 = COPY [[COPY]]
2618   CHECK: BL &exp
2619   CHECK: $q0 = COPY [[ANYEXT]]
2620   CHECK: BL &expl
2621   )";
2622 
2623   // Check
2624   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2625 }
2626 
2627 TEST_F(AArch64GISelMITest, LibcallFExp2) {
2628   setUp();
2629   if (!TM)
2630     return;
2631 
2632   // Declare your legalization info
2633   DefineLegalizerInfo(A, {
2634     getActionDefinitionsBuilder(G_FEXP2).libcallFor({s32, s64, s128});
2635   });
2636 
2637   LLT S32{LLT::scalar(32)};
2638   LLT S64{LLT::scalar(64)};
2639   LLT S128{LLT::scalar(128)};
2640   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2641   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2642 
2643   auto MIBExp232 = B.buildInstr(TargetOpcode::G_FEXP2, {S32}, {MIBTrunc});
2644   auto MIBExp264 = B.buildInstr(TargetOpcode::G_FEXP2, {S64}, {Copies[0]});
2645   auto MIBExp2128 = B.buildInstr(TargetOpcode::G_FEXP2, {S128}, {MIBExt});
2646 
2647   AInfo Info(MF->getSubtarget());
2648   DummyGISelObserver Observer;
2649   LostDebugLocObserver DummyLocObserver("");
2650   LegalizerHelper Helper(*MF, Info, Observer, B);
2651 
2652   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2653             Helper.libcall(*MIBExp232, DummyLocObserver));
2654   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2655             Helper.libcall(*MIBExp264, DummyLocObserver));
2656   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2657             Helper.libcall(*MIBExp2128, DummyLocObserver));
2658 
2659   const auto *CheckStr = R"(
2660   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2661   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2662   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2663   CHECK: $s0 = COPY [[TRUNC]]
2664   CHECK: BL &exp2f
2665   CHECK: $d0 = COPY [[COPY]]
2666   CHECK: BL &exp2
2667   CHECK: $q0 = COPY [[ANYEXT]]
2668   CHECK: BL &exp2l
2669   )";
2670 
2671   // Check
2672   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2673 }
2674 
2675 TEST_F(AArch64GISelMITest, LibcallFRem) {
2676   setUp();
2677   if (!TM)
2678     return;
2679 
2680   // Declare your legalization info
2681   DefineLegalizerInfo(A, {
2682     getActionDefinitionsBuilder(G_FREM).libcallFor({s32, s64, s128});
2683   });
2684 
2685   LLT S32{LLT::scalar(32)};
2686   LLT S64{LLT::scalar(64)};
2687   LLT S128{LLT::scalar(128)};
2688   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2689   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2690 
2691   auto MIBFRem32 = B.buildInstr(TargetOpcode::G_FREM, {S32}, {MIBTrunc});
2692   auto MIBFRem64 = B.buildInstr(TargetOpcode::G_FREM, {S64}, {Copies[0]});
2693   auto MIBFRem128 = B.buildInstr(TargetOpcode::G_FREM, {S128}, {MIBExt});
2694 
2695   AInfo Info(MF->getSubtarget());
2696   DummyGISelObserver Observer;
2697   LostDebugLocObserver DummyLocObserver("");
2698   LegalizerHelper Helper(*MF, Info, Observer, B);
2699 
2700   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2701             Helper.libcall(*MIBFRem32, DummyLocObserver));
2702   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2703             Helper.libcall(*MIBFRem64, DummyLocObserver));
2704   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2705             Helper.libcall(*MIBFRem128, DummyLocObserver));
2706 
2707   const auto *CheckStr = R"(
2708   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2709   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2710   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2711   CHECK: $s0 = COPY [[TRUNC]]
2712   CHECK: BL &fmodf
2713   CHECK: $d0 = COPY [[COPY]]
2714   CHECK: BL &fmod
2715   CHECK: $q0 = COPY [[ANYEXT]]
2716   CHECK: BL &fmodl
2717   )";
2718 
2719   // Check
2720   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2721 }
2722 
2723 TEST_F(AArch64GISelMITest, LibcallFPow) {
2724   setUp();
2725   if (!TM)
2726     return;
2727 
2728   // Declare your legalization info
2729   DefineLegalizerInfo(A, {
2730     getActionDefinitionsBuilder(G_FPOW).libcallFor({s32, s64, s128});
2731   });
2732 
2733   LLT S32{LLT::scalar(32)};
2734   LLT S64{LLT::scalar(64)};
2735   LLT S128{LLT::scalar(128)};
2736   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2737   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2738 
2739   auto MIBPow32 = B.buildInstr(TargetOpcode::G_FPOW, {S32}, {MIBTrunc});
2740   auto MIBPow64 = B.buildInstr(TargetOpcode::G_FPOW, {S64}, {Copies[0]});
2741   auto MIBPow128 = B.buildInstr(TargetOpcode::G_FPOW, {S128}, {MIBExt});
2742 
2743   AInfo Info(MF->getSubtarget());
2744   DummyGISelObserver Observer;
2745   LostDebugLocObserver DummyLocObserver("");
2746   LegalizerHelper Helper(*MF, Info, Observer, B);
2747 
2748   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2749             Helper.libcall(*MIBPow32, DummyLocObserver));
2750   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2751             Helper.libcall(*MIBPow64, DummyLocObserver));
2752   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2753             Helper.libcall(*MIBPow128, DummyLocObserver));
2754 
2755   const auto *CheckStr = R"(
2756   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2757   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2758   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2759   CHECK: $s0 = COPY [[TRUNC]]
2760   CHECK: BL &powf
2761   CHECK: $d0 = COPY [[COPY]]
2762   CHECK: BL &pow
2763   CHECK: $q0 = COPY [[ANYEXT]]
2764   CHECK: BL &powl
2765   )";
2766 
2767   // Check
2768   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2769 }
2770 
2771 TEST_F(AArch64GISelMITest, LibcallFMa) {
2772   setUp();
2773   if (!TM)
2774     return;
2775 
2776   // Declare your legalization info
2777   DefineLegalizerInfo(A, {
2778     getActionDefinitionsBuilder(G_FMA).libcallFor({s32, s64, s128});
2779   });
2780 
2781   LLT S32{LLT::scalar(32)};
2782   LLT S64{LLT::scalar(64)};
2783   LLT S128{LLT::scalar(128)};
2784   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2785   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2786 
2787   auto MIBMa32 = B.buildInstr(TargetOpcode::G_FMA, {S32}, {MIBTrunc, MIBTrunc});
2788   auto MIBMa64 =
2789       B.buildInstr(TargetOpcode::G_FMA, {S64}, {Copies[0], Copies[0]});
2790   auto MIBMa128 = B.buildInstr(TargetOpcode::G_FMA, {S128}, {MIBExt, MIBExt});
2791 
2792   AInfo Info(MF->getSubtarget());
2793   DummyGISelObserver Observer;
2794   LostDebugLocObserver DummyLocObserver("");
2795   LegalizerHelper Helper(*MF, Info, Observer, B);
2796 
2797   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2798             Helper.libcall(*MIBMa32, DummyLocObserver));
2799   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2800             Helper.libcall(*MIBMa64, DummyLocObserver));
2801   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2802             Helper.libcall(*MIBMa128, DummyLocObserver));
2803 
2804   const auto *CheckStr = R"(
2805   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2806   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2807   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2808   CHECK: $s0 = COPY [[TRUNC]]
2809   CHECK: BL &fmaf
2810   CHECK: $d0 = COPY [[COPY]]
2811   CHECK: BL &fma
2812   CHECK: $q0 = COPY [[ANYEXT]]
2813   CHECK: BL &fmal
2814   )";
2815 
2816   // Check
2817   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2818 }
2819 
2820 TEST_F(AArch64GISelMITest, LibcallFCeil) {
2821   setUp();
2822   if (!TM)
2823     return;
2824 
2825   // Declare your legalization info
2826   DefineLegalizerInfo(A, {
2827     getActionDefinitionsBuilder(G_FCEIL).libcallFor({s32, s64, s128});
2828   });
2829 
2830   LLT S32{LLT::scalar(32)};
2831   LLT S64{LLT::scalar(64)};
2832   LLT S128{LLT::scalar(128)};
2833   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2834   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2835 
2836   auto MIBCeil32 = B.buildInstr(TargetOpcode::G_FCEIL, {S32}, {MIBTrunc});
2837   auto MIBCeil64 = B.buildInstr(TargetOpcode::G_FCEIL, {S64}, {Copies[0]});
2838   auto MIBCeil128 = B.buildInstr(TargetOpcode::G_FCEIL, {S128}, {MIBExt});
2839 
2840   AInfo Info(MF->getSubtarget());
2841   DummyGISelObserver Observer;
2842   LegalizerHelper Helper(*MF, Info, Observer, B);
2843   LostDebugLocObserver DummyLocObserver("");
2844 
2845   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2846             Helper.libcall(*MIBCeil32, DummyLocObserver));
2847   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2848             Helper.libcall(*MIBCeil64, DummyLocObserver));
2849   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2850             Helper.libcall(*MIBCeil128, DummyLocObserver));
2851 
2852   const auto *CheckStr = R"(
2853   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2854   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2855   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2856   CHECK: $s0 = COPY [[TRUNC]]
2857   CHECK: BL &ceilf
2858   CHECK: $d0 = COPY [[COPY]]
2859   CHECK: BL &ceil
2860   CHECK: $q0 = COPY [[ANYEXT]]
2861   CHECK: BL &ceill
2862   )";
2863 
2864   // Check
2865   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2866 }
2867 
2868 TEST_F(AArch64GISelMITest, LibcallFFloor) {
2869   setUp();
2870   if (!TM)
2871     return;
2872 
2873   // Declare your legalization info
2874   DefineLegalizerInfo(A, {
2875     getActionDefinitionsBuilder(G_FFLOOR).libcallFor({s32, s64, s128});
2876   });
2877 
2878   LLT S32{LLT::scalar(32)};
2879   LLT S64{LLT::scalar(64)};
2880   LLT S128{LLT::scalar(128)};
2881   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2882   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2883 
2884   auto MIBFloor32 = B.buildInstr(TargetOpcode::G_FFLOOR, {S32}, {MIBTrunc});
2885   auto MIBFloor64 = B.buildInstr(TargetOpcode::G_FFLOOR, {S64}, {Copies[0]});
2886   auto MIBFloor128 = B.buildInstr(TargetOpcode::G_FFLOOR, {S128}, {MIBExt});
2887 
2888   AInfo Info(MF->getSubtarget());
2889   DummyGISelObserver Observer;
2890   LegalizerHelper Helper(*MF, Info, Observer, B);
2891   LostDebugLocObserver DummyLocObserver("");
2892 
2893   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2894             Helper.libcall(*MIBFloor32, DummyLocObserver));
2895   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2896             Helper.libcall(*MIBFloor64, DummyLocObserver));
2897   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2898             Helper.libcall(*MIBFloor128, DummyLocObserver));
2899 
2900   const auto *CheckStr = R"(
2901   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2902   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2903   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2904   CHECK: $s0 = COPY [[TRUNC]]
2905   CHECK: BL &floorf
2906   CHECK: $d0 = COPY [[COPY]]
2907   CHECK: BL &floor
2908   CHECK: $q0 = COPY [[ANYEXT]]
2909   CHECK: BL &floorl
2910   )";
2911 
2912   // Check
2913   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2914 }
2915 
2916 TEST_F(AArch64GISelMITest, LibcallFMinNum) {
2917   setUp();
2918   if (!TM)
2919     return;
2920 
2921   // Declare your legalization info
2922   DefineLegalizerInfo(A, {
2923     getActionDefinitionsBuilder(G_FMINNUM).libcallFor({s32, s64, s128});
2924   });
2925 
2926   LLT S32{LLT::scalar(32)};
2927   LLT S64{LLT::scalar(64)};
2928   LLT S128{LLT::scalar(128)};
2929   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2930   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2931 
2932   auto MIBMin32 = B.buildFMinNum(S32, MIBTrunc, MIBTrunc);
2933   auto MIBMin64 = B.buildFMinNum(S64, Copies[0], Copies[0]);
2934   auto MIBMin128 = B.buildFMinNum(S128, MIBExt, MIBExt);
2935 
2936   AInfo Info(MF->getSubtarget());
2937   DummyGISelObserver Observer;
2938   LegalizerHelper Helper(*MF, Info, Observer, B);
2939   LostDebugLocObserver DummyLocObserver("");
2940 
2941   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2942             Helper.libcall(*MIBMin32, DummyLocObserver));
2943   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2944             Helper.libcall(*MIBMin64, DummyLocObserver));
2945   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2946             Helper.libcall(*MIBMin128, DummyLocObserver));
2947 
2948   const auto *CheckStr = R"(
2949   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2950   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2951   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2952   CHECK: $s0 = COPY [[TRUNC]]
2953   CHECK: $s1 = COPY [[TRUNC]]
2954   CHECK: BL &fminf
2955   CHECK: $d0 = COPY [[COPY]]
2956   CHECK: $d1 = COPY [[COPY]]
2957   CHECK: BL &fmin
2958   CHECK: $q0 = COPY [[ANYEXT]]
2959   CHECK: $q1 = COPY [[ANYEXT]]
2960   CHECK: BL &fminl
2961   )";
2962 
2963   // Check
2964   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2965 }
2966 
2967 TEST_F(AArch64GISelMITest, LibcallFMaxNum) {
2968   setUp();
2969   if (!TM)
2970     return;
2971 
2972   // Declare your legalization info
2973   DefineLegalizerInfo(A, {
2974     getActionDefinitionsBuilder(G_FMAXNUM).libcallFor({s32, s64, s128});
2975   });
2976 
2977   LLT S32{LLT::scalar(32)};
2978   LLT S64{LLT::scalar(64)};
2979   LLT S128{LLT::scalar(128)};
2980   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2981   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2982 
2983   auto MIBMax32 = B.buildFMaxNum(S32, MIBTrunc, MIBTrunc);
2984   auto MIBMax64 = B.buildFMaxNum(S64, Copies[0], Copies[0]);
2985   auto MIBMax128 = B.buildFMaxNum(S128, MIBExt, MIBExt);
2986 
2987   AInfo Info(MF->getSubtarget());
2988   DummyGISelObserver Observer;
2989   LegalizerHelper Helper(*MF, Info, Observer, B);
2990   LostDebugLocObserver DummyLocObserver("");
2991 
2992   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2993             Helper.libcall(*MIBMax32, DummyLocObserver));
2994   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2995             Helper.libcall(*MIBMax64, DummyLocObserver));
2996   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2997             Helper.libcall(*MIBMax128, DummyLocObserver));
2998 
2999   const auto *CheckStr = R"(
3000   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
3001   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
3002   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
3003   CHECK: $s0 = COPY [[TRUNC]]
3004   CHECK: $s1 = COPY [[TRUNC]]
3005   CHECK: BL &fmaxf
3006   CHECK: $d0 = COPY [[COPY]]
3007   CHECK: $d1 = COPY [[COPY]]
3008   CHECK: BL &fmax
3009   CHECK: $q0 = COPY [[ANYEXT]]
3010   CHECK: $q1 = COPY [[ANYEXT]]
3011   CHECK: BL &fmaxl
3012   )";
3013 
3014   // Check
3015   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3016 }
3017 
3018 TEST_F(AArch64GISelMITest, LibcallFSqrt) {
3019   setUp();
3020   if (!TM)
3021     return;
3022 
3023   // Declare your legalization info
3024   DefineLegalizerInfo(A, {
3025     getActionDefinitionsBuilder(G_FSQRT).libcallFor({s32, s64, s128});
3026   });
3027 
3028   LLT S32{LLT::scalar(32)};
3029   LLT S64{LLT::scalar(64)};
3030   LLT S128{LLT::scalar(128)};
3031   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
3032   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
3033 
3034   auto MIBSqrt32 = B.buildInstr(TargetOpcode::G_FSQRT, {S32}, {MIBTrunc});
3035   auto MIBSqrt64 = B.buildInstr(TargetOpcode::G_FSQRT, {S64}, {Copies[0]});
3036   auto MIBSqrt128 = B.buildInstr(TargetOpcode::G_FSQRT, {S128}, {MIBExt});
3037 
3038   AInfo Info(MF->getSubtarget());
3039   DummyGISelObserver Observer;
3040   LegalizerHelper Helper(*MF, Info, Observer, B);
3041   LostDebugLocObserver DummyLocObserver("");
3042 
3043   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3044             Helper.libcall(*MIBSqrt32, DummyLocObserver));
3045   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3046             Helper.libcall(*MIBSqrt64, DummyLocObserver));
3047   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3048             Helper.libcall(*MIBSqrt128, DummyLocObserver));
3049 
3050   const auto *CheckStr = R"(
3051   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
3052   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
3053   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
3054   CHECK: $s0 = COPY [[TRUNC]]
3055   CHECK: BL &sqrtf
3056   CHECK: $d0 = COPY [[COPY]]
3057   CHECK: BL &sqrt
3058   CHECK: $q0 = COPY [[ANYEXT]]
3059   CHECK: BL &sqrtl
3060   )";
3061 
3062   // Check
3063   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3064 }
3065 
3066 TEST_F(AArch64GISelMITest, LibcallFRint) {
3067   setUp();
3068   if (!TM)
3069     return;
3070 
3071   // Declare your legalization info
3072   DefineLegalizerInfo(A, {
3073     getActionDefinitionsBuilder(G_FRINT).libcallFor({s32, s64, s128});
3074   });
3075 
3076   LLT S32{LLT::scalar(32)};
3077   LLT S64{LLT::scalar(64)};
3078   LLT S128{LLT::scalar(128)};
3079   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
3080   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
3081 
3082   auto MIBRint32 = B.buildInstr(TargetOpcode::G_FRINT, {S32}, {MIBTrunc});
3083   auto MIBRint64 = B.buildInstr(TargetOpcode::G_FRINT, {S64}, {Copies[0]});
3084   auto MIBRint128 = B.buildInstr(TargetOpcode::G_FRINT, {S128}, {MIBExt});
3085 
3086   AInfo Info(MF->getSubtarget());
3087   DummyGISelObserver Observer;
3088   LegalizerHelper Helper(*MF, Info, Observer, B);
3089   LostDebugLocObserver DummyLocObserver("");
3090 
3091   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3092             Helper.libcall(*MIBRint32, DummyLocObserver));
3093   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3094             Helper.libcall(*MIBRint64, DummyLocObserver));
3095   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3096             Helper.libcall(*MIBRint128, DummyLocObserver));
3097 
3098   const auto *CheckStr = R"(
3099   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
3100   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
3101   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
3102   CHECK: $s0 = COPY [[TRUNC]]
3103   CHECK: BL &rintf
3104   CHECK: $d0 = COPY [[COPY]]
3105   CHECK: BL &rint
3106   CHECK: $q0 = COPY [[ANYEXT]]
3107   CHECK: BL &rintl
3108   )";
3109 
3110   // Check
3111   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3112 }
3113 
3114 TEST_F(AArch64GISelMITest, LibcallFNearbyInt) {
3115   setUp();
3116   if (!TM)
3117     return;
3118 
3119   // Declare your legalization info
3120   DefineLegalizerInfo(A, {
3121     getActionDefinitionsBuilder(G_FNEARBYINT).libcallFor({s32, s64, s128});
3122   });
3123 
3124   LLT S32{LLT::scalar(32)};
3125   LLT S64{LLT::scalar(64)};
3126   LLT S128{LLT::scalar(128)};
3127   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
3128   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
3129 
3130   auto MIBNearbyInt32 =
3131       B.buildInstr(TargetOpcode::G_FNEARBYINT, {S32}, {MIBTrunc});
3132   auto MIBNearbyInt64 =
3133       B.buildInstr(TargetOpcode::G_FNEARBYINT, {S64}, {Copies[0]});
3134   auto MIBNearbyInt128 =
3135       B.buildInstr(TargetOpcode::G_FNEARBYINT, {S128}, {MIBExt});
3136 
3137   AInfo Info(MF->getSubtarget());
3138   DummyGISelObserver Observer;
3139   LegalizerHelper Helper(*MF, Info, Observer, B);
3140   LostDebugLocObserver DummyLocObserver("");
3141 
3142   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3143             Helper.libcall(*MIBNearbyInt32, DummyLocObserver));
3144   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3145             Helper.libcall(*MIBNearbyInt64, DummyLocObserver));
3146   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3147             Helper.libcall(*MIBNearbyInt128, DummyLocObserver));
3148 
3149   const auto *CheckStr = R"(
3150   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
3151   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
3152   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
3153   CHECK: $s0 = COPY [[TRUNC]]
3154   CHECK: BL &nearbyintf
3155   CHECK: $d0 = COPY [[COPY]]
3156   CHECK: BL &nearbyint
3157   CHECK: $q0 = COPY [[ANYEXT]]
3158   CHECK: BL &nearbyintl
3159   )";
3160 
3161   // Check
3162   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3163 }
3164 
3165 TEST_F(AArch64GISelMITest, NarrowScalarExtract) {
3166   setUp();
3167   if (!TM)
3168     return;
3169 
3170   // Declare your legalization info
3171   DefineLegalizerInfo(A, {
3172     getActionDefinitionsBuilder(G_UNMERGE_VALUES).legalFor({{s32, s64}});
3173     getActionDefinitionsBuilder(G_EXTRACT).legalForTypeWithAnyImm({{s16, s32}});
3174   });
3175 
3176   LLT S16{LLT::scalar(16)};
3177   LLT S32{LLT::scalar(32)};
3178 
3179   auto MIBExtractS32 = B.buildExtract(S32, Copies[1], 32);
3180   auto MIBExtractS16 = B.buildExtract(S16, Copies[1], 0);
3181 
3182   AInfo Info(MF->getSubtarget());
3183   DummyGISelObserver Observer;
3184   LegalizerHelper Helper(*MF, Info, Observer, B);
3185 
3186   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3187             Helper.narrowScalar(*MIBExtractS32, 1, S32));
3188 
3189   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3190             Helper.narrowScalar(*MIBExtractS16, 1, S32));
3191 
3192   const auto *CheckStr = R"(
3193   CHECK: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES
3194   CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY [[UV1]]
3195   CHECK: [[UV3:%[0-9]+]]:_(s32), [[UV4:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES
3196   CHECK: [[EXTR:%[0-9]+]]:_(s16) = G_EXTRACT [[UV3]]:_(s32), 0
3197   CHECK: [[COPY:%[0-9]+]]:_(s16) = COPY [[EXTR]]
3198   )";
3199 
3200   // Check
3201   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3202 }
3203 
3204 TEST_F(AArch64GISelMITest, LowerInsert) {
3205   setUp();
3206   if (!TM)
3207     return;
3208 
3209   // Declare your legalization info
3210   DefineLegalizerInfo(A, { getActionDefinitionsBuilder(G_INSERT).lower(); });
3211 
3212   LLT S32{LLT::scalar(32)};
3213   LLT S64{LLT::scalar(64)};
3214   LLT P0{LLT::pointer(0, 64)};
3215   LLT P1{LLT::pointer(1, 32)};
3216   LLT V2S32{LLT::fixed_vector(2, 32)};
3217 
3218   auto TruncS32 = B.buildTrunc(S32, Copies[0]);
3219   auto IntToPtrP0 = B.buildIntToPtr(P0, Copies[0]);
3220   auto IntToPtrP1 = B.buildIntToPtr(P1, TruncS32);
3221   auto BitcastV2S32 = B.buildBitcast(V2S32, Copies[0]);
3222 
3223   auto InsertS64S32 = B.buildInsert(S64, Copies[0], TruncS32, 0);
3224   auto InsertS64P1 = B.buildInsert(S64, Copies[0], IntToPtrP1, 8);
3225   auto InsertP0S32 = B.buildInsert(P0, IntToPtrP0, TruncS32, 16);
3226   auto InsertP0P1 = B.buildInsert(P0, IntToPtrP0, IntToPtrP1, 4);
3227   auto InsertV2S32S32 = B.buildInsert(V2S32, BitcastV2S32, TruncS32, 32);
3228   auto InsertV2S32P1 = B.buildInsert(V2S32, BitcastV2S32, IntToPtrP1, 0);
3229 
3230   AInfo Info(MF->getSubtarget());
3231   DummyGISelObserver Observer;
3232   LegalizerHelper Helper(*MF, Info, Observer, B);
3233 
3234   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3235             Helper.lower(*InsertS64S32, 0, LLT{}));
3236 
3237   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3238             Helper.lower(*InsertS64P1, 0, LLT{}));
3239 
3240   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3241             Helper.lower(*InsertP0S32, 0, LLT{}));
3242 
3243   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3244             Helper.lower(*InsertP0P1, 0, LLT{}));
3245 
3246   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3247             Helper.lower(*InsertV2S32S32, 0, LLT{}));
3248 
3249   EXPECT_EQ(LegalizerHelper::LegalizeResult::UnableToLegalize,
3250             Helper.lower(*InsertV2S32P1, 0, LLT{}));
3251 
3252   const auto *CheckStr = R"(
3253   CHECK: [[S64:%[0-9]+]]:_(s64) = COPY
3254   CHECK: [[S32:%[0-9]+]]:_(s32) = G_TRUNC [[S64]]
3255   CHECK: [[P0:%[0-9]+]]:_(p0) = G_INTTOPTR [[S64]]
3256   CHECK: [[P1:%[0-9]+]]:_(p1) = G_INTTOPTR [[S32]]
3257   CHECK: [[V2S32:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[S64]]
3258   CHECK: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[S32]]
3259   CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT
3260   CHECK: [[AND:%[0-9]+]]:_(s64) = G_AND [[S64]]:_, [[C]]:_
3261   CHECK: [[OR:%[0-9]+]]:_(s64) = G_OR [[AND]]:_, [[ZEXT]]:_
3262 
3263   CHECK: [[PTRTOINT:%[0-9]+]]:_(s32) = G_PTRTOINT [[P1]]
3264   CHECK: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[PTRTOINT]]
3265   CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT
3266   CHECK: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ZEXT]]:_, [[C]]:_(s64)
3267   CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT
3268   CHECK: [[AND:%[0-9]+]]:_(s64) = G_AND [[S64]]:_, [[C]]:_
3269   CHECK: [[OR:%[0-9]+]]:_(s64) = G_OR [[AND]]:_, [[SHL]]:_
3270 
3271   CHECK: [[PTRTOINT:%[0-9]+]]:_(s64) = G_PTRTOINT [[P0]]
3272   CHECK: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[S32]]
3273   CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT
3274   CHECK: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ZEXT]]:_, [[C]]:_(s64)
3275   CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT
3276   CHECK: [[AND:%[0-9]+]]:_(s64) = G_AND [[PTRTOINT]]:_, [[C]]:_
3277   CHECK: [[OR:%[0-9]+]]:_(s64) = G_OR [[AND]]:_, [[SHL]]:_
3278   CHECK: [[INTTOPTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[OR]]
3279 
3280   CHECK: [[PTRTOINT:%[0-9]+]]:_(s64) = G_PTRTOINT [[P0]]
3281   CHECK: [[PTRTOINT1:%[0-9]+]]:_(s32) = G_PTRTOINT [[P1]]
3282   CHECK: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[PTRTOINT1]]
3283   CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT
3284   CHECK: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ZEXT]]:_, [[C]]:_(s64)
3285   CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT
3286   CHECK: [[AND:%[0-9]+]]:_(s64) = G_AND [[PTRTOINT]]:_, [[C]]:_
3287   CHECK: [[OR:%[0-9]+]]:_(s64) = G_OR [[AND]]:_, [[SHL]]:_
3288   CHECK: [[INTTOPTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[OR]]
3289 
3290   CHECK: [[V2S32_E0:%[0-9]+]]:_(s32), [[V2S32_E1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[V2S32]]
3291   CHECK: [[BV:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[V2S32_E0]]:_(s32), [[S32]]:_(s32)
3292   )";
3293 
3294   // Check
3295   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3296 }
3297 
3298 // Test lowering of G_FFLOOR
3299 TEST_F(AArch64GISelMITest, LowerFFloor) {
3300   setUp();
3301   if (!TM)
3302     return;
3303 
3304   // Declare your legalization info
3305   DefineLegalizerInfo(A, {});
3306   // Build Instr
3307   auto Floor = B.buildFFloor(LLT::scalar(64), Copies[0], MachineInstr::MIFlag::FmNoInfs);
3308   AInfo Info(MF->getSubtarget());
3309   DummyGISelObserver Observer;
3310   LegalizerHelper Helper(*MF, Info, Observer, B);
3311   // Perform Legalization
3312   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3313             Helper.lower(*Floor, 0, LLT()));
3314 
3315   auto CheckStr = R"(
3316   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
3317   CHECK: [[TRUNC:%[0-9]+]]:_(s64) = ninf G_INTRINSIC_TRUNC [[COPY]]
3318   CHECK: [[ZERO:%[0-9]+]]:_(s64) = G_FCONSTANT double 0.000000e+00
3319   CHECK: [[CMP0:%[0-9]+]]:_(s1) = ninf G_FCMP floatpred(olt), [[COPY]]:_(s64), [[ZERO]]:_
3320   CHECK: [[CMP1:%[0-9]+]]:_(s1) = ninf G_FCMP floatpred(one), [[COPY]]:_(s64), [[TRUNC]]:_
3321   CHECK: [[AND:%[0-9]+]]:_(s1) = G_AND [[CMP0]]:_, [[CMP1]]:_
3322   CHECK: [[ITOFP:%[0-9]+]]:_(s64) = G_SITOFP [[AND]]
3323   = ninf G_FADD [[TRUNC]]:_, [[ITOFP]]:_
3324   )";
3325 
3326   // Check
3327   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3328 }
3329 
3330 // Test lowering of G_BSWAP
3331 TEST_F(AArch64GISelMITest, LowerBSWAP) {
3332   setUp();
3333   if (!TM)
3334     return;
3335 
3336   DefineLegalizerInfo(A, {});
3337 
3338   // Make sure vector lowering doesn't assert.
3339   auto Cast = B.buildBitcast(LLT::fixed_vector(2, 32), Copies[0]);
3340   auto BSwap = B.buildBSwap(LLT::fixed_vector(2, 32), Cast);
3341   AInfo Info(MF->getSubtarget());
3342   DummyGISelObserver Observer;
3343   LegalizerHelper Helper(*MF, Info, Observer, B);
3344   // Perform Legalization
3345   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3346             Helper.lower(*BSwap, 0, LLT()));
3347 
3348   auto CheckStr = R"(
3349   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
3350   CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[COPY]]
3351   CHECK: [[K24:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
3352   CHECK: [[SPLAT24:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[K24]]:_(s32), [[K24]]:_(s32)
3353   CHECK: [[SHL0:%[0-9]+]]:_(<2 x s32>) = G_SHL [[VEC]]:_, [[SPLAT24]]
3354   CHECK: [[SHR0:%[0-9]+]]:_(<2 x s32>) = G_LSHR [[VEC]]:_, [[SPLAT24]]
3355   CHECK: [[OR0:%[0-9]+]]:_(<2 x s32>) = G_OR [[SHR0]]:_, [[SHL0]]:_
3356   CHECK: [[KMASK:%[0-9]+]]:_(s32) = G_CONSTANT i32 65280
3357   CHECK: [[SPLATMASK:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[KMASK]]:_(s32), [[KMASK]]:_(s32)
3358   CHECK: [[K8:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
3359   CHECK: [[SPLAT8:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[K8]]:_(s32), [[K8]]:_(s32)
3360   CHECK: [[AND0:%[0-9]+]]:_(<2 x s32>) = G_AND [[VEC]]:_, [[SPLATMASK]]:_
3361   CHECK: [[SHL1:%[0-9]+]]:_(<2 x s32>) = G_SHL [[AND0]]:_, [[SPLAT8]]
3362   CHECK: [[OR1:%[0-9]+]]:_(<2 x s32>) = G_OR [[OR0]]:_, [[SHL1]]:_
3363   CHECK: [[SHR1:%[0-9]+]]:_(<2 x s32>) = G_LSHR [[VEC]]:_, [[SPLAT8]]
3364   CHECK: [[AND1:%[0-9]+]]:_(<2 x s32>) = G_AND [[SHR1]]:_, [[SPLATMASK]]:_
3365   CHECK: [[BSWAP:%[0-9]+]]:_(<2 x s32>) = G_OR [[OR1]]:_, [[AND1]]:_
3366   )";
3367 
3368   // Check
3369   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3370 }
3371 
3372 // Test lowering of G_SDIVREM into G_SDIV and G_SREM
3373 TEST_F(AArch64GISelMITest, LowerSDIVREM) {
3374   setUp();
3375   if (!TM)
3376     return;
3377 
3378   // Declare your legalization info
3379   DefineLegalizerInfo(
3380       A, { getActionDefinitionsBuilder(G_SDIVREM).lowerFor({s64}); });
3381 
3382   LLT S64{LLT::scalar(64)};
3383 
3384   // Build Instr
3385   auto SDivrem =
3386       B.buildInstr(TargetOpcode::G_SDIVREM, {S64, S64}, {Copies[0], Copies[1]});
3387   AInfo Info(MF->getSubtarget());
3388   DummyGISelObserver Observer;
3389   LegalizerHelper Helper(*MF, Info, Observer, B);
3390   // Perform Legalization
3391   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3392             Helper.lower(*SDivrem, 0, S64));
3393 
3394   const auto *CheckStr = R"(
3395   CHECK: [[DIV:%[0-9]+]]:_(s64) = G_SDIV %0:_, %1:_
3396   CHECK: [[REM:%[0-9]+]]:_(s64) = G_SREM %0:_, %1:_
3397   )";
3398 
3399   // Check
3400   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3401 }
3402 
3403 // Test lowering of G_UDIVREM into G_UDIV and G_UREM
3404 TEST_F(AArch64GISelMITest, LowerUDIVREM) {
3405   setUp();
3406   if (!TM)
3407     return;
3408 
3409   // Declare your legalization info
3410   DefineLegalizerInfo(
3411       A, { getActionDefinitionsBuilder(G_UDIVREM).lowerFor({s64}); });
3412 
3413   LLT S64{LLT::scalar(64)};
3414 
3415   // Build Instr
3416   auto UDivrem =
3417       B.buildInstr(TargetOpcode::G_UDIVREM, {S64, S64}, {Copies[0], Copies[1]});
3418   AInfo Info(MF->getSubtarget());
3419   DummyGISelObserver Observer;
3420   LegalizerHelper Helper(*MF, Info, Observer, B);
3421   // Perform Legalization
3422   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3423             Helper.lower(*UDivrem, 0, S64));
3424 
3425   const auto *CheckStr = R"(
3426   CHECK: [[DIV:%[0-9]+]]:_(s64) = G_UDIV %0:_, %1:_
3427   CHECK: [[REM:%[0-9]+]]:_(s64) = G_UREM %0:_, %1:_
3428   )";
3429 
3430   // Check
3431   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3432 }
3433 
3434 // Test widening of G_UNMERGE_VALUES
3435 TEST_F(AArch64GISelMITest, WidenUnmerge) {
3436   setUp();
3437   if (!TM)
3438     return;
3439 
3440   DefineLegalizerInfo(A, {});
3441 
3442   // Check that widening G_UNMERGE_VALUES to a larger type than the source type
3443   // works as expected
3444   LLT P0{LLT::pointer(0, 64)};
3445   LLT S32{LLT::scalar(32)};
3446   LLT S96{LLT::scalar(96)};
3447 
3448   auto IntToPtr = B.buildIntToPtr(P0, Copies[0]);
3449   auto UnmergePtr = B.buildUnmerge(S32, IntToPtr);
3450   auto UnmergeScalar = B.buildUnmerge(S32, Copies[0]);
3451 
3452   AInfo Info(MF->getSubtarget());
3453   DummyGISelObserver Observer;
3454   LegalizerHelper Helper(*MF, Info, Observer, B);
3455 
3456   // Perform Legalization
3457   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3458             Helper.widenScalar(*UnmergePtr, 0, S96));
3459 
3460   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3461             Helper.widenScalar(*UnmergeScalar, 0, S96));
3462 
3463   const auto *CheckStr = R"(
3464   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
3465   CHECK: [[PTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[COPY]]
3466   CHECK: [[INT:%[0-9]+]]:_(s64) = G_PTRTOINT [[PTR]]
3467   CHECK: [[ANYEXT:%[0-9]+]]:_(s96) = G_ANYEXT [[INT]]
3468   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[ANYEXT]]
3469   CHECK: [[C:%[0-9]+]]:_(s96) = G_CONSTANT i96 32
3470   CHECK: [[LSHR:%[0-9]+]]:_(s96) = G_LSHR [[ANYEXT]]:_, [[C]]
3471   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[LSHR]]
3472   CHECK: [[ANYEXT:%[0-9]+]]:_(s96) = G_ANYEXT [[COPY]]
3473   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[ANYEXT]]
3474   CHECK: [[C:%[0-9]+]]:_(s96) = G_CONSTANT i96 32
3475   CHECK: [[LSHR:%[0-9]+]]:_(s96) = G_LSHR [[ANYEXT]]:_, [[C]]
3476   CHECK: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC [[LSHR]]
3477   )";
3478 
3479   // Check
3480   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3481 }
3482 
3483 TEST_F(AArch64GISelMITest, BitcastLoad) {
3484   setUp();
3485   if (!TM)
3486     return;
3487 
3488   LLT P0 = LLT::pointer(0, 64);
3489   LLT S32 = LLT::scalar(32);
3490   LLT V4S8 = LLT::fixed_vector(4, 8);
3491   auto Ptr = B.buildUndef(P0);
3492 
3493   DefineLegalizerInfo(A, {});
3494 
3495   MachineMemOperand *MMO = B.getMF().getMachineMemOperand(
3496       MachinePointerInfo(), MachineMemOperand::MOLoad, 4, Align(4));
3497   auto Load = B.buildLoad(V4S8, Ptr, *MMO);
3498 
3499   AInfo Info(MF->getSubtarget());
3500   DummyGISelObserver Observer;
3501   B.setInsertPt(*EntryMBB, Load->getIterator());
3502   LegalizerHelper Helper(*MF, Info, Observer, B);
3503   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3504             Helper.bitcast(*Load, 0, S32));
3505 
3506   auto CheckStr = R"(
3507   CHECK: [[PTR:%[0-9]+]]:_(p0) = G_IMPLICIT_DEF
3508   CHECK: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD
3509   CHECK: [[CAST:%[0-9]+]]:_(<4 x s8>) = G_BITCAST [[LOAD]]
3510 
3511   )";
3512 
3513   // Check
3514   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3515 }
3516 
3517 TEST_F(AArch64GISelMITest, BitcastStore) {
3518   setUp();
3519   if (!TM)
3520     return;
3521 
3522   LLT P0 = LLT::pointer(0, 64);
3523   LLT S32 = LLT::scalar(32);
3524   LLT V4S8 = LLT::fixed_vector(4, 8);
3525   auto Ptr = B.buildUndef(P0);
3526 
3527   DefineLegalizerInfo(A, {});
3528 
3529   MachineMemOperand *MMO = B.getMF().getMachineMemOperand(
3530       MachinePointerInfo(), MachineMemOperand::MOStore, 4, Align(4));
3531   auto Val = B.buildUndef(V4S8);
3532   auto Store = B.buildStore(Val, Ptr, *MMO);
3533 
3534   AInfo Info(MF->getSubtarget());
3535   DummyGISelObserver Observer;
3536   LegalizerHelper Helper(*MF, Info, Observer, B);
3537   B.setInsertPt(*EntryMBB, Store->getIterator());
3538   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3539             Helper.bitcast(*Store, 0, S32));
3540 
3541   auto CheckStr = R"(
3542   CHECK: [[VAL:%[0-9]+]]:_(<4 x s8>) = G_IMPLICIT_DEF
3543   CHECK: [[CAST:%[0-9]+]]:_(s32) = G_BITCAST [[VAL]]
3544   CHECK: G_STORE [[CAST]]
3545   )";
3546 
3547   // Check
3548   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3549 }
3550 
3551 TEST_F(AArch64GISelMITest, BitcastSelect) {
3552   setUp();
3553   if (!TM)
3554     return;
3555 
3556   LLT S1 = LLT::scalar(1);
3557   LLT S32 = LLT::scalar(32);
3558   LLT V4S8 = LLT::fixed_vector(4, 8);
3559 
3560   DefineLegalizerInfo(A, {});
3561 
3562   auto Cond = B.buildUndef(S1);
3563   auto Val0 = B.buildConstant(V4S8, 123);
3564   auto Val1 = B.buildConstant(V4S8, 99);
3565 
3566   auto Select = B.buildSelect(V4S8, Cond, Val0, Val1);
3567 
3568   AInfo Info(MF->getSubtarget());
3569   DummyGISelObserver Observer;
3570   LegalizerHelper Helper(*MF, Info, Observer, B);
3571   B.setInsertPt(*EntryMBB, Select->getIterator());
3572   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3573             Helper.bitcast(*Select, 0, S32));
3574 
3575   auto CheckStr = R"(
3576   CHECK: [[VAL0:%[0-9]+]]:_(<4 x s8>) = G_BUILD_VECTOR
3577   CHECK: [[VAL1:%[0-9]+]]:_(<4 x s8>) = G_BUILD_VECTOR
3578   CHECK: [[CAST0:%[0-9]+]]:_(s32) = G_BITCAST [[VAL0]]
3579   CHECK: [[CAST1:%[0-9]+]]:_(s32) = G_BITCAST [[VAL1]]
3580   CHECK: [[SELECT:%[0-9]+]]:_(s32) = G_SELECT %{{[0-9]+}}:_(s1), [[CAST0]]:_, [[CAST1]]:_
3581   CHECK: [[CAST2:%[0-9]+]]:_(<4 x s8>) = G_BITCAST [[SELECT]]
3582   )";
3583 
3584   // Check
3585   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3586 
3587   // Doesn't make sense
3588   auto VCond = B.buildUndef(LLT::fixed_vector(4, 1));
3589   auto VSelect = B.buildSelect(V4S8, VCond, Val0, Val1);
3590 
3591   B.setInsertPt(*EntryMBB, VSelect->getIterator());
3592   EXPECT_EQ(LegalizerHelper::LegalizeResult::UnableToLegalize,
3593             Helper.bitcast(*VSelect, 0, S32));
3594   EXPECT_EQ(LegalizerHelper::LegalizeResult::UnableToLegalize,
3595             Helper.bitcast(*VSelect, 1, LLT::scalar(4)));
3596 }
3597 
3598 TEST_F(AArch64GISelMITest, BitcastBitOps) {
3599   setUp();
3600   if (!TM)
3601     return;
3602 
3603   LLT S32 = LLT::scalar(32);
3604   LLT V4S8 = LLT::fixed_vector(4, 8);
3605 
3606   DefineLegalizerInfo(A, {});
3607 
3608   auto Val0 = B.buildConstant(V4S8, 123);
3609   auto Val1 = B.buildConstant(V4S8, 99);
3610   auto And = B.buildAnd(V4S8, Val0, Val1);
3611   auto Or = B.buildOr(V4S8, Val0, Val1);
3612   auto Xor = B.buildXor(V4S8, Val0, Val1);
3613 
3614   AInfo Info(MF->getSubtarget());
3615   DummyGISelObserver Observer;
3616   LegalizerHelper Helper(*MF, Info, Observer, B);
3617   B.setInsertPt(*EntryMBB, And->getIterator());
3618   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3619             Helper.bitcast(*And, 0, S32));
3620 
3621   B.setInsertPt(*EntryMBB, Or->getIterator());
3622   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3623             Helper.bitcast(*Or, 0, S32));
3624 
3625   B.setInsertPt(*EntryMBB, Xor->getIterator());
3626   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3627             Helper.bitcast(*Xor, 0, S32));
3628 
3629   auto CheckStr = R"(
3630   CHECK: [[VAL0:%[0-9]+]]:_(<4 x s8>) = G_BUILD_VECTOR
3631   CHECK: [[VAL1:%[0-9]+]]:_(<4 x s8>) = G_BUILD_VECTOR
3632   CHECK: [[CAST0:%[0-9]+]]:_(s32) = G_BITCAST [[VAL0]]
3633   CHECK: [[CAST1:%[0-9]+]]:_(s32) = G_BITCAST [[VAL1]]
3634   CHECK: [[AND:%[0-9]+]]:_(s32) = G_AND [[CAST0]]:_, [[CAST1]]:_
3635   CHECK: [[CAST_AND:%[0-9]+]]:_(<4 x s8>) = G_BITCAST [[AND]]
3636   CHECK: [[CAST2:%[0-9]+]]:_(s32) = G_BITCAST [[VAL0]]
3637   CHECK: [[CAST3:%[0-9]+]]:_(s32) = G_BITCAST [[VAL1]]
3638   CHECK: [[OR:%[0-9]+]]:_(s32) = G_OR [[CAST2]]:_, [[CAST3]]:_
3639   CHECK: [[CAST_OR:%[0-9]+]]:_(<4 x s8>) = G_BITCAST [[OR]]
3640   CHECK: [[CAST4:%[0-9]+]]:_(s32) = G_BITCAST [[VAL0]]
3641   CHECK: [[CAST5:%[0-9]+]]:_(s32) = G_BITCAST [[VAL1]]
3642   CHECK: [[XOR:%[0-9]+]]:_(s32) = G_XOR [[CAST4]]:_, [[CAST5]]:_
3643   CHECK: [[CAST_XOR:%[0-9]+]]:_(<4 x s8>) = G_BITCAST [[XOR]]
3644   )";
3645 
3646   // Check
3647   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3648 }
3649 
3650 TEST_F(AArch64GISelMITest, CreateLibcall) {
3651   setUp();
3652   if (!TM)
3653     return;
3654 
3655   DefineLegalizerInfo(A, {});
3656 
3657   AInfo Info(MF->getSubtarget());
3658   DummyGISelObserver Observer;
3659 
3660   LLVMContext &Ctx = MF->getFunction().getContext();
3661   auto *RetTy = Type::getVoidTy(Ctx);
3662 
3663   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3664             createLibcall(B, "abort", {{}, RetTy, 0}, {}, CallingConv::C));
3665 
3666   auto CheckStr = R"(
3667   CHECK: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
3668   CHECK: BL &abort
3669   CHECK: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
3670   )";
3671 
3672   // Check
3673   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3674 }
3675 
3676 // Test narrowing of G_IMPLICIT_DEF
3677 TEST_F(AArch64GISelMITest, NarrowImplicitDef) {
3678   setUp();
3679   if (!TM)
3680     return;
3681 
3682   DefineLegalizerInfo(A, {});
3683 
3684   // Make sure that G_IMPLICIT_DEF can be narrowed if the original size is not a
3685   // multiple of narrow size
3686   LLT S32{LLT::scalar(32)};
3687   LLT S48{LLT::scalar(48)};
3688   LLT S64{LLT::scalar(64)};
3689   LLT V2S64{{LLT::fixed_vector(2, 64)}};
3690 
3691   auto Implicit1 = B.buildUndef(S64);
3692   auto Implicit2 = B.buildUndef(S64);
3693   auto Implicit3 = B.buildUndef(V2S64);
3694   auto Implicit4 = B.buildUndef(V2S64);
3695 
3696   AInfo Info(MF->getSubtarget());
3697   DummyGISelObserver Observer;
3698   LegalizerHelper Helper(*MF, Info, Observer, B);
3699 
3700   // Perform Legalization
3701 
3702   B.setInsertPt(*EntryMBB, Implicit1->getIterator());
3703   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3704             Helper.narrowScalar(*Implicit1, 0, S48));
3705 
3706   B.setInsertPt(*EntryMBB, Implicit2->getIterator());
3707   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3708             Helper.narrowScalar(*Implicit2, 0, S32));
3709 
3710   B.setInsertPt(*EntryMBB, Implicit3->getIterator());
3711   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3712             Helper.narrowScalar(*Implicit3, 0, S48));
3713 
3714   B.setInsertPt(*EntryMBB, Implicit4->getIterator());
3715   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3716             Helper.narrowScalar(*Implicit4, 0, S32));
3717 
3718   const auto *CheckStr = R"(
3719   CHECK: [[DEF:%[0-9]+]]:_(s48) = G_IMPLICIT_DEF
3720   CHECK: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[DEF]]
3721 
3722   CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
3723   CHECK: [[DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
3724   CHECK: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[DEF]]:_(s32), [[DEF1]]
3725 
3726   CHECK: [[DEF:%[0-9]+]]:_(<2 x s48>) = G_IMPLICIT_DEF
3727   CHECK: [[ANYEXT:%[0-9]+]]:_(<2 x s64>) = G_ANYEXT [[DEF]]
3728 
3729   CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
3730   CHECK: [[DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
3731   CHECK: [[DEF2:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
3732   CHECK: [[DEF3:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
3733   CHECK: [[BV:%[0-9]+]]:_(<2 x s64>) = G_BUILD_VECTOR [[DEF]]:_(s32), [[DEF1]]:_(s32), [[DEF2]]:_(s32), [[DEF3]]:_(s32)
3734   )";
3735 
3736   // Check
3737   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3738 }
3739 
3740 // Test widening of G_FREEZE
3741 TEST_F(AArch64GISelMITest, WidenFreeze) {
3742   setUp();
3743   if (!TM)
3744     return;
3745 
3746   DefineLegalizerInfo(A, {});
3747 
3748   // Make sure that G_FREEZE is widened with anyext
3749   LLT S64{LLT::scalar(64)};
3750   LLT S128{LLT::scalar(128)};
3751   LLT V2S32{LLT::fixed_vector(2, 32)};
3752   LLT V2S64{LLT::fixed_vector(2, 64)};
3753 
3754   auto Vector = B.buildBitcast(V2S32, Copies[0]);
3755 
3756   auto FreezeScalar = B.buildInstr(TargetOpcode::G_FREEZE, {S64}, {Copies[0]});
3757   auto FreezeVector = B.buildInstr(TargetOpcode::G_FREEZE, {V2S32}, {Vector});
3758 
3759   AInfo Info(MF->getSubtarget());
3760   DummyGISelObserver Observer;
3761   LegalizerHelper Helper(*MF, Info, Observer, B);
3762 
3763   // Perform Legalization
3764 
3765   B.setInsertPt(*EntryMBB, FreezeScalar->getIterator());
3766   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3767             Helper.widenScalar(*FreezeScalar, 0, S128));
3768 
3769   B.setInsertPt(*EntryMBB, FreezeVector->getIterator());
3770   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3771             Helper.widenScalar(*FreezeVector, 0, V2S64));
3772 
3773   const auto *CheckStr = R"(
3774   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
3775   CHECK: [[BITCAST:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[COPY]]
3776 
3777   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT [[COPY]]
3778   CHECK: [[FREEZE:%[0-9]+]]:_(s128) = G_FREEZE [[ANYEXT]]
3779   CHECK: [[TRUNC:%[0-9]+]]:_(s64) = G_TRUNC [[FREEZE]]
3780 
3781   CHECK: [[ANYEXT1:%[0-9]+]]:_(<2 x s64>) = G_ANYEXT [[BITCAST]]
3782   CHECK: [[FREEZE1:%[0-9]+]]:_(<2 x s64>) = G_FREEZE [[ANYEXT1]]
3783   CHECK: [[TRUNC1:%[0-9]+]]:_(<2 x s32>) = G_TRUNC [[FREEZE1]]
3784   )";
3785 
3786   // Check
3787   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3788 }
3789 
3790 // Test narrowing of G_FREEZE
3791 TEST_F(AArch64GISelMITest, NarrowFreeze) {
3792   setUp();
3793   if (!TM)
3794     return;
3795 
3796   DefineLegalizerInfo(A, {});
3797 
3798   // Make sure that G_FREEZE is narrowed using unmerge/extract
3799   LLT S32{LLT::scalar(32)};
3800   LLT S33{LLT::scalar(33)};
3801   LLT S48{LLT::scalar(48)};
3802   LLT S64{LLT::scalar(64)};
3803   LLT V2S16{LLT::fixed_vector(2, 16)};
3804   LLT V3S16{LLT::fixed_vector(3, 16)};
3805   LLT V4S16{LLT::fixed_vector(4, 16)};
3806 
3807   auto Trunc = B.buildTrunc(S33, {Copies[0]});
3808   auto Trunc1 = B.buildTrunc(S48, {Copies[0]});
3809   auto Vector = B.buildBitcast(V3S16, Trunc1);
3810 
3811   auto FreezeScalar = B.buildInstr(TargetOpcode::G_FREEZE, {S64}, {Copies[0]});
3812   auto FreezeOdd = B.buildInstr(TargetOpcode::G_FREEZE, {S33}, {Trunc});
3813   auto FreezeVector = B.buildInstr(TargetOpcode::G_FREEZE, {V3S16}, {Vector});
3814   auto FreezeVector1 = B.buildInstr(TargetOpcode::G_FREEZE, {V3S16}, {Vector});
3815 
3816   AInfo Info(MF->getSubtarget());
3817   DummyGISelObserver Observer;
3818   LegalizerHelper Helper(*MF, Info, Observer, B);
3819 
3820   // Perform Legalization
3821 
3822   B.setInsertPt(*EntryMBB, FreezeScalar->getIterator());
3823   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3824             Helper.narrowScalar(*FreezeScalar, 0, S32));
3825 
3826   // This should be followed by narrowScalar to S32.
3827   B.setInsertPt(*EntryMBB, FreezeOdd->getIterator());
3828   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3829             Helper.widenScalar(*FreezeOdd, 0, S64));
3830 
3831   B.setInsertPt(*EntryMBB, FreezeVector->getIterator());
3832   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3833             Helper.fewerElementsVector(*FreezeVector, 0, V2S16));
3834 
3835   // This should be followed by fewerElements to V2S16.
3836   B.setInsertPt(*EntryMBB, FreezeVector1->getIterator());
3837   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3838             Helper.moreElementsVector(*FreezeVector1, 0, V4S16));
3839 
3840   const auto *CheckStr = R"(
3841   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
3842   CHECK: [[TRUNC:%[0-9]+]]:_(s33) = G_TRUNC [[COPY]]
3843   CHECK: [[TRUNC1:%[0-9]+]]:_(s48) = G_TRUNC [[COPY]]
3844   CHECK: [[BITCAST:%[0-9]+]]:_(<3 x s16>) = G_BITCAST [[TRUNC1]]
3845 
3846   CHECK: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[COPY]]
3847   CHECK: [[FREEZE:%[0-9]+]]:_(s32) = G_FREEZE [[UV]]
3848   CHECK: [[FREEZE1:%[0-9]+]]:_(s32) = G_FREEZE [[UV1]]
3849   CHECK: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[FREEZE]]:_(s32), [[FREEZE1]]
3850 
3851   CHECK: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[TRUNC]]
3852   CHECK: [[FREEZE2:%[0-9]+]]:_(s64) = G_FREEZE [[ANYEXT]]
3853   CHECK: [[TRUNC1:%[0-9]+]]:_(s33) = G_TRUNC [[FREEZE2]]
3854 
3855   CHECK: [[UV2:%[0-9]+]]:_(s16), [[UV3:%[0-9]+]]:_(s16), [[UV4:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[BITCAST]]
3856   CHECK: [[BV:%[0-9]+]]:_(<2 x s16>) = G_BUILD_VECTOR [[UV2]]:_(s16), [[UV3]]:_(s16)
3857   CHECK: [[FREEZE3:%[0-9]+]]:_(<2 x s16>) = G_FREEZE [[BV]]
3858   CHECK: [[FREEZE4:%[0-9]+]]:_(s16) = G_FREEZE [[UV4]]
3859   CHECK: [[FREEZE3_E0:%[0-9]+]]:_(s16), [[FREEZE3_E1:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[FREEZE3]]
3860   CHECK: [[BV1:%[0-9]+]]:_(<3 x s16>) = G_BUILD_VECTOR [[FREEZE3_E0]]:_(s16), [[FREEZE3_E1]]:_(s16), [[FREEZE4]]:_(s16)
3861 
3862   CHECK: [[UV5:%[0-9]+]]:_(s16), [[UV6:%[0-9]+]]:_(s16), [[UV7:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[BITCAST]]
3863   CHECK: [[IMP_DEF:%[0-9]+]]:_(s16) = G_IMPLICIT_DEF
3864   CHECK: [[BV1:%[0-9]+]]:_(<4 x s16>) = G_BUILD_VECTOR [[UV5]]:_(s16), [[UV6]]:_(s16), [[UV7]]:_(s16), [[IMP_DEF]]:_(s16)
3865   CHECK: [[FREEZE5:%[0-9]+]]:_(<4 x s16>) = G_FREEZE [[BV1]]
3866   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]]
3867   CHECK: [[BV2:%[0-9]+]]:_(<3 x s16>) = G_BUILD_VECTOR [[FREEZE5_E0]]:_(s16), [[FREEZE5_E1]]:_(s16), [[FREEZE5_E2]]:_(s16)
3868   )";
3869 
3870   // Check
3871   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3872 }
3873 
3874 // Test fewer elements of G_FREEZE
3875 TEST_F(AArch64GISelMITest, FewerElementsFreeze) {
3876   setUp();
3877   if (!TM)
3878     return;
3879 
3880   DefineLegalizerInfo(A, {});
3881 
3882   LLT S32{LLT::scalar(32)};
3883   LLT V2S16{LLT::fixed_vector(2, 16)};
3884   LLT V2S32{LLT::fixed_vector(2, 32)};
3885   LLT V4S16{LLT::fixed_vector(4, 16)};
3886 
3887   auto Vector1 = B.buildBitcast(V2S32, Copies[0]);
3888   auto Vector2 = B.buildBitcast(V4S16, Copies[0]);
3889 
3890   auto FreezeVector1 = B.buildInstr(TargetOpcode::G_FREEZE, {V2S32}, {Vector1});
3891   auto FreezeVector2 = B.buildInstr(TargetOpcode::G_FREEZE, {V4S16}, {Vector2});
3892 
3893   AInfo Info(MF->getSubtarget());
3894   DummyGISelObserver Observer;
3895   LegalizerHelper Helper(*MF, Info, Observer, B);
3896 
3897   // Perform Legalization
3898 
3899   B.setInsertPt(*EntryMBB, FreezeVector1->getIterator());
3900   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3901             Helper.fewerElementsVector(*FreezeVector1, 0, S32));
3902 
3903   B.setInsertPt(*EntryMBB, FreezeVector2->getIterator());
3904   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3905             Helper.fewerElementsVector(*FreezeVector2, 0, V2S16));
3906 
3907   const auto *CheckStr = R"(
3908   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
3909   CHECK: [[BITCAST:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[COPY]]
3910   CHECK: [[BITCAST1:%[0-9]+]]:_(<4 x s16>) = G_BITCAST [[COPY]]
3911 
3912   CHECK: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[BITCAST]]
3913   CHECK: [[FREEZE:%[0-9]+]]:_(s32) = G_FREEZE [[UV]]
3914   CHECK: [[FREEZE1:%[0-9]+]]:_(s32) = G_FREEZE [[UV1]]
3915   CHECK: [[MV:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[FREEZE]]:_(s32), [[FREEZE1]]
3916 
3917   CHECK: [[UV:%[0-9]+]]:_(<2 x s16>), [[UV1:%[0-9]+]]:_(<2 x s16>) = G_UNMERGE_VALUES [[BITCAST1]]
3918   CHECK: [[FREEZE2:%[0-9]+]]:_(<2 x s16>) = G_FREEZE [[UV]]
3919   CHECK: [[FREEZE3:%[0-9]+]]:_(<2 x s16>) = G_FREEZE [[UV1]]
3920   CHECK: [[MV:%[0-9]+]]:_(<4 x s16>) = G_CONCAT_VECTORS [[FREEZE2]]:_(<2 x s16>), [[FREEZE3]]
3921   )";
3922 
3923   // Check
3924   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3925 }
3926 
3927 // Test more elements of G_FREEZE
3928 TEST_F(AArch64GISelMITest, MoreElementsFreeze) {
3929   setUp();
3930   if (!TM)
3931     return;
3932 
3933   DefineLegalizerInfo(A, {});
3934 
3935   LLT V2S32{LLT::fixed_vector(2, 32)};
3936   LLT V4S32{LLT::fixed_vector(4, 32)};
3937 
3938   auto Vector1 = B.buildBitcast(V2S32, Copies[0]);
3939   auto FreezeVector1 = B.buildInstr(TargetOpcode::G_FREEZE, {V2S32}, {Vector1});
3940 
3941   AInfo Info(MF->getSubtarget());
3942   DummyGISelObserver Observer;
3943   LegalizerHelper Helper(*MF, Info, Observer, B);
3944 
3945   // Perform Legalization
3946   B.setInsertPt(*EntryMBB, FreezeVector1->getIterator());
3947   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3948             Helper.moreElementsVector(*FreezeVector1, 0, V4S32));
3949 
3950   const auto *CheckStr = R"(
3951   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
3952   CHECK: [[BITCAST:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[COPY]]
3953   CHECK: [[BITCAST_E0:%[0-9]+]]:_(s32), [[BITCAST_E1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[BITCAST]]:_(<2 x s32>)
3954   CHECK: [[IMP_DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
3955   CHECK: [[BITCAST_LARGE:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[BITCAST_E0]]:_(s32), [[BITCAST_E1]]:_(s32), [[IMP_DEF]]:_(s32), [[IMP_DEF]]:_(s32)
3956   CHECK: [[FREEZE:%[0-9]+]]:_(<4 x s32>) = G_FREEZE [[BITCAST_LARGE]]
3957   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>)
3958   CHECK: (<2 x s32>) = G_BUILD_VECTOR [[FREEZE_E0]]:_(s32), [[FREEZE_E1]]:_(s32)
3959   )";
3960 
3961   // Check
3962   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3963 }
3964 
3965 // Test fewer elements of G_INSERT_VECTOR_ELEMENT
3966 TEST_F(AArch64GISelMITest, FewerElementsInsertVectorElt) {
3967   setUp();
3968   if (!TM)
3969     return;
3970 
3971   DefineLegalizerInfo(A, {});
3972 
3973   LLT P0{LLT::pointer(0, 64)};
3974   LLT S64{LLT::scalar(64)};
3975   LLT S16{LLT::scalar(16)};
3976   LLT V2S16{LLT::fixed_vector(2, 16)};
3977   LLT V3S16{LLT::fixed_vector(3, 16)};
3978   LLT V8S16{LLT::fixed_vector(8, 16)};
3979 
3980   auto Ptr0 = B.buildIntToPtr(P0, Copies[0]);
3981   auto VectorV8 = B.buildLoad(V8S16, Ptr0, MachinePointerInfo(), Align(8));
3982   auto Value = B.buildTrunc(S16, Copies[1]);
3983 
3984   auto Seven = B.buildConstant(S64, 7);
3985   auto InsertV8Constant7_0 =
3986       B.buildInsertVectorElement(V8S16, VectorV8, Value, Seven);
3987   auto InsertV8Constant7_1 =
3988       B.buildInsertVectorElement(V8S16, VectorV8, Value, Seven);
3989 
3990   B.buildStore(InsertV8Constant7_0, Ptr0, MachinePointerInfo(), Align(8),
3991                MachineMemOperand::MOVolatile);
3992   B.buildStore(InsertV8Constant7_1, Ptr0, MachinePointerInfo(), Align(8),
3993                MachineMemOperand::MOVolatile);
3994 
3995   AInfo Info(MF->getSubtarget());
3996   DummyGISelObserver Observer;
3997   LegalizerHelper Helper(*MF, Info, Observer, B);
3998 
3999   // Perform Legalization
4000   B.setInsertPt(*EntryMBB, InsertV8Constant7_0->getIterator());
4001 
4002   // This should index the high element of the 4th piece of an unmerge.
4003   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
4004             Helper.fewerElementsVector(*InsertV8Constant7_0, 0, V2S16));
4005 
4006   // This case requires extracting an intermediate vector type into the target
4007   // v4s16.
4008   B.setInsertPt(*EntryMBB, InsertV8Constant7_1->getIterator());
4009   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
4010             Helper.fewerElementsVector(*InsertV8Constant7_1, 0, V3S16));
4011 
4012   const auto *CheckStr = R"(
4013   CHECK: [[COPY0:%[0-9]+]]:_(s64) = COPY
4014   CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY
4015   CHECK: [[COPY2:%[0-9]+]]:_(s64) = COPY
4016   CHECK: [[PTR0:%[0-9]+]]:_(p0) = G_INTTOPTR [[COPY0]]
4017   CHECK: [[VEC8:%[0-9]+]]:_(<8 x s16>) = G_LOAD [[PTR0]]:_(p0) :: (load (<8 x s16>), align 8)
4018   CHECK: [[INSERT_VAL:%[0-9]+]]:_(s16) = G_TRUNC [[COPY1]]
4019 
4020 
4021   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]]
4022   CHECK: [[ONE:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
4023   CHECK: [[SUB_INSERT_7:%[0-9]+]]:_(<2 x s16>) = G_INSERT_VECTOR_ELT [[UNMERGE3]]:_, [[INSERT_VAL]]:_(s16), [[ONE]]
4024   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>)
4025 
4026 
4027   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>)
4028   CHECK: [[IMPDEF_S16:%[0-9]+]]:_(s16) = G_IMPLICIT_DEF
4029   CHECK: [[BUILD0:%[0-9]+]]:_(<3 x s16>) = G_BUILD_VECTOR [[UNMERGE1_0]]:_(s16), [[UNMERGE1_1]]:_(s16), [[UNMERGE1_2]]:_(s16)
4030   CHECK: [[BUILD1:%[0-9]+]]:_(<3 x s16>) = G_BUILD_VECTOR [[UNMERGE1_3]]:_(s16), [[UNMERGE1_4]]:_(s16), [[UNMERGE1_5]]:_(s16)
4031   CHECK: [[BUILD2:%[0-9]+]]:_(<3 x s16>) = G_BUILD_VECTOR [[UNMERGE1_6]]:_(s16), [[UNMERGE1_7]]:_(s16), [[IMPDEF_S16]]:_(s16)
4032   CHECK: [[IMPDEF_V3S16:%[0-9]+]]:_(<3 x s16>) = G_IMPLICIT_DEF
4033   CHECK: [[ONE_1:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
4034   CHECK: [[SUB_INSERT_7_V3S16:%[0-9]+]]:_(<3 x s16>) = G_INSERT_VECTOR_ELT [[BUILD2]]:_, [[INSERT_VAL]]:_(s16), [[ONE_1]]
4035 
4036   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>)
4037   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>)
4038   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>)
4039 
4040 
4041   CHECK: G_STORE [[INSERT_V8_7_0]]
4042   CHECK: G_STORE [[INSERT_V8_7_1]]
4043   )";
4044 
4045   // Check
4046   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
4047 }
4048 
4049 // Test widen scalar of G_UNMERGE_VALUES
4050 TEST_F(AArch64GISelMITest, widenScalarUnmerge) {
4051   setUp();
4052   if (!TM)
4053     return;
4054 
4055   DefineLegalizerInfo(A, {});
4056 
4057   LLT S96{LLT::scalar(96)};
4058   LLT S64{LLT::scalar(64)};
4059   LLT S48{LLT::scalar(48)};
4060 
4061   auto Src = B.buildAnyExt(S96, Copies[0]);
4062   auto Unmerge = B.buildUnmerge(S48, Src);
4063 
4064   AInfo Info(MF->getSubtarget());
4065   DummyGISelObserver Observer;
4066   LegalizerHelper Helper(*MF, Info, Observer, B);
4067 
4068   // Perform Legalization
4069   B.setInsertPt(*EntryMBB, Unmerge->getIterator());
4070 
4071   // This should create unmerges to a GCD type (S16), then remerge to S48
4072   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
4073             Helper.widenScalar(*Unmerge, 0, S64));
4074 
4075   const auto *CheckStr = R"(
4076   CHECK: [[COPY0:%[0-9]+]]:_(s64) = COPY
4077   CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY
4078   CHECK: [[COPY2:%[0-9]+]]:_(s64) = COPY
4079   CHECK: [[ANYEXT:%[0-9]+]]:_(s96) = G_ANYEXT [[COPY0]]
4080   CHECK: [[ANYEXT1:%[0-9]+]]:_(s192) = G_ANYEXT [[ANYEXT]]
4081   CHECK: [[UNMERGE:%[0-9]+]]:_(s64), [[UNMERGE1:%[0-9]+]]:_(s64), [[UNMERGE2:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[ANYEXT1]]
4082   CHECK: [[UNMERGE3:%[0-9]+]]:_(s16), [[UNMERGE4:%[0-9]+]]:_(s16), [[UNMERGE5:%[0-9]+]]:_(s16), [[UNMERGE6:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[UNMERGE]]
4083   CHECK: [[UNMERGE7:%[0-9]+]]:_(s16), [[UNMERGE8:%[0-9]+]]:_(s16), [[UNMERGE9:%[0-9]+]]:_(s16), [[UNMERGE10:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[UNMERGE1]]
4084   CHECK: [[UNMERGE11:%[0-9]+]]:_(s16), [[UNMERGE12:%[0-9]+]]:_(s16), [[UNMERGE13:%[0-9]+]]:_(s16), [[UNMERGE14:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[UNMERGE2]]
4085   CHECK: [[MERGE:%[0-9]+]]:_(s48) = G_MERGE_VALUES [[UNMERGE3]]:_(s16), [[UNMERGE4]]:_(s16), [[UNMERGE5]]:_(s16)
4086   CHECK: [[MERGE1:%[0-9]+]]:_(s48) = G_MERGE_VALUES [[UNMERGE6]]:_(s16), [[UNMERGE7]]:_(s16), [[UNMERGE8]]:_(s16)
4087   )";
4088 
4089   // Check
4090   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
4091 }
4092 
4093 // Test moreElements of G_SHUFFLE_VECTOR.
4094 TEST_F(AArch64GISelMITest, moreElementsShuffle) {
4095   setUp();
4096   if (!TM)
4097     return;
4098 
4099   DefineLegalizerInfo(A, {});
4100 
4101   LLT S64{LLT::scalar(64)};
4102   LLT V6S64 = LLT::fixed_vector(6, S64);
4103 
4104   auto V1 = B.buildBuildVector(V6S64, {Copies[0], Copies[1], Copies[0],
4105                                        Copies[1], Copies[0], Copies[1]});
4106   auto V2 = B.buildBuildVector(V6S64, {Copies[0], Copies[1], Copies[0],
4107                                        Copies[1], Copies[0], Copies[1]});
4108   auto Shuffle = B.buildShuffleVector(V6S64, V1, V2, {3, 4, 7, 0, 1, 11});
4109 
4110   AInfo Info(MF->getSubtarget());
4111   DummyGISelObserver Observer;
4112   LegalizerHelper Helper(*MF, Info, Observer, B);
4113 
4114   // Perform Legalization
4115   B.setInsertPt(*EntryMBB, Shuffle->getIterator());
4116 
4117   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
4118             Helper.moreElementsVector(*Shuffle, 0, LLT::fixed_vector(8, S64)));
4119 
4120   const auto *CheckStr = R"(
4121   CHECK: [[COPY0:%[0-9]+]]:_(s64) = COPY
4122   CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY
4123   CHECK: [[COPY2:%[0-9]+]]:_(s64) = COPY
4124   CHECK: [[BV1:%[0-9]+]]:_(<6 x s64>) = G_BUILD_VECTOR
4125   CHECK: [[BV2:%[0-9]+]]:_(<6 x s64>) = G_BUILD_VECTOR
4126 
4127   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>)
4128   CHECK: [[IMP_DEF0:%[0-9]+]]:_(s64) = G_IMPLICIT_DEF
4129   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)
4130 
4131   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>)
4132   CHECK: [[IMP_DEF1:%[0-9]+]]:_(s64) = G_IMPLICIT_DEF
4133   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)
4134 
4135   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)
4136 
4137   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>)
4138   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)
4139   )";
4140 
4141   // Check
4142   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
4143 }
4144 
4145 // Test narror scalar of G_SHL with constant shift amount
4146 TEST_F(AArch64GISelMITest, narrowScalarShiftByConstant) {
4147   setUp();
4148   if (!TM)
4149     return;
4150 
4151   DefineLegalizerInfo(A, {});
4152 
4153   LLT S64{LLT::scalar(64)};
4154   LLT S32{LLT::scalar(32)};
4155 
4156   auto Constant = B.buildConstant(S64, 33);
4157   auto Trunc = B.buildTrunc(S32, Constant);
4158   auto Shift = B.buildShl(S64, Copies[0], Trunc);
4159 
4160   AInfo Info(MF->getSubtarget());
4161   DummyGISelObserver Observer;
4162   LegalizerHelper Helper(*MF, Info, Observer, B);
4163 
4164   // Perform Legalization
4165   B.setInsertPt(*EntryMBB, Shift->getIterator());
4166 
4167   // This should detect the G_CONSTANT feeding the G_SHL through a G_TRUNC
4168   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
4169             Helper.narrowScalarShift(*Shift, 0, S32));
4170 
4171   const auto *CheckStr = R"(
4172   CHECK: [[COPY0:%[0-9]+]]:_(s64) = COPY
4173   CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY
4174   CHECK: [[COPY2:%[0-9]+]]:_(s64) = COPY
4175   CHECK: [[THIRTY3:%[0-9]+]]:_(s64) = G_CONSTANT i64 33
4176   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC %4:_(s64)
4177   CHECK: [[UNMERGE:%[0-9]+]]:_(s32), [[UNMERGE2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[COPY0]]
4178   CHECK: [[ZERO:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
4179   CHECK: [[ONE:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
4180   CHECK: [[SHIFT:%[0-9]+]]:_(s32) = G_SHL [[UNMERGE]]:_, [[ONE]]:_(s32)
4181   CHECK: [[MERGE:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[ZERO]]:_(s32), [[SHIFT]]:_(s32)
4182   )";
4183 
4184   // Check
4185   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
4186 }
4187 
4188 TEST_F(AArch64GISelMITest, MoreElementsSelect) {
4189   setUp();
4190   if (!TM)
4191     return;
4192 
4193   LLT s1 = LLT::scalar(1);
4194   LLT s64 = LLT::scalar(64);
4195   LLT v2s1 = LLT::fixed_vector(2, 1);
4196   LLT v2s32 = LLT::fixed_vector(2, 32);
4197 
4198   LegalizerInfo LI;
4199   DummyGISelObserver Observer;
4200   LegalizerHelper Helper(*MF, LI, Observer, B);
4201 
4202   B.setInsertPt(*EntryMBB, EntryMBB->end());
4203 
4204   auto Val0 = B.buildBitcast(v2s32, Copies[0]);
4205   auto Val1 = B.buildBitcast(v2s32, Copies[1]);
4206 
4207   // Build select of vectors with scalar condition.
4208   auto Zero = B.buildConstant(s64, 0);
4209   auto Cond = B.buildICmp(CmpInst::ICMP_EQ, s1, Copies[2], Zero);
4210   auto Select = B.buildSelect(v2s32, Cond, Val0, Val1);
4211 
4212   // Splat the condition into a vector select
4213   B.setInstr(*Select);
4214 
4215   EXPECT_EQ(LegalizerHelper::LegalizeResult::UnableToLegalize,
4216             Helper.moreElementsVector(*Select, 1, LLT::fixed_vector(3, 1)));
4217   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
4218             Helper.moreElementsVector(*Select, 1, v2s1));
4219 
4220   auto CheckStr = R"(
4221   CHECK: [[BITCAST0:%[0-9]+]]:_(<2 x s32>) = G_BITCAST
4222   CHECK: [[BITCAST1:%[0-9]+]]:_(<2 x s32>) = G_BITCAST
4223   CHECK: [[ZERO0:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
4224   CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), %{{[0-9]+}}:_(s64), [[ZERO0]]
4225   CHECK: [[IMPDEF:%[0-9]+]]:_(<2 x s1>) = G_IMPLICIT_DEF
4226   CHECK: [[ZERO1:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
4227   CHECK: [[INSERT:%[0-9]+]]:_(<2 x s1>) = G_INSERT_VECTOR_ELT [[IMPDEF]]:_, [[CMP]]:_(s1), [[ZERO1]]
4228   CHECK: [[SHUFFLE:%[0-9]+]]:_(<2 x s1>) = G_SHUFFLE_VECTOR [[INSERT]]:_(<2 x s1>), [[IMPDEF]]:_, shufflemask(0, 0)
4229   CHECK: [[SELECT:%[0-9]+]]:_(<2 x s32>) = G_SELECT [[SHUFFLE]]:_(<2 x s1>), [[BITCAST0]]:_, [[BITCAST1]]:_
4230   )";
4231 
4232   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
4233 }
4234 
4235 } // namespace
4236