xref: /llvm-project/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp (revision 95c2bcbf8b98c176408e5cce82afef232b788b18)
1 //===- LegalizerHelperTest.cpp
2 //-----------------------------------------------===//
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "GISelMITest.h"
11 #include "llvm/CodeGen/GlobalISel/LostDebugLocObserver.h"
12 
13 using namespace LegalizeActions;
14 using namespace LegalizeMutations;
15 using namespace LegalityPredicates;
16 
17 namespace {
18 
19 class DummyGISelObserver : public GISelChangeObserver {
20 public:
21   void changingInstr(MachineInstr &MI) override {}
22   void changedInstr(MachineInstr &MI) override {}
23   void createdInstr(MachineInstr &MI) override {}
24   void erasingInstr(MachineInstr &MI) override {}
25 };
26 
27 // Test G_ROTL/G_ROTR lowering.
28 TEST_F(AArch64GISelMITest, LowerRotates) {
29   setUp();
30   if (!TM)
31     return;
32 
33   // Declare your legalization info
34   DefineLegalizerInfo(A, {
35     getActionDefinitionsBuilder({G_ROTR, G_ROTL}).lower(); });
36 
37   LLT S32 = LLT::scalar(32);
38   auto Src = B.buildTrunc(S32, Copies[0]);
39   auto Amt = B.buildTrunc(S32, Copies[1]);
40   auto ROTR = B.buildInstr(TargetOpcode::G_ROTR, {S32}, {Src, Amt});
41   auto ROTL = B.buildInstr(TargetOpcode::G_ROTL, {S32}, {Src, Amt});
42 
43   AInfo Info(MF->getSubtarget());
44   DummyGISelObserver Observer;
45   LegalizerHelper Helper(*MF, Info, Observer, B);
46   // Perform Legalization
47   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
48             Helper.lower(*ROTR, 0, S32));
49   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
50             Helper.lower(*ROTL, 0, S32));
51 
52   auto CheckStr = R"(
53   ; Check G_ROTR
54   CHECK: [[SRC:%[0-9]+]]:_(s32) = G_TRUNC
55   CHECK: [[AMT:%[0-9]+]]:_(s32) = G_TRUNC
56   CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
57   CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 31
58   CHECK: [[SUB:%[0-9]+]]:_(s32) = G_SUB [[C]]:_, [[AMT]]:_
59   CHECK: [[AND:%[0-9]+]]:_(s32) = G_AND [[AMT]]:_, [[C1]]:_
60   CHECK: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[SRC]]:_, [[AND]]:_(s32)
61   CHECK: [[AND1:%[0-9]+]]:_(s32) = G_AND [[SUB]]:_, [[C1]]:_
62   CHECK: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[SRC]]:_, [[AND1]]:_(s32)
63   CHECK: G_OR [[LSHR]]:_, [[SHL]]:_
64 
65   ; Check G_ROTL
66   CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
67   CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 31
68   CHECK: [[SUB:%[0-9]+]]:_(s32) = G_SUB [[C]]:_, [[AMT]]:_
69   CHECK: [[AND:%[0-9]+]]:_(s32) = G_AND [[AMT]]:_, [[C1]]:_
70   CHECK: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[SRC]]:_, [[AND]]:_(s32)
71   CHECK: [[AND1:%[0-9]+]]:_(s32) = G_AND [[SUB]]:_, [[C1]]:_
72   CHECK: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[SRC]]:_, [[AND1]]:_(s32)
73   CHECK: G_OR [[SHL]]:_, [[LSHR]]:_
74   )";
75 
76   // Check
77   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
78 }
79 
80 // Test G_ROTL/G_ROTR non-pow2 lowering.
81 TEST_F(AArch64GISelMITest, LowerRotatesNonPow2) {
82   setUp();
83   if (!TM)
84     return;
85 
86   // Declare your legalization info
87   DefineLegalizerInfo(A, {
88     getActionDefinitionsBuilder({G_ROTR, G_ROTL}).lower(); });
89 
90   LLT S24 = LLT::scalar(24);
91   auto Src = B.buildTrunc(S24, Copies[0]);
92   auto Amt = B.buildTrunc(S24, Copies[1]);
93   auto ROTR = B.buildInstr(TargetOpcode::G_ROTR, {S24}, {Src, Amt});
94   auto ROTL = B.buildInstr(TargetOpcode::G_ROTL, {S24}, {Src, Amt});
95 
96   AInfo Info(MF->getSubtarget());
97   DummyGISelObserver Observer;
98   LegalizerHelper Helper(*MF, Info, Observer, B);
99   // Perform Legalization
100   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
101             Helper.lower(*ROTR, 0, S24));
102   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
103             Helper.lower(*ROTL, 0, S24));
104 
105   auto CheckStr = R"(
106   ; Check G_ROTR
107   CHECK: [[SRC:%[0-9]+]]:_(s24) = G_TRUNC
108   CHECK: [[AMT:%[0-9]+]]:_(s24) = G_TRUNC
109   CHECK: [[C:%[0-9]+]]:_(s24) = G_CONSTANT i24 0
110   CHECK: [[C1:%[0-9]+]]:_(s24) = G_CONSTANT i24 23
111   CHECK: [[C2:%[0-9]+]]:_(s24) = G_CONSTANT i24 24
112   CHECK: [[UREM:%[0-9]+]]:_(s24) = G_UREM [[AMT]]:_, [[C2]]:_
113   CHECK: [[LSHR:%[0-9]+]]:_(s24) = G_LSHR [[SRC]]:_, [[UREM]]:_(s24)
114   CHECK: [[SUB:%[0-9]+]]:_(s24) = G_SUB [[C1]]:_, [[UREM]]:_
115   CHECK: [[C4:%[0-9]+]]:_(s24) = G_CONSTANT i24 1
116   CHECK: [[SHL:%[0-9]+]]:_(s24) = G_SHL [[SRC]]:_, [[C4]]:_(s24)
117   CHECK: [[SHL2:%[0-9]+]]:_(s24) = G_SHL [[SHL]]:_, [[SUB]]:_(s24)
118   CHECK: G_OR [[LSHR]]:_, [[SHL2]]:_
119 
120   ; Check G_ROTL
121   CHECK: [[C:%[0-9]+]]:_(s24) = G_CONSTANT i24 0
122   CHECK: [[C1:%[0-9]+]]:_(s24) = G_CONSTANT i24 23
123   CHECK: [[C2:%[0-9]+]]:_(s24) = G_CONSTANT i24 24
124   CHECK: [[UREM:%[0-9]+]]:_(s24) = G_UREM [[AMT]]:_, [[C2]]:_
125   CHECK: [[SHL:%[0-9]+]]:_(s24) = G_SHL [[SRC]]:_, [[UREM]]:_(s24)
126   CHECK: [[SUB:%[0-9]+]]:_(s24) = G_SUB [[C1]]:_, [[UREM]]:_
127   CHECK: [[C4:%[0-9]+]]:_(s24) = G_CONSTANT i24 1
128   CHECK: [[LSHR:%[0-9]+]]:_(s24) = G_LSHR [[SRC]]:_, [[C4]]:_(s24)
129   CHECK: [[LSHR2:%[0-9]+]]:_(s24) = G_LSHR [[LSHR]]:_, [[SUB]]:_(s24)
130   CHECK: G_OR [[SHL]]:_, [[LSHR2]]:_
131   )";
132 
133   // Check
134   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
135 }
136 
137 // Test vector G_ROTR lowering.
138 TEST_F(AArch64GISelMITest, LowerRotatesVector) {
139   setUp();
140   if (!TM)
141     return;
142 
143   // Declare your legalization info
144   DefineLegalizerInfo(A, {
145     getActionDefinitionsBuilder({G_ROTR, G_ROTL}).lower(); });
146 
147   LLT S32 = LLT::scalar(32);
148   LLT V4S32 = LLT::fixed_vector(4, S32);
149   auto SrcTrunc = B.buildTrunc(S32, Copies[0]);
150   auto Src = B.buildSplatVector(V4S32, SrcTrunc);
151   auto AmtTrunc = B.buildTrunc(S32, Copies[1]);
152   auto Amt = B.buildSplatVector(V4S32, AmtTrunc);
153   auto ROTR = B.buildInstr(TargetOpcode::G_ROTR, {V4S32}, {Src, Amt});
154 
155   AInfo Info(MF->getSubtarget());
156   DummyGISelObserver Observer;
157   LegalizerHelper Helper(*MF, Info, Observer, B);
158   // Perform Legalization
159   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
160             Helper.lower(*ROTR, 0, V4S32));
161 
162   auto CheckStr = R"(
163   CHECK: [[SRCTRUNC:%[0-9]+]]:_(s32) = G_TRUNC
164   CHECK: [[SRC:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[SRCTRUNC]]
165   CHECK: [[AMTTRUNC:%[0-9]+]]:_(s32) = G_TRUNC
166   CHECK: [[AMT:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[AMTTRUNC]]
167   CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
168   CHECK: [[ZERO:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[C]]
169   CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 31
170   CHECK: [[VEC31:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[C1]]
171   CHECK: [[SUB:%[0-9]+]]:_(<4 x s32>) = G_SUB [[ZERO]]:_, [[AMT]]:_
172   CHECK: [[AND:%[0-9]+]]:_(<4 x s32>) = G_AND [[AMT]]:_, [[VEC31]]:_
173   CHECK: [[LSHR:%[0-9]+]]:_(<4 x s32>) = G_LSHR [[SRC]]:_, [[AND]]:_(<4 x s32>)
174   CHECK: [[AND1:%[0-9]+]]:_(<4 x s32>) = G_AND [[SUB]]:_, [[VEC31]]:_
175   CHECK: [[SHL:%[0-9]+]]:_(<4 x s32>) = G_SHL [[SRC]]:_, [[AND1]]:_(<4 x s32>)
176   CHECK: G_OR [[LSHR]]:_, [[SHL]]:_
177   )";
178 
179   // Check
180   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
181 }
182 
183 // Test CTTZ expansion when CTTZ_ZERO_UNDEF is legal or custom,
184 // in which case it becomes CTTZ_ZERO_UNDEF with select.
185 TEST_F(AArch64GISelMITest, LowerBitCountingCTTZ0) {
186   setUp();
187   if (!TM)
188     return;
189 
190   // Declare your legalization info
191   DefineLegalizerInfo(A, {
192     getActionDefinitionsBuilder(G_CTTZ_ZERO_UNDEF).legalFor({{s32, s64}});
193   });
194   // Build Instr
195   auto MIBCTTZ =
196       B.buildInstr(TargetOpcode::G_CTTZ, {LLT::scalar(32)}, {Copies[0]});
197   AInfo Info(MF->getSubtarget());
198   DummyGISelObserver Observer;
199   LegalizerHelper Helper(*MF, Info, Observer, B);
200   // Perform Legalization
201   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
202             Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)));
203 
204   auto CheckStr = R"(
205   CHECK: [[CZU:%[0-9]+]]:_(s32) = G_CTTZ_ZERO_UNDEF %0
206   CHECK: [[ZERO:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
207   CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), %0:_(s64), [[ZERO]]
208   CHECK: [[SIXTY4:%[0-9]+]]:_(s32) = G_CONSTANT i32 64
209   CHECK: [[SEL:%[0-9]+]]:_(s32) = G_SELECT [[CMP]]:_(s1), [[SIXTY4]]:_, [[CZU]]
210   )";
211 
212   // Check
213   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
214 }
215 
216 // CTTZ expansion in terms of CTLZ
217 TEST_F(AArch64GISelMITest, LowerBitCountingCTTZ1) {
218   setUp();
219   if (!TM)
220     return;
221 
222   // Declare your legalization info
223   DefineLegalizerInfo(A, {
224     getActionDefinitionsBuilder(G_CTLZ).legalFor({{s64, s64}});
225   });
226   // Build Instr
227   auto MIBCTTZ =
228       B.buildInstr(TargetOpcode::G_CTTZ, {LLT::scalar(64)}, {Copies[0]});
229   AInfo Info(MF->getSubtarget());
230   DummyGISelObserver Observer;
231   LegalizerHelper Helper(*MF, Info, Observer, B);
232   // Perform Legalization
233   EXPECT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) ==
234               LegalizerHelper::LegalizeResult::Legalized);
235 
236   auto CheckStr = R"(
237   CHECK: [[NEG1:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1
238   CHECK: [[NOT:%[0-9]+]]:_(s64) = G_XOR %0:_, [[NEG1]]
239   CHECK: [[SUB1:%[0-9]+]]:_(s64) = G_ADD %0:_, [[NEG1]]
240   CHECK: [[AND1:%[0-9]+]]:_(s64) = G_AND [[NOT]]:_, [[SUB1]]:_
241   CHECK: [[CST64:%[0-9]+]]:_(s64) = G_CONSTANT i64 64
242   CHECK: [[CTLZ:%[0-9]+]]:_(s64) = G_CTLZ [[AND1]]:_
243   CHECK: G_SUB [[CST64]]:_, [[CTLZ]]:_
244   )";
245 
246   // Check
247   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
248 }
249 
250 // CTLZ scalar narrowing
251 TEST_F(AArch64GISelMITest, NarrowScalarCTLZ) {
252   setUp();
253   if (!TM)
254     return;
255 
256   // Declare your legalization info
257   DefineLegalizerInfo(A, {
258     getActionDefinitionsBuilder(G_CTLZ).legalFor({{s32, s32}});
259   });
260   // Build Instr
261   auto CTLZ =
262       B.buildInstr(TargetOpcode::G_CTLZ, {LLT::scalar(32)}, {Copies[0]});
263   AInfo Info(MF->getSubtarget());
264   DummyGISelObserver Observer;
265   LegalizerHelper Helper(*MF, Info, Observer, B);
266   // Perform Legalization
267   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
268             Helper.narrowScalar(*CTLZ, 1, LLT::scalar(32)));
269 
270   auto CheckStr = R"(
271   CHECK: [[UNMERGE_LO:%[0-9]+]]:_(s32), [[UNMERGE_HI:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES %0:_(s64)
272   CHECK: [[ZERO:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
273   CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[UNMERGE_HI]]:_(s32), [[ZERO]]:_
274   CHECK: [[CTLZ_LO:%[0-9]+]]:_(s32) = G_CTLZ [[UNMERGE_LO]]:_(s32)
275   CHECK: [[THIRTYTWO:%[0-9]+]]:_(s32) = G_CONSTANT i32 32
276   CHECK: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[CTLZ_LO]]:_, [[THIRTYTWO]]:_
277   CHECK: [[CTLZ_HI:%[0-9]+]]:_(s32) = G_CTLZ_ZERO_UNDEF [[UNMERGE_HI]]:_(s32)
278   CHECK: %{{[0-9]+}}:_(s32) = G_SELECT [[CMP]]:_(s1), [[ADD]]:_, [[CTLZ_HI]]:_
279   )";
280 
281   // Check
282   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
283 }
284 
285 // CTTZ scalar narrowing
286 TEST_F(AArch64GISelMITest, NarrowScalarCTTZ) {
287   setUp();
288   if (!TM)
289     return;
290 
291   // Declare your legalization info
292   DefineLegalizerInfo(A, {
293     getActionDefinitionsBuilder(G_CTTZ).legalFor({{s32, s64}});
294   });
295   // Build Instr
296   auto CTTZ =
297       B.buildInstr(TargetOpcode::G_CTTZ, {LLT::scalar(32)}, {Copies[0]});
298   AInfo Info(MF->getSubtarget());
299   DummyGISelObserver Observer;
300   LegalizerHelper Helper(*MF, Info, Observer, B);
301   // Perform Legalization
302   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
303             Helper.narrowScalar(*CTTZ, 1, LLT::scalar(32)));
304 
305   auto CheckStr = R"(
306   CHECK: [[UNMERGE_LO:%[0-9]+]]:_(s32), [[UNMERGE_HI:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES %0:_(s64)
307   CHECK: [[ZERO:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
308   CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[UNMERGE_LO]]:_(s32), [[ZERO]]:_
309   CHECK: [[CTTZ_HI:%[0-9]+]]:_(s32) = G_CTTZ [[UNMERGE_HI]]:_(s32)
310   CHECK: [[THIRTYTWO:%[0-9]+]]:_(s32) = G_CONSTANT i32 32
311   CHECK: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[CTTZ_HI]]:_, [[THIRTYTWO]]:_
312   CHECK: [[CTTZ_LO:%[0-9]+]]:_(s32) = G_CTTZ_ZERO_UNDEF [[UNMERGE_LO]]:_(s32)
313   CHECK: %{{[0-9]+}}:_(s32) = G_SELECT [[CMP]]:_(s1), [[ADD]]:_, [[CTTZ_LO]]:_
314   )";
315 
316   // Check
317   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
318 }
319 
320 // CTTZ expansion in terms of CTPOP
321 TEST_F(AArch64GISelMITest, LowerBitCountingCTTZ2) {
322   setUp();
323   if (!TM)
324     return;
325 
326   // Declare your legalization info
327   DefineLegalizerInfo(A, {
328     getActionDefinitionsBuilder(G_CTPOP).legalFor({{s64, s64}});
329   });
330   // Build
331   auto MIBCTTZ =
332       B.buildInstr(TargetOpcode::G_CTTZ, {LLT::scalar(64)}, {Copies[0]});
333   AInfo Info(MF->getSubtarget());
334   DummyGISelObserver Observer;
335   LegalizerHelper Helper(*MF, Info, Observer, B);
336 
337   B.setInsertPt(*EntryMBB, MIBCTTZ->getIterator());
338   EXPECT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) ==
339               LegalizerHelper::LegalizeResult::Legalized);
340 
341   auto CheckStr = R"(
342   CHECK: [[NEG1:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1
343   CHECK: [[NOT:%[0-9]+]]:_(s64) = G_XOR %0:_, [[NEG1]]
344   CHECK: [[SUB1:%[0-9]+]]:_(s64) = G_ADD %0:_, [[NEG1]]
345   CHECK: [[AND1:%[0-9]+]]:_(s64) = G_AND [[NOT]]:_, [[SUB1]]:_
346   CHECK: [[POP:%[0-9]+]]:_(s64) = G_CTPOP [[AND1]]
347   )";
348 
349   // Check
350   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
351 }
352 
353 // CTPOP widening.
354 TEST_F(AArch64GISelMITest, WidenBitCountingCTPOP1) {
355   setUp();
356   if (!TM)
357     return;
358 
359   // Declare your legalization info
360   DefineLegalizerInfo(A, {
361       getActionDefinitionsBuilder(G_CTPOP).legalFor({{s16, s16}});
362     });
363 
364   // Build
365   // Trunc it to s8.
366   LLT s8{LLT::scalar(8)};
367   LLT s16{LLT::scalar(16)};
368   auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
369   auto MIBCTPOP = B.buildInstr(TargetOpcode::G_CTPOP, {s16}, {MIBTrunc});
370   AInfo Info(MF->getSubtarget());
371   DummyGISelObserver Observer;
372   LegalizerHelper Helper(*MF, Info, Observer, B);
373   B.setInstr(*MIBCTPOP);
374   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
375             Helper.widenScalar(*MIBCTPOP, 1, s16));
376 
377   auto CheckStr = R"(
378   CHECK: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC %0:_(s64)
379   CHECK: [[ZEXT:%[0-9]+]]:_(s16) = G_ZEXT [[TRUNC]]:_(s8)
380   CHECK: [[CTPOP:%[0-9]+]]:_(s16) = G_CTPOP [[ZEXT]]
381   CHECK: [[COPY:%[0-9]+]]:_(s16) = COPY [[CTPOP]]:_(s16)
382   )";
383 
384   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
385 }
386 
387 // Test a strange case where the result is wider than the source
388 TEST_F(AArch64GISelMITest, WidenBitCountingCTPOP2) {
389   setUp();
390   if (!TM)
391     return;
392 
393   // Declare your legalization info
394   DefineLegalizerInfo(A, {
395       getActionDefinitionsBuilder(G_CTPOP).legalFor({{s32, s16}});
396     });
397 
398   // Build
399   // Trunc it to s8.
400   LLT s8{LLT::scalar(8)};
401   LLT s16{LLT::scalar(16)};
402   LLT s32{LLT::scalar(32)};
403   auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
404   auto MIBCTPOP = B.buildInstr(TargetOpcode::G_CTPOP, {s32}, {MIBTrunc});
405   AInfo Info(MF->getSubtarget());
406   DummyGISelObserver Observer;
407   LegalizerHelper Helper(*MF, Info, Observer, B);
408   B.setInstr(*MIBCTPOP);
409   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
410             Helper.widenScalar(*MIBCTPOP, 1, s16));
411 
412   auto CheckStr = R"(
413   CHECK: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC %0:_(s64)
414   CHECK: [[ZEXT:%[0-9]+]]:_(s16) = G_ZEXT [[TRUNC]]:_(s8)
415   CHECK: [[CTPOP:%[0-9]+]]:_(s16) = G_CTPOP [[ZEXT]]
416   CHECK: [[COPY:%[0-9]+]]:_(s32) = G_ZEXT [[CTPOP]]:_(s16)
417   )";
418 
419   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
420 }
421 
422 // CTTZ_ZERO_UNDEF expansion in terms of CTTZ
423 TEST_F(AArch64GISelMITest, LowerBitCountingCTTZ3) {
424   setUp();
425   if (!TM)
426     return;
427 
428   // Declare your legalization info
429   DefineLegalizerInfo(A, {
430     getActionDefinitionsBuilder(G_CTTZ).legalFor({{s64, s64}});
431   });
432   // Build
433   auto MIBCTTZ = B.buildInstr(TargetOpcode::G_CTTZ_ZERO_UNDEF,
434                               {LLT::scalar(64)}, {Copies[0]});
435   AInfo Info(MF->getSubtarget());
436   DummyGISelObserver Observer;
437   LegalizerHelper Helper(*MF, Info, Observer, B);
438   EXPECT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) ==
439               LegalizerHelper::LegalizeResult::Legalized);
440 
441   auto CheckStr = R"(
442   CHECK: CTTZ
443   )";
444 
445   // Check
446   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
447 }
448 
449 // CTLZ expansion in terms of CTLZ_ZERO_UNDEF
450 TEST_F(AArch64GISelMITest, LowerBitCountingCTLZ0) {
451   setUp();
452   if (!TM)
453     return;
454 
455   // Declare your legalization info
456   DefineLegalizerInfo(A, {
457     getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF).legalFor({{s64, s64}});
458   });
459   // Build
460   auto MIBCTLZ =
461       B.buildInstr(TargetOpcode::G_CTLZ, {LLT::scalar(64)}, {Copies[0]});
462   AInfo Info(MF->getSubtarget());
463   DummyGISelObserver Observer;
464   LegalizerHelper Helper(*MF, Info, Observer, B);
465   EXPECT_TRUE(Helper.lower(*MIBCTLZ, 0, LLT::scalar(64)) ==
466               LegalizerHelper::LegalizeResult::Legalized);
467 
468   auto CheckStr = R"(
469   CHECK: [[CZU:%[0-9]+]]:_(s64) = G_CTLZ_ZERO_UNDEF %0
470   CHECK: [[ZERO:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
471   CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), %0:_(s64), [[ZERO]]
472   CHECK: [[SIXTY4:%[0-9]+]]:_(s64) = G_CONSTANT i64 64
473   CHECK: [[SEL:%[0-9]+]]:_(s64) = G_SELECT [[CMP]]:_(s1), [[SIXTY4]]:_, [[CZU]]
474   )";
475 
476   // Check
477   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
478 }
479 
480 // CTLZ expansion in terms of CTLZ_ZERO_UNDEF if the latter is a libcall
481 TEST_F(AArch64GISelMITest, LowerBitCountingCTLZLibcall) {
482   setUp();
483   if (!TM)
484     return;
485 
486   // Declare your legalization info
487   DefineLegalizerInfo(A, {
488     getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF).libcallFor({{s32, s64}});
489   });
490   // Build
491   auto MIBCTLZ =
492       B.buildInstr(TargetOpcode::G_CTLZ, {LLT::scalar(32)}, {Copies[0]});
493   AInfo Info(MF->getSubtarget());
494   DummyGISelObserver Observer;
495   LegalizerHelper Helper(*MF, Info, Observer, B);
496   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
497             Helper.lower(*MIBCTLZ, 0, LLT::scalar(32)));
498 
499   auto CheckStr = R"(
500   CHECK: [[CZU:%[0-9]+]]:_(s32) = G_CTLZ_ZERO_UNDEF %0
501   CHECK: [[ZERO:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
502   CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), %0:_(s64), [[ZERO]]
503   CHECK: [[THIRTY2:%[0-9]+]]:_(s32) = G_CONSTANT i32 64
504   CHECK: [[SEL:%[0-9]+]]:_(s32) = G_SELECT [[CMP]]:_(s1), [[THIRTY2]]:_, [[CZU]]
505   )";
506 
507   // Check
508   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
509 }
510 
511 // CTLZ expansion
512 TEST_F(AArch64GISelMITest, LowerBitCountingCTLZ1) {
513   setUp();
514   if (!TM)
515     return;
516 
517   // Declare your legalization info
518   DefineLegalizerInfo(A, {
519     getActionDefinitionsBuilder(G_CTPOP).legalFor({{s8, s8}});
520   });
521   // Build
522   // Trunc it to s8.
523   LLT s8{LLT::scalar(8)};
524   auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
525   auto MIBCTLZ = B.buildInstr(TargetOpcode::G_CTLZ, {s8}, {MIBTrunc});
526   AInfo Info(MF->getSubtarget());
527   DummyGISelObserver Observer;
528   LegalizerHelper Helper(*MF, Info, Observer, B);
529   EXPECT_TRUE(Helper.lower(*MIBCTLZ, 0, s8) ==
530               LegalizerHelper::LegalizeResult::Legalized);
531 
532   auto CheckStr = R"(
533   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
534   CHECK: [[Cst1:%[0-9]+]]:_(s8) = G_CONSTANT i8 1
535   CHECK: [[Sh1:%[0-9]+]]:_(s8) = G_LSHR [[Trunc]]:_, [[Cst1]]:_
536   CHECK: [[Or1:%[0-9]+]]:_(s8) = G_OR [[Trunc]]:_, [[Sh1]]:_
537   CHECK: [[Cst2:%[0-9]+]]:_(s8) = G_CONSTANT i8 2
538   CHECK: [[Sh2:%[0-9]+]]:_(s8) = G_LSHR [[Or1]]:_, [[Cst2]]:_
539   CHECK: [[Or2:%[0-9]+]]:_(s8) = G_OR [[Or1]]:_, [[Sh2]]:_
540   CHECK: [[Cst4:%[0-9]+]]:_(s8) = G_CONSTANT i8 4
541   CHECK: [[Sh4:%[0-9]+]]:_(s8) = G_LSHR [[Or2]]:_, [[Cst4]]:_
542   CHECK: [[Or4:%[0-9]+]]:_(s8) = G_OR [[Or2]]:_, [[Sh4]]:_
543   CHECK: [[CTPOP:%[0-9]+]]:_(s8) = G_CTPOP [[Or4]]:_
544   CHECK: [[Len:%[0-9]+]]:_(s8) = G_CONSTANT i8 8
545   CHECK: [[Sub:%[0-9]+]]:_(s8) = G_SUB [[Len]]:_, [[CTPOP]]:_
546   )";
547 
548   // Check
549   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
550 }
551 
552 // CTLZ widening.
553 TEST_F(AArch64GISelMITest, WidenBitCountingCTLZ) {
554   setUp();
555   if (!TM)
556     return;
557 
558   // Declare your legalization info
559   DefineLegalizerInfo(A, {
560     getActionDefinitionsBuilder(G_CTLZ).legalFor({{s16, s16}});
561   });
562   // Build
563   // Trunc it to s8.
564   LLT s8{LLT::scalar(8)};
565   LLT s16{LLT::scalar(16)};
566   auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
567   auto MIBCTLZ = B.buildInstr(TargetOpcode::G_CTLZ, {s8}, {MIBTrunc});
568   AInfo Info(MF->getSubtarget());
569   DummyGISelObserver Observer;
570   LegalizerHelper Helper(*MF, Info, Observer, B);
571   EXPECT_TRUE(Helper.widenScalar(*MIBCTLZ, 1, s16) ==
572               LegalizerHelper::LegalizeResult::Legalized);
573 
574   auto CheckStr = R"(
575   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
576   CHECK: [[Zext:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
577   CHECK: [[Ctlz:%[0-9]+]]:_(s16) = G_CTLZ [[Zext]]
578   CHECK: [[Cst8:%[0-9]+]]:_(s16) = G_CONSTANT i16 8
579   CHECK: [[Sub:%[0-9]+]]:_(s16) = G_SUB [[Ctlz]]:_, [[Cst8]]:_
580   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC [[Sub]]
581   )";
582 
583   // Check
584   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
585 }
586 
587 // CTLZ_ZERO_UNDEF widening.
588 TEST_F(AArch64GISelMITest, WidenBitCountingCTLZZeroUndef) {
589   setUp();
590   if (!TM)
591     return;
592 
593   // Declare your legalization info
594   DefineLegalizerInfo(A, {
595     getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF).legalFor({{s16, s16}});
596   });
597   // Build
598   // Trunc it to s8.
599   LLT s8{LLT::scalar(8)};
600   LLT s16{LLT::scalar(16)};
601   auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
602   auto MIBCTLZ_ZU =
603       B.buildInstr(TargetOpcode::G_CTLZ_ZERO_UNDEF, {s8}, {MIBTrunc});
604   AInfo Info(MF->getSubtarget());
605   DummyGISelObserver Observer;
606   LegalizerHelper Helper(*MF, Info, Observer, B);
607   EXPECT_TRUE(Helper.widenScalar(*MIBCTLZ_ZU, 1, s16) ==
608               LegalizerHelper::LegalizeResult::Legalized);
609 
610   auto CheckStr = R"(
611   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
612   CHECK: [[Zext:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
613   CHECK: [[CtlzZu:%[0-9]+]]:_(s16) = G_CTLZ_ZERO_UNDEF [[Zext]]
614   CHECK: [[Cst8:%[0-9]+]]:_(s16) = G_CONSTANT i16 8
615   CHECK: [[Sub:%[0-9]+]]:_(s16) = G_SUB [[CtlzZu]]:_, [[Cst8]]:_
616   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC [[Sub]]
617   )";
618 
619   // Check
620   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
621 }
622 
623 // CTPOP widening.
624 TEST_F(AArch64GISelMITest, WidenBitCountingCTPOP) {
625   setUp();
626   if (!TM)
627     return;
628 
629   // Declare your legalization info
630   DefineLegalizerInfo(A, {
631     getActionDefinitionsBuilder(G_CTPOP).legalFor({{s16, s16}});
632   });
633   // Build
634   // Trunc it to s8.
635   LLT s8{LLT::scalar(8)};
636   LLT s16{LLT::scalar(16)};
637   auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
638   auto MIBCTPOP = B.buildInstr(TargetOpcode::G_CTPOP, {s8}, {MIBTrunc});
639   AInfo Info(MF->getSubtarget());
640   DummyGISelObserver Observer;
641   LegalizerHelper Helper(*MF, Info, Observer, B);
642   EXPECT_TRUE(Helper.widenScalar(*MIBCTPOP, 1, s16) ==
643               LegalizerHelper::LegalizeResult::Legalized);
644 
645   auto CheckStr = R"(
646   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
647   CHECK: [[Zext:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
648   CHECK: [[Ctpop:%[0-9]+]]:_(s16) = G_CTPOP [[Zext]]
649   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC [[Ctpop]]
650   )";
651 
652   // Check
653   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
654 }
655 
656 // CTTZ_ZERO_UNDEF widening.
657 TEST_F(AArch64GISelMITest, WidenBitCountingCTTZ_ZERO_UNDEF) {
658   setUp();
659   if (!TM)
660     return;
661 
662   // Declare your legalization info
663   DefineLegalizerInfo(A, {
664     getActionDefinitionsBuilder(G_CTTZ_ZERO_UNDEF).legalFor({{s16, s16}});
665   });
666   // Build
667   // Trunc it to s8.
668   LLT s8{LLT::scalar(8)};
669   LLT s16{LLT::scalar(16)};
670   auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
671   auto MIBCTTZ_ZERO_UNDEF =
672       B.buildInstr(TargetOpcode::G_CTTZ_ZERO_UNDEF, {s8}, {MIBTrunc});
673   AInfo Info(MF->getSubtarget());
674   DummyGISelObserver Observer;
675   LegalizerHelper Helper(*MF, Info, Observer, B);
676   EXPECT_TRUE(Helper.widenScalar(*MIBCTTZ_ZERO_UNDEF, 1, s16) ==
677               LegalizerHelper::LegalizeResult::Legalized);
678 
679   auto CheckStr = R"(
680   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
681   CHECK: [[AnyExt:%[0-9]+]]:_(s16) = G_ANYEXT [[Trunc]]
682   CHECK: [[CttzZu:%[0-9]+]]:_(s16) = G_CTTZ_ZERO_UNDEF [[AnyExt]]
683   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC [[CttzZu]]
684   )";
685 
686   // Check
687   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
688 }
689 
690 // CTTZ widening.
691 TEST_F(AArch64GISelMITest, WidenBitCountingCTTZ) {
692   setUp();
693   if (!TM)
694     return;
695 
696   // Declare your legalization info
697   DefineLegalizerInfo(A, {
698     getActionDefinitionsBuilder(G_CTTZ).legalFor({{s16, s16}});
699   });
700   // Build
701   // Trunc it to s8.
702   LLT s8{LLT::scalar(8)};
703   LLT s16{LLT::scalar(16)};
704   auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
705   auto MIBCTTZ = B.buildInstr(TargetOpcode::G_CTTZ, {s8}, {MIBTrunc});
706   AInfo Info(MF->getSubtarget());
707   DummyGISelObserver Observer;
708   LegalizerHelper Helper(*MF, Info, Observer, B);
709   EXPECT_TRUE(Helper.widenScalar(*MIBCTTZ, 1, s16) ==
710               LegalizerHelper::LegalizeResult::Legalized);
711 
712   auto CheckStr = R"(
713   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
714   CHECK: [[AnyExt:%[0-9]+]]:_(s16) = G_ANYEXT [[Trunc]]
715   CHECK: [[Cst:%[0-9]+]]:_(s16) = G_CONSTANT i16 256
716   CHECK: [[Or:%[0-9]+]]:_(s16) = G_OR [[AnyExt]]:_, [[Cst]]
717   CHECK: [[Cttz:%[0-9]+]]:_(s16) = G_CTTZ_ZERO_UNDEF [[Or]]
718   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC [[Cttz]]
719   )";
720 
721   // Check
722   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
723 }
724 // UADDO widening.
725 TEST_F(AArch64GISelMITest, WidenUADDO) {
726   setUp();
727   if (!TM)
728     return;
729 
730   // Declare your legalization info
731   DefineLegalizerInfo(A, {
732     getActionDefinitionsBuilder(G_ADD).legalFor({{s16, s16}});
733   });
734   // Build
735   // Trunc it to s8.
736   LLT s8{LLT::scalar(8)};
737   LLT s16{LLT::scalar(16)};
738   auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
739   unsigned CarryReg = MRI->createGenericVirtualRegister(LLT::scalar(1));
740   auto MIBUAddO =
741       B.buildInstr(TargetOpcode::G_UADDO, {s8, CarryReg}, {MIBTrunc, MIBTrunc});
742   AInfo Info(MF->getSubtarget());
743   DummyGISelObserver Observer;
744   LegalizerHelper Helper(*MF, Info, Observer, B);
745   EXPECT_TRUE(Helper.widenScalar(*MIBUAddO, 0, s16) ==
746               LegalizerHelper::LegalizeResult::Legalized);
747 
748   auto CheckStr = R"(
749   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
750   CHECK: [[LHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
751   CHECK: [[RHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
752   CHECK: [[ADD:%[0-9]+]]:_(s16) = G_ADD [[LHS]]:_, [[RHS]]:_
753   CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[ADD]]
754   CHECK: [[ZEXT:%[0-9]+]]:_(s16) = G_ZEXT [[TRUNC1]]
755   CHECK: G_ICMP intpred(ne), [[ADD]]:_(s16), [[ZEXT]]:_
756   CHECK: G_TRUNC [[ADD]]
757   )";
758 
759   // Check
760   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
761 }
762 
763 // USUBO widening.
764 TEST_F(AArch64GISelMITest, WidenUSUBO) {
765   setUp();
766   if (!TM)
767     return;
768 
769   // Declare your legalization info
770   DefineLegalizerInfo(A, {
771     getActionDefinitionsBuilder(G_SUB).legalFor({{s16, s16}});
772   });
773   // Build
774   // Trunc it to s8.
775   LLT s8{LLT::scalar(8)};
776   LLT s16{LLT::scalar(16)};
777   auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
778   unsigned CarryReg = MRI->createGenericVirtualRegister(LLT::scalar(1));
779   auto MIBUSUBO =
780       B.buildInstr(TargetOpcode::G_USUBO, {s8, CarryReg}, {MIBTrunc, MIBTrunc});
781   AInfo Info(MF->getSubtarget());
782   DummyGISelObserver Observer;
783   LegalizerHelper Helper(*MF, Info, Observer, B);
784   EXPECT_TRUE(Helper.widenScalar(*MIBUSUBO, 0, s16) ==
785               LegalizerHelper::LegalizeResult::Legalized);
786 
787   auto CheckStr = R"(
788   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
789   CHECK: [[LHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
790   CHECK: [[RHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
791   CHECK: [[SUB:%[0-9]+]]:_(s16) = G_SUB [[LHS]]:_, [[RHS]]:_
792   CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[SUB]]
793   CHECK: [[ZEXT:%[0-9]+]]:_(s16) = G_ZEXT [[TRUNC1]]
794   CHECK: G_ICMP intpred(ne), [[SUB]]:_(s16), [[ZEXT]]:_
795   CHECK: G_TRUNC [[SUB]]
796   )";
797 
798   // Check
799   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
800 }
801 
802 // SADDO widening.
803 TEST_F(AArch64GISelMITest, WidenSADDO) {
804   setUp();
805   if (!TM)
806     return;
807 
808   // Declare your legalization info
809   DefineLegalizerInfo(A, {
810     getActionDefinitionsBuilder(G_ADD).legalFor({{s16, s16}});
811   });
812   // Build
813   // Trunc it to s8.
814   LLT s8{LLT::scalar(8)};
815   LLT s16{LLT::scalar(16)};
816   auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
817   unsigned CarryReg = MRI->createGenericVirtualRegister(LLT::scalar(1));
818   auto MIBSAddO =
819       B.buildInstr(TargetOpcode::G_SADDO, {s8, CarryReg}, {MIBTrunc, MIBTrunc});
820   AInfo Info(MF->getSubtarget());
821   DummyGISelObserver Observer;
822   LegalizerHelper Helper(*MF, Info, Observer, B);
823   EXPECT_TRUE(Helper.widenScalar(*MIBSAddO, 0, s16) ==
824               LegalizerHelper::LegalizeResult::Legalized);
825 
826   auto CheckStr = R"(
827   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
828   CHECK: [[LHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]]
829   CHECK: [[RHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]]
830   CHECK: [[ADD:%[0-9]+]]:_(s16) = G_ADD [[LHS]]:_, [[RHS]]:_
831   CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[ADD]]
832   CHECK: [[SEXT:%[0-9]+]]:_(s16) = G_SEXT [[TRUNC1]]
833   CHECK: G_ICMP intpred(ne), [[ADD]]:_(s16), [[SEXT]]:_
834   CHECK: G_TRUNC [[ADD]]
835   )";
836 
837   // Check
838   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
839 }
840 
841 // SSUBO widening.
842 TEST_F(AArch64GISelMITest, WidenSSUBO) {
843   setUp();
844   if (!TM)
845     return;
846 
847   // Declare your legalization info
848   DefineLegalizerInfo(A, {
849     getActionDefinitionsBuilder(G_SUB).legalFor({{s16, s16}});
850   });
851   // Build
852   // Trunc it to s8.
853   LLT s8{LLT::scalar(8)};
854   LLT s16{LLT::scalar(16)};
855   auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
856   unsigned CarryReg = MRI->createGenericVirtualRegister(LLT::scalar(1));
857   auto MIBSSUBO =
858       B.buildInstr(TargetOpcode::G_SSUBO, {s8, CarryReg}, {MIBTrunc, MIBTrunc});
859   AInfo Info(MF->getSubtarget());
860   DummyGISelObserver Observer;
861   LegalizerHelper Helper(*MF, Info, Observer, B);
862   EXPECT_TRUE(Helper.widenScalar(*MIBSSUBO, 0, s16) ==
863               LegalizerHelper::LegalizeResult::Legalized);
864 
865   auto CheckStr = R"(
866   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
867   CHECK: [[LHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]]
868   CHECK: [[RHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]]
869   CHECK: [[SUB:%[0-9]+]]:_(s16) = G_SUB [[LHS]]:_, [[RHS]]:_
870   CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[SUB]]
871   CHECK: [[SEXT:%[0-9]+]]:_(s16) = G_SEXT [[TRUNC1]]
872   CHECK: G_ICMP intpred(ne), [[SUB]]:_(s16), [[SEXT]]:_
873   CHECK: G_TRUNC [[SUB]]
874   )";
875 
876   // Check
877   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
878 }
879 
880 TEST_F(AArch64GISelMITest, WidenUADDE) {
881   setUp();
882   if (!TM)
883     return;
884 
885   // Declare your legalization info
886   DefineLegalizerInfo(A, {
887     getActionDefinitionsBuilder(G_UADDE).legalFor({{s16, s16}});
888   });
889   // Build
890   // Trunc it to s8.
891   LLT s8{LLT::scalar(8)};
892   LLT s16{LLT::scalar(16)};
893   auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
894   auto CarryIn = B.buildUndef(LLT::scalar(1));
895   Register CarryReg = MRI->createGenericVirtualRegister(LLT::scalar(1));
896   auto MIBUAddO = B.buildInstr(TargetOpcode::G_UADDE, {s8, CarryReg},
897                                {MIBTrunc, MIBTrunc, CarryIn});
898   AInfo Info(MF->getSubtarget());
899   DummyGISelObserver Observer;
900   LegalizerHelper Helper(*MF, Info, Observer, B);
901   EXPECT_TRUE(Helper.widenScalar(*MIBUAddO, 0, s16) ==
902               LegalizerHelper::LegalizeResult::Legalized);
903 
904   const char *CheckStr = R"(
905   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
906   CHECK: [[Implicit:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF
907   CHECK: [[LHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
908   CHECK: [[RHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
909   CHECK: [[UADDE:%[0-9]+]]:_(s16), [[CARRY:%[0-9]+]]:_(s1) = G_UADDE [[LHS]]:_, [[RHS]]:_, [[Implicit]]:_
910   CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[UADDE]]
911   CHECK: [[ZEXT:%[0-9]+]]:_(s16) = G_ZEXT [[TRUNC1]]
912   CHECK: G_ICMP intpred(ne), [[UADDE]]:_(s16), [[ZEXT]]:_
913   CHECK: G_TRUNC [[UADDE]]
914   )";
915 
916   // Check
917   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
918 }
919 
920 TEST_F(AArch64GISelMITest, WidenUSUBE) {
921   setUp();
922   if (!TM)
923     return;
924 
925   // Declare your legalization info
926   DefineLegalizerInfo(A, {
927     getActionDefinitionsBuilder(G_USUBE).legalFor({{s16, s16}});
928   });
929   // Build
930   // Trunc it to s8.
931   LLT s8{LLT::scalar(8)};
932   LLT s16{LLT::scalar(16)};
933   auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
934   auto CarryIn = B.buildUndef(LLT::scalar(1));
935   Register CarryReg = MRI->createGenericVirtualRegister(LLT::scalar(1));
936   auto MIBUSUBE = B.buildInstr(TargetOpcode::G_USUBE, {s8, CarryReg},
937                                {MIBTrunc, MIBTrunc, CarryIn});
938   AInfo Info(MF->getSubtarget());
939   DummyGISelObserver Observer;
940   LegalizerHelper Helper(*MF, Info, Observer, B);
941   EXPECT_TRUE(Helper.widenScalar(*MIBUSUBE, 0, s16) ==
942               LegalizerHelper::LegalizeResult::Legalized);
943 
944   const char *CheckStr = R"(
945   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
946   CHECK: [[Implicit:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF
947   CHECK: [[LHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
948   CHECK: [[RHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
949   CHECK: [[USUBE:%[0-9]+]]:_(s16), [[CARRY:%[0-9]+]]:_(s1) = G_USUBE [[LHS]]:_, [[RHS]]:_, [[Implicit]]:_
950   CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[USUBE]]
951   CHECK: [[ZEXT:%[0-9]+]]:_(s16) = G_ZEXT [[TRUNC1]]
952   CHECK: G_ICMP intpred(ne), [[USUBE]]:_(s16), [[ZEXT]]:_
953   CHECK: G_TRUNC [[USUBE]]
954   )";
955 
956   // Check
957   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
958 }
959 
960 TEST_F(AArch64GISelMITest, WidenSADDE) {
961   setUp();
962   if (!TM)
963     return;
964 
965   // Declare your legalization info
966   DefineLegalizerInfo(A, {
967     getActionDefinitionsBuilder({G_SADDE, G_UADDE}).legalFor({{s16, s16}});
968   });
969   // Build
970   // Trunc it to s8.
971   LLT s8{LLT::scalar(8)};
972   LLT s16{LLT::scalar(16)};
973   auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
974   auto CarryIn = B.buildUndef(LLT::scalar(1));
975   Register CarryReg = MRI->createGenericVirtualRegister(LLT::scalar(1));
976   auto MIBUAddO = B.buildInstr(TargetOpcode::G_SADDE, {s8, CarryReg},
977                                {MIBTrunc, MIBTrunc, CarryIn});
978   AInfo Info(MF->getSubtarget());
979   DummyGISelObserver Observer;
980   LegalizerHelper Helper(*MF, Info, Observer, B);
981   EXPECT_TRUE(Helper.widenScalar(*MIBUAddO, 0, s16) ==
982               LegalizerHelper::LegalizeResult::Legalized);
983 
984   const char *CheckStr = R"(
985   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
986   CHECK: [[Implicit:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF
987   CHECK: [[LHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]]
988   CHECK: [[RHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]]
989   CHECK: [[SADDE:%[0-9]+]]:_(s16), [[CARRY:%[0-9]+]]:_(s1) = G_UADDE [[LHS]]:_, [[RHS]]:_, [[Implicit]]:_
990   CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[SADDE]]
991   CHECK: [[SEXT:%[0-9]+]]:_(s16) = G_SEXT [[TRUNC1]]
992   CHECK: G_ICMP intpred(ne), [[SADDE]]:_(s16), [[SEXT]]:_
993   CHECK: G_TRUNC [[SADDE]]
994   )";
995 
996   // Check
997   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
998 }
999 
1000 TEST_F(AArch64GISelMITest, WidenSSUBE) {
1001   setUp();
1002   if (!TM)
1003     return;
1004 
1005   // Declare your legalization info
1006   DefineLegalizerInfo(A, {
1007     getActionDefinitionsBuilder({G_SSUBE, G_USUBE}).legalFor({{s16, s16}});
1008   });
1009   // Build
1010   // Trunc it to s8.
1011   LLT s8{LLT::scalar(8)};
1012   LLT s16{LLT::scalar(16)};
1013   auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
1014   auto CarryIn = B.buildUndef(LLT::scalar(1));
1015   Register CarryReg = MRI->createGenericVirtualRegister(LLT::scalar(1));
1016   auto MIBSSUBE = B.buildInstr(TargetOpcode::G_SSUBE, {s8, CarryReg},
1017                                {MIBTrunc, MIBTrunc, CarryIn});
1018   AInfo Info(MF->getSubtarget());
1019   DummyGISelObserver Observer;
1020   LegalizerHelper Helper(*MF, Info, Observer, B);
1021   EXPECT_TRUE(Helper.widenScalar(*MIBSSUBE, 0, s16) ==
1022               LegalizerHelper::LegalizeResult::Legalized);
1023 
1024   const char *CheckStr = R"(
1025   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
1026   CHECK: [[Implicit:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF
1027   CHECK: [[LHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]]
1028   CHECK: [[RHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]]
1029   CHECK: [[SSUBE:%[0-9]+]]:_(s16), [[CARRY:%[0-9]+]]:_(s1) = G_USUBE [[LHS]]:_, [[RHS]]:_, [[Implicit]]:_
1030   CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[SSUBE]]
1031   CHECK: [[SEXT:%[0-9]+]]:_(s16) = G_SEXT [[TRUNC1]]
1032   CHECK: G_ICMP intpred(ne), [[SSUBE]]:_(s16), [[SEXT]]:_
1033   CHECK: G_TRUNC [[SSUBE]]
1034   )";
1035 
1036   // Check
1037   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
1038 }
1039 
1040 TEST_F(AArch64GISelMITest, 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.buildMerge(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.buildMerge(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.buildMerge(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.buildMerge(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.buildMerge(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, LibcallSRem) {
2140   setUp();
2141   if (!TM)
2142     return;
2143 
2144   // Declare your legalization info
2145   DefineLegalizerInfo(A, {
2146     getActionDefinitionsBuilder(G_SREM).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 MIBSRem32 =
2156       B.buildInstr(TargetOpcode::G_SREM, {S32}, {MIBTrunc, MIBTrunc});
2157   auto MIBSRem64 =
2158       B.buildInstr(TargetOpcode::G_SREM, {S64}, {Copies[0], Copies[0]});
2159   auto MIBSRem128 =
2160       B.buildInstr(TargetOpcode::G_SREM, {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(*MIBSRem32, DummyLocObserver));
2169   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2170             Helper.libcall(*MIBSRem64, DummyLocObserver));
2171   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2172             Helper.libcall(*MIBSRem128, 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 &__modsi3
2181   CHECK: $x0 = COPY [[COPY]]
2182   CHECK: $x1 = COPY [[COPY]]
2183   CHECK: BL &__moddi3
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 &__modti3
2191   )";
2192 
2193   // Check
2194   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2195 }
2196 
2197 TEST_F(AArch64GISelMITest, LibcallURem) {
2198   setUp();
2199   if (!TM)
2200     return;
2201 
2202   // Declare your legalization info
2203   DefineLegalizerInfo(A, {
2204     getActionDefinitionsBuilder(G_UREM).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 MIBURem32 =
2214       B.buildInstr(TargetOpcode::G_UREM, {S32}, {MIBTrunc, MIBTrunc});
2215   auto MIBURem64 =
2216       B.buildInstr(TargetOpcode::G_UREM, {S64}, {Copies[0], Copies[0]});
2217   auto MIBURem128 =
2218       B.buildInstr(TargetOpcode::G_UREM, {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(*MIBURem32, DummyLocObserver));
2227   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2228             Helper.libcall(*MIBURem64, DummyLocObserver));
2229   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2230             Helper.libcall(*MIBURem128, DummyLocObserver));
2231 
2232   const 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 &__umodsi3
2239   CHECK: $x0 = COPY [[COPY]]
2240   CHECK: $x1 = COPY [[COPY]]
2241   CHECK: BL &__umoddi3
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 &__umodti3
2249   )";
2250 
2251   // Check
2252   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2253 }
2254 
2255 TEST_F(AArch64GISelMITest, LibcallCtlzZeroUndef) {
2256   setUp();
2257   if (!TM)
2258     return;
2259 
2260   // Declare your legalization info
2261   DefineLegalizerInfo(A, {
2262     getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF)
2263         .libcallFor({{s32, s32}, {s64, s64}, {s128, s128}});
2264   });
2265 
2266   LLT S32{LLT::scalar(32)};
2267   LLT S64{LLT::scalar(64)};
2268   LLT S128{LLT::scalar(128)};
2269   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2270   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2271 
2272   auto MIBCtlz32 =
2273       B.buildInstr(TargetOpcode::G_CTLZ_ZERO_UNDEF, {S32}, {MIBTrunc});
2274   auto MIBCtlz64 =
2275       B.buildInstr(TargetOpcode::G_CTLZ_ZERO_UNDEF, {S64}, {Copies[0]});
2276   auto MIBCtlz128 =
2277       B.buildInstr(TargetOpcode::G_CTLZ_ZERO_UNDEF, {S128}, {MIBExt});
2278 
2279   AInfo Info(MF->getSubtarget());
2280   DummyGISelObserver Observer;
2281   LostDebugLocObserver DummyLocObserver("");
2282   LegalizerHelper Helper(*MF, Info, Observer, B);
2283 
2284   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2285             Helper.libcall(*MIBCtlz32, DummyLocObserver));
2286   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2287             Helper.libcall(*MIBCtlz64, DummyLocObserver));
2288   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2289             Helper.libcall(*MIBCtlz128, DummyLocObserver));
2290 
2291   const auto *CheckStr = R"(
2292   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2293   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2294   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2295   CHECK: $w0 = COPY [[TRUNC]]
2296   CHECK: BL &__clzsi2
2297   CHECK: $x0 = COPY [[COPY]]
2298   CHECK: BL &__clzdi2
2299   CHECK: [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[ANYEXT]]
2300   CHECK: $x0 = COPY [[UV]]
2301   CHECK: $x1 = COPY [[UV1]]
2302   CHECK: BL &__clzti2
2303   )";
2304 
2305   // Check
2306   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2307 }
2308 
2309 TEST_F(AArch64GISelMITest, LibcallFAdd) {
2310   setUp();
2311   if (!TM)
2312     return;
2313 
2314   // Declare your legalization info
2315   DefineLegalizerInfo(A, {
2316     getActionDefinitionsBuilder(G_FADD).libcallFor({s32, s64, s128});
2317   });
2318 
2319   LLT S32{LLT::scalar(32)};
2320   LLT S64{LLT::scalar(64)};
2321   LLT S128{LLT::scalar(128)};
2322   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2323   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2324 
2325   auto MIBAdd32 =
2326       B.buildInstr(TargetOpcode::G_FADD, {S32}, {MIBTrunc, MIBTrunc});
2327   auto MIBAdd64 =
2328       B.buildInstr(TargetOpcode::G_FADD, {S64}, {Copies[0], Copies[0]});
2329   auto MIBAdd128 = B.buildInstr(TargetOpcode::G_FADD, {S128}, {MIBExt, MIBExt});
2330 
2331   AInfo Info(MF->getSubtarget());
2332   DummyGISelObserver Observer;
2333   LostDebugLocObserver DummyLocObserver("");
2334   LegalizerHelper Helper(*MF, Info, Observer, B);
2335 
2336   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2337             Helper.libcall(*MIBAdd32, DummyLocObserver));
2338   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2339             Helper.libcall(*MIBAdd64, DummyLocObserver));
2340   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2341             Helper.libcall(*MIBAdd128, DummyLocObserver));
2342 
2343   const auto *CheckStr = R"(
2344   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2345   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2346   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2347   CHECK: $s0 = COPY [[TRUNC]]
2348   CHECK: $s1 = COPY [[TRUNC]]
2349   CHECK: BL &__addsf3
2350   CHECK: $d0 = COPY [[COPY]]
2351   CHECK: $d1 = COPY [[COPY]]
2352   CHECK: BL &__adddf3
2353   CHECK: $q0 = COPY [[ANYEXT]]
2354   CHECK: $q1 = COPY [[ANYEXT]]
2355   CHECK: BL &__addtf3
2356   )";
2357 
2358   // Check
2359   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2360 }
2361 
2362 TEST_F(AArch64GISelMITest, LibcallFSub) {
2363   setUp();
2364   if (!TM)
2365     return;
2366 
2367   // Declare your legalization info
2368   DefineLegalizerInfo(A, {
2369     getActionDefinitionsBuilder(G_FSUB).libcallFor({s32, s64, s128});
2370   });
2371 
2372   LLT S32{LLT::scalar(32)};
2373   LLT S64{LLT::scalar(64)};
2374   LLT S128{LLT::scalar(128)};
2375   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2376   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2377 
2378   auto MIBSub32 =
2379       B.buildInstr(TargetOpcode::G_FSUB, {S32}, {MIBTrunc, MIBTrunc});
2380   auto MIBSub64 =
2381       B.buildInstr(TargetOpcode::G_FSUB, {S64}, {Copies[0], Copies[0]});
2382   auto MIBSub128 = B.buildInstr(TargetOpcode::G_FSUB, {S128}, {MIBExt, MIBExt});
2383 
2384   AInfo Info(MF->getSubtarget());
2385   DummyGISelObserver Observer;
2386   LostDebugLocObserver DummyLocObserver("");
2387   LegalizerHelper Helper(*MF, Info, Observer, B);
2388 
2389   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2390             Helper.libcall(*MIBSub32, DummyLocObserver));
2391   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2392             Helper.libcall(*MIBSub64, DummyLocObserver));
2393   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2394             Helper.libcall(*MIBSub128, DummyLocObserver));
2395 
2396   const auto *CheckStr = R"(
2397   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2398   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2399   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2400   CHECK: $s0 = COPY [[TRUNC]]
2401   CHECK: $s1 = COPY [[TRUNC]]
2402   CHECK: BL &__subsf3
2403   CHECK: $d0 = COPY [[COPY]]
2404   CHECK: $d1 = COPY [[COPY]]
2405   CHECK: BL &__subdf3
2406   CHECK: $q0 = COPY [[ANYEXT]]
2407   CHECK: $q1 = COPY [[ANYEXT]]
2408   CHECK: BL &__subtf3
2409   )";
2410 
2411   // Check
2412   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2413 }
2414 
2415 TEST_F(AArch64GISelMITest, LibcallFMul) {
2416   setUp();
2417   if (!TM)
2418     return;
2419 
2420   // Declare your legalization info
2421   DefineLegalizerInfo(A, {
2422     getActionDefinitionsBuilder(G_FMUL).libcallFor({s32, s64, s128});
2423   });
2424 
2425   LLT S32{LLT::scalar(32)};
2426   LLT S64{LLT::scalar(64)};
2427   LLT S128{LLT::scalar(128)};
2428   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2429   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2430 
2431   auto MIBMul32 =
2432       B.buildInstr(TargetOpcode::G_FMUL, {S32}, {MIBTrunc, MIBTrunc});
2433   auto MIBMul64 =
2434       B.buildInstr(TargetOpcode::G_FMUL, {S64}, {Copies[0], Copies[0]});
2435   auto MIBMul128 = B.buildInstr(TargetOpcode::G_FMUL, {S128}, {MIBExt, MIBExt});
2436 
2437   AInfo Info(MF->getSubtarget());
2438   DummyGISelObserver Observer;
2439   LegalizerHelper Helper(*MF, Info, Observer, B);
2440   LostDebugLocObserver DummyLocObserver("");
2441 
2442   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2443             Helper.libcall(*MIBMul32, DummyLocObserver));
2444   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2445             Helper.libcall(*MIBMul64, DummyLocObserver));
2446   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2447             Helper.libcall(*MIBMul128, DummyLocObserver));
2448 
2449   const auto *CheckStr = R"(
2450   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2451   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2452   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2453   CHECK: $s0 = COPY [[TRUNC]]
2454   CHECK: $s1 = COPY [[TRUNC]]
2455   CHECK: BL &__mulsf3
2456   CHECK: $d0 = COPY [[COPY]]
2457   CHECK: $d1 = COPY [[COPY]]
2458   CHECK: BL &__muldf3
2459   CHECK: $q0 = COPY [[ANYEXT]]
2460   CHECK: $q1 = COPY [[ANYEXT]]
2461   CHECK: BL &__multf3
2462   )";
2463 
2464   // Check
2465   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2466 }
2467 
2468 TEST_F(AArch64GISelMITest, LibcallFDiv) {
2469   setUp();
2470   if (!TM)
2471     return;
2472 
2473   // Declare your legalization info
2474   DefineLegalizerInfo(A, {
2475     getActionDefinitionsBuilder(G_FDIV).libcallFor({s32, s64, s128});
2476   });
2477 
2478   LLT S32{LLT::scalar(32)};
2479   LLT S64{LLT::scalar(64)};
2480   LLT S128{LLT::scalar(128)};
2481   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2482   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2483 
2484   auto MIBDiv32 =
2485       B.buildInstr(TargetOpcode::G_FDIV, {S32}, {MIBTrunc, MIBTrunc});
2486   auto MIBDiv64 =
2487       B.buildInstr(TargetOpcode::G_FDIV, {S64}, {Copies[0], Copies[0]});
2488   auto MIBDiv128 = B.buildInstr(TargetOpcode::G_FDIV, {S128}, {MIBExt, MIBExt});
2489 
2490   AInfo Info(MF->getSubtarget());
2491   DummyGISelObserver Observer;
2492   LostDebugLocObserver DummyLocObserver("");
2493   LegalizerHelper Helper(*MF, Info, Observer, B);
2494 
2495   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2496             Helper.libcall(*MIBDiv32, DummyLocObserver));
2497   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2498             Helper.libcall(*MIBDiv64, DummyLocObserver));
2499   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2500             Helper.libcall(*MIBDiv128, DummyLocObserver));
2501 
2502   const auto *CheckStr = R"(
2503   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2504   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2505   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2506   CHECK: $s0 = COPY [[TRUNC]]
2507   CHECK: $s1 = COPY [[TRUNC]]
2508   CHECK: BL &__divsf3
2509   CHECK: $d0 = COPY [[COPY]]
2510   CHECK: $d1 = COPY [[COPY]]
2511   CHECK: BL &__divdf3
2512   CHECK: $q0 = COPY [[ANYEXT]]
2513   CHECK: $q1 = COPY [[ANYEXT]]
2514   CHECK: BL &__divtf3
2515   )";
2516 
2517   // Check
2518   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2519 }
2520 
2521 TEST_F(AArch64GISelMITest, LibcallFExp) {
2522   setUp();
2523   if (!TM)
2524     return;
2525 
2526   // Declare your legalization info
2527   DefineLegalizerInfo(A, {
2528     getActionDefinitionsBuilder(G_FEXP).libcallFor({s32, s64, s128});
2529   });
2530 
2531   LLT S32{LLT::scalar(32)};
2532   LLT S64{LLT::scalar(64)};
2533   LLT S128{LLT::scalar(128)};
2534   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2535   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2536 
2537   auto MIBExp32 = B.buildInstr(TargetOpcode::G_FEXP, {S32}, {MIBTrunc});
2538   auto MIBExp64 = B.buildInstr(TargetOpcode::G_FEXP, {S64}, {Copies[0]});
2539   auto MIBExp128 = B.buildInstr(TargetOpcode::G_FEXP, {S128}, {MIBExt});
2540 
2541   AInfo Info(MF->getSubtarget());
2542   DummyGISelObserver Observer;
2543   LostDebugLocObserver DummyLocObserver("");
2544   LegalizerHelper Helper(*MF, Info, Observer, B);
2545 
2546   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2547             Helper.libcall(*MIBExp32, DummyLocObserver));
2548   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2549             Helper.libcall(*MIBExp64, DummyLocObserver));
2550   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2551             Helper.libcall(*MIBExp128, DummyLocObserver));
2552 
2553   const auto *CheckStr = R"(
2554   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2555   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2556   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2557   CHECK: $s0 = COPY [[TRUNC]]
2558   CHECK: BL &expf
2559   CHECK: $d0 = COPY [[COPY]]
2560   CHECK: BL &exp
2561   CHECK: $q0 = COPY [[ANYEXT]]
2562   CHECK: BL &expl
2563   )";
2564 
2565   // Check
2566   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2567 }
2568 
2569 TEST_F(AArch64GISelMITest, LibcallFExp2) {
2570   setUp();
2571   if (!TM)
2572     return;
2573 
2574   // Declare your legalization info
2575   DefineLegalizerInfo(A, {
2576     getActionDefinitionsBuilder(G_FEXP2).libcallFor({s32, s64, s128});
2577   });
2578 
2579   LLT S32{LLT::scalar(32)};
2580   LLT S64{LLT::scalar(64)};
2581   LLT S128{LLT::scalar(128)};
2582   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2583   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2584 
2585   auto MIBExp232 = B.buildInstr(TargetOpcode::G_FEXP2, {S32}, {MIBTrunc});
2586   auto MIBExp264 = B.buildInstr(TargetOpcode::G_FEXP2, {S64}, {Copies[0]});
2587   auto MIBExp2128 = B.buildInstr(TargetOpcode::G_FEXP2, {S128}, {MIBExt});
2588 
2589   AInfo Info(MF->getSubtarget());
2590   DummyGISelObserver Observer;
2591   LostDebugLocObserver DummyLocObserver("");
2592   LegalizerHelper Helper(*MF, Info, Observer, B);
2593 
2594   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2595             Helper.libcall(*MIBExp232, DummyLocObserver));
2596   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2597             Helper.libcall(*MIBExp264, DummyLocObserver));
2598   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2599             Helper.libcall(*MIBExp2128, DummyLocObserver));
2600 
2601   const auto *CheckStr = R"(
2602   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2603   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2604   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2605   CHECK: $s0 = COPY [[TRUNC]]
2606   CHECK: BL &exp2f
2607   CHECK: $d0 = COPY [[COPY]]
2608   CHECK: BL &exp2
2609   CHECK: $q0 = COPY [[ANYEXT]]
2610   CHECK: BL &exp2l
2611   )";
2612 
2613   // Check
2614   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2615 }
2616 
2617 TEST_F(AArch64GISelMITest, LibcallFRem) {
2618   setUp();
2619   if (!TM)
2620     return;
2621 
2622   // Declare your legalization info
2623   DefineLegalizerInfo(A, {
2624     getActionDefinitionsBuilder(G_FREM).libcallFor({s32, s64, s128});
2625   });
2626 
2627   LLT S32{LLT::scalar(32)};
2628   LLT S64{LLT::scalar(64)};
2629   LLT S128{LLT::scalar(128)};
2630   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2631   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2632 
2633   auto MIBFRem32 = B.buildInstr(TargetOpcode::G_FREM, {S32}, {MIBTrunc});
2634   auto MIBFRem64 = B.buildInstr(TargetOpcode::G_FREM, {S64}, {Copies[0]});
2635   auto MIBFRem128 = B.buildInstr(TargetOpcode::G_FREM, {S128}, {MIBExt});
2636 
2637   AInfo Info(MF->getSubtarget());
2638   DummyGISelObserver Observer;
2639   LostDebugLocObserver DummyLocObserver("");
2640   LegalizerHelper Helper(*MF, Info, Observer, B);
2641 
2642   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2643             Helper.libcall(*MIBFRem32, DummyLocObserver));
2644   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2645             Helper.libcall(*MIBFRem64, DummyLocObserver));
2646   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2647             Helper.libcall(*MIBFRem128, DummyLocObserver));
2648 
2649   const auto *CheckStr = R"(
2650   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2651   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2652   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2653   CHECK: $s0 = COPY [[TRUNC]]
2654   CHECK: BL &fmodf
2655   CHECK: $d0 = COPY [[COPY]]
2656   CHECK: BL &fmod
2657   CHECK: $q0 = COPY [[ANYEXT]]
2658   CHECK: BL &fmodl
2659   )";
2660 
2661   // Check
2662   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2663 }
2664 
2665 TEST_F(AArch64GISelMITest, LibcallFPow) {
2666   setUp();
2667   if (!TM)
2668     return;
2669 
2670   // Declare your legalization info
2671   DefineLegalizerInfo(A, {
2672     getActionDefinitionsBuilder(G_FPOW).libcallFor({s32, s64, s128});
2673   });
2674 
2675   LLT S32{LLT::scalar(32)};
2676   LLT S64{LLT::scalar(64)};
2677   LLT S128{LLT::scalar(128)};
2678   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2679   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2680 
2681   auto MIBPow32 = B.buildInstr(TargetOpcode::G_FPOW, {S32}, {MIBTrunc});
2682   auto MIBPow64 = B.buildInstr(TargetOpcode::G_FPOW, {S64}, {Copies[0]});
2683   auto MIBPow128 = B.buildInstr(TargetOpcode::G_FPOW, {S128}, {MIBExt});
2684 
2685   AInfo Info(MF->getSubtarget());
2686   DummyGISelObserver Observer;
2687   LostDebugLocObserver DummyLocObserver("");
2688   LegalizerHelper Helper(*MF, Info, Observer, B);
2689 
2690   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2691             Helper.libcall(*MIBPow32, DummyLocObserver));
2692   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2693             Helper.libcall(*MIBPow64, DummyLocObserver));
2694   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2695             Helper.libcall(*MIBPow128, DummyLocObserver));
2696 
2697   const auto *CheckStr = R"(
2698   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2699   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2700   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2701   CHECK: $s0 = COPY [[TRUNC]]
2702   CHECK: BL &powf
2703   CHECK: $d0 = COPY [[COPY]]
2704   CHECK: BL &pow
2705   CHECK: $q0 = COPY [[ANYEXT]]
2706   CHECK: BL &powl
2707   )";
2708 
2709   // Check
2710   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2711 }
2712 
2713 TEST_F(AArch64GISelMITest, LibcallFMa) {
2714   setUp();
2715   if (!TM)
2716     return;
2717 
2718   // Declare your legalization info
2719   DefineLegalizerInfo(A, {
2720     getActionDefinitionsBuilder(G_FMA).libcallFor({s32, s64, s128});
2721   });
2722 
2723   LLT S32{LLT::scalar(32)};
2724   LLT S64{LLT::scalar(64)};
2725   LLT S128{LLT::scalar(128)};
2726   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2727   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2728 
2729   auto MIBMa32 = B.buildInstr(TargetOpcode::G_FMA, {S32}, {MIBTrunc, MIBTrunc});
2730   auto MIBMa64 =
2731       B.buildInstr(TargetOpcode::G_FMA, {S64}, {Copies[0], Copies[0]});
2732   auto MIBMa128 = B.buildInstr(TargetOpcode::G_FMA, {S128}, {MIBExt, MIBExt});
2733 
2734   AInfo Info(MF->getSubtarget());
2735   DummyGISelObserver Observer;
2736   LostDebugLocObserver DummyLocObserver("");
2737   LegalizerHelper Helper(*MF, Info, Observer, B);
2738 
2739   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2740             Helper.libcall(*MIBMa32, DummyLocObserver));
2741   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2742             Helper.libcall(*MIBMa64, DummyLocObserver));
2743   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2744             Helper.libcall(*MIBMa128, DummyLocObserver));
2745 
2746   const auto *CheckStr = R"(
2747   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2748   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2749   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2750   CHECK: $s0 = COPY [[TRUNC]]
2751   CHECK: BL &fmaf
2752   CHECK: $d0 = COPY [[COPY]]
2753   CHECK: BL &fma
2754   CHECK: $q0 = COPY [[ANYEXT]]
2755   CHECK: BL &fmal
2756   )";
2757 
2758   // Check
2759   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2760 }
2761 
2762 TEST_F(AArch64GISelMITest, LibcallFCeil) {
2763   setUp();
2764   if (!TM)
2765     return;
2766 
2767   // Declare your legalization info
2768   DefineLegalizerInfo(A, {
2769     getActionDefinitionsBuilder(G_FCEIL).libcallFor({s32, s64, s128});
2770   });
2771 
2772   LLT S32{LLT::scalar(32)};
2773   LLT S64{LLT::scalar(64)};
2774   LLT S128{LLT::scalar(128)};
2775   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2776   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2777 
2778   auto MIBCeil32 = B.buildInstr(TargetOpcode::G_FCEIL, {S32}, {MIBTrunc});
2779   auto MIBCeil64 = B.buildInstr(TargetOpcode::G_FCEIL, {S64}, {Copies[0]});
2780   auto MIBCeil128 = B.buildInstr(TargetOpcode::G_FCEIL, {S128}, {MIBExt});
2781 
2782   AInfo Info(MF->getSubtarget());
2783   DummyGISelObserver Observer;
2784   LegalizerHelper Helper(*MF, Info, Observer, B);
2785   LostDebugLocObserver DummyLocObserver("");
2786 
2787   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2788             Helper.libcall(*MIBCeil32, DummyLocObserver));
2789   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2790             Helper.libcall(*MIBCeil64, DummyLocObserver));
2791   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2792             Helper.libcall(*MIBCeil128, DummyLocObserver));
2793 
2794   const auto *CheckStr = R"(
2795   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2796   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2797   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2798   CHECK: $s0 = COPY [[TRUNC]]
2799   CHECK: BL &ceilf
2800   CHECK: $d0 = COPY [[COPY]]
2801   CHECK: BL &ceil
2802   CHECK: $q0 = COPY [[ANYEXT]]
2803   CHECK: BL &ceill
2804   )";
2805 
2806   // Check
2807   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2808 }
2809 
2810 TEST_F(AArch64GISelMITest, LibcallFFloor) {
2811   setUp();
2812   if (!TM)
2813     return;
2814 
2815   // Declare your legalization info
2816   DefineLegalizerInfo(A, {
2817     getActionDefinitionsBuilder(G_FFLOOR).libcallFor({s32, s64, s128});
2818   });
2819 
2820   LLT S32{LLT::scalar(32)};
2821   LLT S64{LLT::scalar(64)};
2822   LLT S128{LLT::scalar(128)};
2823   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2824   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2825 
2826   auto MIBFloor32 = B.buildInstr(TargetOpcode::G_FFLOOR, {S32}, {MIBTrunc});
2827   auto MIBFloor64 = B.buildInstr(TargetOpcode::G_FFLOOR, {S64}, {Copies[0]});
2828   auto MIBFloor128 = B.buildInstr(TargetOpcode::G_FFLOOR, {S128}, {MIBExt});
2829 
2830   AInfo Info(MF->getSubtarget());
2831   DummyGISelObserver Observer;
2832   LegalizerHelper Helper(*MF, Info, Observer, B);
2833   LostDebugLocObserver DummyLocObserver("");
2834 
2835   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2836             Helper.libcall(*MIBFloor32, DummyLocObserver));
2837   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2838             Helper.libcall(*MIBFloor64, DummyLocObserver));
2839   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2840             Helper.libcall(*MIBFloor128, DummyLocObserver));
2841 
2842   const auto *CheckStr = R"(
2843   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2844   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2845   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2846   CHECK: $s0 = COPY [[TRUNC]]
2847   CHECK: BL &floorf
2848   CHECK: $d0 = COPY [[COPY]]
2849   CHECK: BL &floor
2850   CHECK: $q0 = COPY [[ANYEXT]]
2851   CHECK: BL &floorl
2852   )";
2853 
2854   // Check
2855   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2856 }
2857 
2858 TEST_F(AArch64GISelMITest, LibcallFMinNum) {
2859   setUp();
2860   if (!TM)
2861     return;
2862 
2863   // Declare your legalization info
2864   DefineLegalizerInfo(A, {
2865     getActionDefinitionsBuilder(G_FMINNUM).libcallFor({s32, s64, s128});
2866   });
2867 
2868   LLT S32{LLT::scalar(32)};
2869   LLT S64{LLT::scalar(64)};
2870   LLT S128{LLT::scalar(128)};
2871   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2872   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2873 
2874   auto MIBMin32 = B.buildFMinNum(S32, MIBTrunc, MIBTrunc);
2875   auto MIBMin64 = B.buildFMinNum(S64, Copies[0], Copies[0]);
2876   auto MIBMin128 = B.buildFMinNum(S128, MIBExt, MIBExt);
2877 
2878   AInfo Info(MF->getSubtarget());
2879   DummyGISelObserver Observer;
2880   LegalizerHelper Helper(*MF, Info, Observer, B);
2881   LostDebugLocObserver DummyLocObserver("");
2882 
2883   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2884             Helper.libcall(*MIBMin32, DummyLocObserver));
2885   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2886             Helper.libcall(*MIBMin64, DummyLocObserver));
2887   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2888             Helper.libcall(*MIBMin128, DummyLocObserver));
2889 
2890   const auto *CheckStr = R"(
2891   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2892   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2893   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2894   CHECK: $s0 = COPY [[TRUNC]]
2895   CHECK: $s1 = COPY [[TRUNC]]
2896   CHECK: BL &fminf
2897   CHECK: $d0 = COPY [[COPY]]
2898   CHECK: $d1 = COPY [[COPY]]
2899   CHECK: BL &fmin
2900   CHECK: $q0 = COPY [[ANYEXT]]
2901   CHECK: $q1 = COPY [[ANYEXT]]
2902   CHECK: BL &fminl
2903   )";
2904 
2905   // Check
2906   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2907 }
2908 
2909 TEST_F(AArch64GISelMITest, LibcallFMaxNum) {
2910   setUp();
2911   if (!TM)
2912     return;
2913 
2914   // Declare your legalization info
2915   DefineLegalizerInfo(A, {
2916     getActionDefinitionsBuilder(G_FMAXNUM).libcallFor({s32, s64, s128});
2917   });
2918 
2919   LLT S32{LLT::scalar(32)};
2920   LLT S64{LLT::scalar(64)};
2921   LLT S128{LLT::scalar(128)};
2922   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2923   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2924 
2925   auto MIBMax32 = B.buildFMaxNum(S32, MIBTrunc, MIBTrunc);
2926   auto MIBMax64 = B.buildFMaxNum(S64, Copies[0], Copies[0]);
2927   auto MIBMax128 = B.buildFMaxNum(S128, MIBExt, MIBExt);
2928 
2929   AInfo Info(MF->getSubtarget());
2930   DummyGISelObserver Observer;
2931   LegalizerHelper Helper(*MF, Info, Observer, B);
2932   LostDebugLocObserver DummyLocObserver("");
2933 
2934   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2935             Helper.libcall(*MIBMax32, DummyLocObserver));
2936   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2937             Helper.libcall(*MIBMax64, DummyLocObserver));
2938   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2939             Helper.libcall(*MIBMax128, DummyLocObserver));
2940 
2941   const auto *CheckStr = R"(
2942   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2943   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2944   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2945   CHECK: $s0 = COPY [[TRUNC]]
2946   CHECK: $s1 = COPY [[TRUNC]]
2947   CHECK: BL &fmaxf
2948   CHECK: $d0 = COPY [[COPY]]
2949   CHECK: $d1 = COPY [[COPY]]
2950   CHECK: BL &fmax
2951   CHECK: $q0 = COPY [[ANYEXT]]
2952   CHECK: $q1 = COPY [[ANYEXT]]
2953   CHECK: BL &fmaxl
2954   )";
2955 
2956   // Check
2957   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
2958 }
2959 
2960 TEST_F(AArch64GISelMITest, LibcallFSqrt) {
2961   setUp();
2962   if (!TM)
2963     return;
2964 
2965   // Declare your legalization info
2966   DefineLegalizerInfo(A, {
2967     getActionDefinitionsBuilder(G_FSQRT).libcallFor({s32, s64, s128});
2968   });
2969 
2970   LLT S32{LLT::scalar(32)};
2971   LLT S64{LLT::scalar(64)};
2972   LLT S128{LLT::scalar(128)};
2973   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
2974   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
2975 
2976   auto MIBSqrt32 = B.buildInstr(TargetOpcode::G_FSQRT, {S32}, {MIBTrunc});
2977   auto MIBSqrt64 = B.buildInstr(TargetOpcode::G_FSQRT, {S64}, {Copies[0]});
2978   auto MIBSqrt128 = B.buildInstr(TargetOpcode::G_FSQRT, {S128}, {MIBExt});
2979 
2980   AInfo Info(MF->getSubtarget());
2981   DummyGISelObserver Observer;
2982   LegalizerHelper Helper(*MF, Info, Observer, B);
2983   LostDebugLocObserver DummyLocObserver("");
2984 
2985   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2986             Helper.libcall(*MIBSqrt32, DummyLocObserver));
2987   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2988             Helper.libcall(*MIBSqrt64, DummyLocObserver));
2989   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
2990             Helper.libcall(*MIBSqrt128, DummyLocObserver));
2991 
2992   const auto *CheckStr = R"(
2993   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2994   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2995   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2996   CHECK: $s0 = COPY [[TRUNC]]
2997   CHECK: BL &sqrtf
2998   CHECK: $d0 = COPY [[COPY]]
2999   CHECK: BL &sqrt
3000   CHECK: $q0 = COPY [[ANYEXT]]
3001   CHECK: BL &sqrtl
3002   )";
3003 
3004   // Check
3005   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3006 }
3007 
3008 TEST_F(AArch64GISelMITest, LibcallFRint) {
3009   setUp();
3010   if (!TM)
3011     return;
3012 
3013   // Declare your legalization info
3014   DefineLegalizerInfo(A, {
3015     getActionDefinitionsBuilder(G_FRINT).libcallFor({s32, s64, s128});
3016   });
3017 
3018   LLT S32{LLT::scalar(32)};
3019   LLT S64{LLT::scalar(64)};
3020   LLT S128{LLT::scalar(128)};
3021   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
3022   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
3023 
3024   auto MIBRint32 = B.buildInstr(TargetOpcode::G_FRINT, {S32}, {MIBTrunc});
3025   auto MIBRint64 = B.buildInstr(TargetOpcode::G_FRINT, {S64}, {Copies[0]});
3026   auto MIBRint128 = B.buildInstr(TargetOpcode::G_FRINT, {S128}, {MIBExt});
3027 
3028   AInfo Info(MF->getSubtarget());
3029   DummyGISelObserver Observer;
3030   LegalizerHelper Helper(*MF, Info, Observer, B);
3031   LostDebugLocObserver DummyLocObserver("");
3032 
3033   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3034             Helper.libcall(*MIBRint32, DummyLocObserver));
3035   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3036             Helper.libcall(*MIBRint64, DummyLocObserver));
3037   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3038             Helper.libcall(*MIBRint128, DummyLocObserver));
3039 
3040   const auto *CheckStr = R"(
3041   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
3042   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
3043   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
3044   CHECK: $s0 = COPY [[TRUNC]]
3045   CHECK: BL &rintf
3046   CHECK: $d0 = COPY [[COPY]]
3047   CHECK: BL &rint
3048   CHECK: $q0 = COPY [[ANYEXT]]
3049   CHECK: BL &rintl
3050   )";
3051 
3052   // Check
3053   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3054 }
3055 
3056 TEST_F(AArch64GISelMITest, LibcallFNearbyInt) {
3057   setUp();
3058   if (!TM)
3059     return;
3060 
3061   // Declare your legalization info
3062   DefineLegalizerInfo(A, {
3063     getActionDefinitionsBuilder(G_FNEARBYINT).libcallFor({s32, s64, s128});
3064   });
3065 
3066   LLT S32{LLT::scalar(32)};
3067   LLT S64{LLT::scalar(64)};
3068   LLT S128{LLT::scalar(128)};
3069   auto MIBTrunc = B.buildTrunc(S32, Copies[0]);
3070   auto MIBExt = B.buildAnyExt(S128, Copies[0]);
3071 
3072   auto MIBNearbyInt32 =
3073       B.buildInstr(TargetOpcode::G_FNEARBYINT, {S32}, {MIBTrunc});
3074   auto MIBNearbyInt64 =
3075       B.buildInstr(TargetOpcode::G_FNEARBYINT, {S64}, {Copies[0]});
3076   auto MIBNearbyInt128 =
3077       B.buildInstr(TargetOpcode::G_FNEARBYINT, {S128}, {MIBExt});
3078 
3079   AInfo Info(MF->getSubtarget());
3080   DummyGISelObserver Observer;
3081   LegalizerHelper Helper(*MF, Info, Observer, B);
3082   LostDebugLocObserver DummyLocObserver("");
3083 
3084   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3085             Helper.libcall(*MIBNearbyInt32, DummyLocObserver));
3086   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3087             Helper.libcall(*MIBNearbyInt64, DummyLocObserver));
3088   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3089             Helper.libcall(*MIBNearbyInt128, DummyLocObserver));
3090 
3091   const auto *CheckStr = R"(
3092   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
3093   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
3094   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
3095   CHECK: $s0 = COPY [[TRUNC]]
3096   CHECK: BL &nearbyintf
3097   CHECK: $d0 = COPY [[COPY]]
3098   CHECK: BL &nearbyint
3099   CHECK: $q0 = COPY [[ANYEXT]]
3100   CHECK: BL &nearbyintl
3101   )";
3102 
3103   // Check
3104   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3105 }
3106 
3107 TEST_F(AArch64GISelMITest, NarrowScalarExtract) {
3108   setUp();
3109   if (!TM)
3110     return;
3111 
3112   // Declare your legalization info
3113   DefineLegalizerInfo(A, {
3114     getActionDefinitionsBuilder(G_UNMERGE_VALUES).legalFor({{s32, s64}});
3115     getActionDefinitionsBuilder(G_EXTRACT).legalForTypeWithAnyImm({{s16, s32}});
3116   });
3117 
3118   LLT S16{LLT::scalar(16)};
3119   LLT S32{LLT::scalar(32)};
3120 
3121   auto MIBExtractS32 = B.buildExtract(S32, Copies[1], 32);
3122   auto MIBExtractS16 = B.buildExtract(S16, Copies[1], 0);
3123 
3124   AInfo Info(MF->getSubtarget());
3125   DummyGISelObserver Observer;
3126   LegalizerHelper Helper(*MF, Info, Observer, B);
3127 
3128   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3129             Helper.narrowScalar(*MIBExtractS32, 1, S32));
3130 
3131   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3132             Helper.narrowScalar(*MIBExtractS16, 1, S32));
3133 
3134   const auto *CheckStr = R"(
3135   CHECK: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES
3136   CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY [[UV1]]
3137   CHECK: [[UV3:%[0-9]+]]:_(s32), [[UV4:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES
3138   CHECK: [[EXTR:%[0-9]+]]:_(s16) = G_EXTRACT [[UV3]]:_(s32), 0
3139   CHECK: [[COPY:%[0-9]+]]:_(s16) = COPY [[EXTR]]
3140   )";
3141 
3142   // Check
3143   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3144 }
3145 
3146 TEST_F(AArch64GISelMITest, LowerInsert) {
3147   setUp();
3148   if (!TM)
3149     return;
3150 
3151   // Declare your legalization info
3152   DefineLegalizerInfo(A, { getActionDefinitionsBuilder(G_INSERT).lower(); });
3153 
3154   LLT S32{LLT::scalar(32)};
3155   LLT S64{LLT::scalar(64)};
3156   LLT P0{LLT::pointer(0, 64)};
3157   LLT P1{LLT::pointer(1, 32)};
3158   LLT V2S32{LLT::fixed_vector(2, 32)};
3159 
3160   auto TruncS32 = B.buildTrunc(S32, Copies[0]);
3161   auto IntToPtrP0 = B.buildIntToPtr(P0, Copies[0]);
3162   auto IntToPtrP1 = B.buildIntToPtr(P1, TruncS32);
3163   auto BitcastV2S32 = B.buildBitcast(V2S32, Copies[0]);
3164 
3165   auto InsertS64S32 = B.buildInsert(S64, Copies[0], TruncS32, 0);
3166   auto InsertS64P1 = B.buildInsert(S64, Copies[0], IntToPtrP1, 8);
3167   auto InsertP0S32 = B.buildInsert(P0, IntToPtrP0, TruncS32, 16);
3168   auto InsertP0P1 = B.buildInsert(P0, IntToPtrP0, IntToPtrP1, 4);
3169   auto InsertV2S32S32 = B.buildInsert(V2S32, BitcastV2S32, TruncS32, 32);
3170   auto InsertV2S32P1 = B.buildInsert(V2S32, BitcastV2S32, IntToPtrP1, 0);
3171 
3172   AInfo Info(MF->getSubtarget());
3173   DummyGISelObserver Observer;
3174   LegalizerHelper Helper(*MF, Info, Observer, B);
3175 
3176   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3177             Helper.lower(*InsertS64S32, 0, LLT{}));
3178 
3179   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3180             Helper.lower(*InsertS64P1, 0, LLT{}));
3181 
3182   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3183             Helper.lower(*InsertP0S32, 0, LLT{}));
3184 
3185   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3186             Helper.lower(*InsertP0P1, 0, LLT{}));
3187 
3188   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3189             Helper.lower(*InsertV2S32S32, 0, LLT{}));
3190 
3191   EXPECT_EQ(LegalizerHelper::LegalizeResult::UnableToLegalize,
3192             Helper.lower(*InsertV2S32P1, 0, LLT{}));
3193 
3194   const auto *CheckStr = R"(
3195   CHECK: [[S64:%[0-9]+]]:_(s64) = COPY
3196   CHECK: [[S32:%[0-9]+]]:_(s32) = G_TRUNC [[S64]]
3197   CHECK: [[P0:%[0-9]+]]:_(p0) = G_INTTOPTR [[S64]]
3198   CHECK: [[P1:%[0-9]+]]:_(p1) = G_INTTOPTR [[S32]]
3199   CHECK: [[V2S32:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[S64]]
3200   CHECK: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[S32]]
3201   CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT
3202   CHECK: [[AND:%[0-9]+]]:_(s64) = G_AND [[S64]]:_, [[C]]:_
3203   CHECK: [[OR:%[0-9]+]]:_(s64) = G_OR [[AND]]:_, [[ZEXT]]:_
3204 
3205   CHECK: [[PTRTOINT:%[0-9]+]]:_(s32) = G_PTRTOINT [[P1]]
3206   CHECK: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[PTRTOINT]]
3207   CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT
3208   CHECK: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ZEXT]]:_, [[C]]:_(s64)
3209   CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT
3210   CHECK: [[AND:%[0-9]+]]:_(s64) = G_AND [[S64]]:_, [[C]]:_
3211   CHECK: [[OR:%[0-9]+]]:_(s64) = G_OR [[AND]]:_, [[SHL]]:_
3212 
3213   CHECK: [[PTRTOINT:%[0-9]+]]:_(s64) = G_PTRTOINT [[P0]]
3214   CHECK: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[S32]]
3215   CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT
3216   CHECK: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ZEXT]]:_, [[C]]:_(s64)
3217   CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT
3218   CHECK: [[AND:%[0-9]+]]:_(s64) = G_AND [[PTRTOINT]]:_, [[C]]:_
3219   CHECK: [[OR:%[0-9]+]]:_(s64) = G_OR [[AND]]:_, [[SHL]]:_
3220   CHECK: [[INTTOPTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[OR]]
3221 
3222   CHECK: [[PTRTOINT:%[0-9]+]]:_(s64) = G_PTRTOINT [[P0]]
3223   CHECK: [[PTRTOINT1:%[0-9]+]]:_(s32) = G_PTRTOINT [[P1]]
3224   CHECK: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[PTRTOINT1]]
3225   CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT
3226   CHECK: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ZEXT]]:_, [[C]]:_(s64)
3227   CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT
3228   CHECK: [[AND:%[0-9]+]]:_(s64) = G_AND [[PTRTOINT]]:_, [[C]]:_
3229   CHECK: [[OR:%[0-9]+]]:_(s64) = G_OR [[AND]]:_, [[SHL]]:_
3230   CHECK: [[INTTOPTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[OR]]
3231 
3232   CHECK: [[V2S32_E0:%[0-9]+]]:_(s32), [[V2S32_E1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[V2S32]]
3233   CHECK: [[BV:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[V2S32_E0]]:_(s32), [[S32]]:_(s32)
3234   )";
3235 
3236   // Check
3237   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3238 }
3239 
3240 // Test lowering of G_FFLOOR
3241 TEST_F(AArch64GISelMITest, LowerFFloor) {
3242   setUp();
3243   if (!TM)
3244     return;
3245 
3246   // Declare your legalization info
3247   DefineLegalizerInfo(A, {});
3248   // Build Instr
3249   auto Floor = B.buildFFloor(LLT::scalar(64), Copies[0], MachineInstr::MIFlag::FmNoInfs);
3250   AInfo Info(MF->getSubtarget());
3251   DummyGISelObserver Observer;
3252   LegalizerHelper Helper(*MF, Info, Observer, B);
3253   // Perform Legalization
3254   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3255             Helper.lower(*Floor, 0, LLT()));
3256 
3257   auto CheckStr = R"(
3258   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
3259   CHECK: [[TRUNC:%[0-9]+]]:_(s64) = ninf G_INTRINSIC_TRUNC [[COPY]]
3260   CHECK: [[ZERO:%[0-9]+]]:_(s64) = G_FCONSTANT double 0.000000e+00
3261   CHECK: [[CMP0:%[0-9]+]]:_(s1) = ninf G_FCMP floatpred(olt), [[COPY]]:_(s64), [[ZERO]]:_
3262   CHECK: [[CMP1:%[0-9]+]]:_(s1) = ninf G_FCMP floatpred(one), [[COPY]]:_(s64), [[TRUNC]]:_
3263   CHECK: [[AND:%[0-9]+]]:_(s1) = G_AND [[CMP0]]:_, [[CMP1]]:_
3264   CHECK: [[ITOFP:%[0-9]+]]:_(s64) = G_SITOFP [[AND]]
3265   = ninf G_FADD [[TRUNC]]:_, [[ITOFP]]:_
3266   )";
3267 
3268   // Check
3269   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3270 }
3271 
3272 // Test lowering of G_BSWAP
3273 TEST_F(AArch64GISelMITest, LowerBSWAP) {
3274   setUp();
3275   if (!TM)
3276     return;
3277 
3278   DefineLegalizerInfo(A, {});
3279 
3280   // Make sure vector lowering doesn't assert.
3281   auto Cast = B.buildBitcast(LLT::fixed_vector(2, 32), Copies[0]);
3282   auto BSwap = B.buildBSwap(LLT::fixed_vector(2, 32), Cast);
3283   AInfo Info(MF->getSubtarget());
3284   DummyGISelObserver Observer;
3285   LegalizerHelper Helper(*MF, Info, Observer, B);
3286   // Perform Legalization
3287   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3288             Helper.lower(*BSwap, 0, LLT()));
3289 
3290   auto CheckStr = R"(
3291   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
3292   CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[COPY]]
3293   CHECK: [[K24:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
3294   CHECK: [[SPLAT24:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[K24]]:_(s32), [[K24]]:_(s32)
3295   CHECK: [[SHL0:%[0-9]+]]:_(<2 x s32>) = G_SHL [[VEC]]:_, [[SPLAT24]]
3296   CHECK: [[SHR0:%[0-9]+]]:_(<2 x s32>) = G_LSHR [[VEC]]:_, [[SPLAT24]]
3297   CHECK: [[OR0:%[0-9]+]]:_(<2 x s32>) = G_OR [[SHR0]]:_, [[SHL0]]:_
3298   CHECK: [[KMASK:%[0-9]+]]:_(s32) = G_CONSTANT i32 65280
3299   CHECK: [[SPLATMASK:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[KMASK]]:_(s32), [[KMASK]]:_(s32)
3300   CHECK: [[K8:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
3301   CHECK: [[SPLAT8:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[K8]]:_(s32), [[K8]]:_(s32)
3302   CHECK: [[AND0:%[0-9]+]]:_(<2 x s32>) = G_AND [[VEC]]:_, [[SPLATMASK]]:_
3303   CHECK: [[SHL1:%[0-9]+]]:_(<2 x s32>) = G_SHL [[AND0]]:_, [[SPLAT8]]
3304   CHECK: [[OR1:%[0-9]+]]:_(<2 x s32>) = G_OR [[OR0]]:_, [[SHL1]]:_
3305   CHECK: [[SHR1:%[0-9]+]]:_(<2 x s32>) = G_LSHR [[VEC]]:_, [[SPLAT8]]
3306   CHECK: [[AND1:%[0-9]+]]:_(<2 x s32>) = G_AND [[SHR1]]:_, [[SPLATMASK]]:_
3307   CHECK: [[BSWAP:%[0-9]+]]:_(<2 x s32>) = G_OR [[OR1]]:_, [[AND1]]:_
3308   )";
3309 
3310   // Check
3311   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3312 }
3313 
3314 // Test lowering of G_SDIVREM into G_SDIV and G_SREM
3315 TEST_F(AArch64GISelMITest, LowerSDIVREM) {
3316   setUp();
3317   if (!TM)
3318     return;
3319 
3320   // Declare your legalization info
3321   DefineLegalizerInfo(
3322       A, { getActionDefinitionsBuilder(G_SDIVREM).lowerFor({s64}); });
3323 
3324   LLT S64{LLT::scalar(64)};
3325 
3326   // Build Instr
3327   auto SDivrem =
3328       B.buildInstr(TargetOpcode::G_SDIVREM, {S64, S64}, {Copies[0], Copies[1]});
3329   AInfo Info(MF->getSubtarget());
3330   DummyGISelObserver Observer;
3331   LegalizerHelper Helper(*MF, Info, Observer, B);
3332   // Perform Legalization
3333   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3334             Helper.lower(*SDivrem, 0, S64));
3335 
3336   const auto *CheckStr = R"(
3337   CHECK: [[DIV:%[0-9]+]]:_(s64) = G_SDIV %0:_, %1:_
3338   CHECK: [[REM:%[0-9]+]]:_(s64) = G_SREM %0:_, %1:_
3339   )";
3340 
3341   // Check
3342   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3343 }
3344 
3345 // Test lowering of G_UDIVREM into G_UDIV and G_UREM
3346 TEST_F(AArch64GISelMITest, LowerUDIVREM) {
3347   setUp();
3348   if (!TM)
3349     return;
3350 
3351   // Declare your legalization info
3352   DefineLegalizerInfo(
3353       A, { getActionDefinitionsBuilder(G_UDIVREM).lowerFor({s64}); });
3354 
3355   LLT S64{LLT::scalar(64)};
3356 
3357   // Build Instr
3358   auto UDivrem =
3359       B.buildInstr(TargetOpcode::G_UDIVREM, {S64, S64}, {Copies[0], Copies[1]});
3360   AInfo Info(MF->getSubtarget());
3361   DummyGISelObserver Observer;
3362   LegalizerHelper Helper(*MF, Info, Observer, B);
3363   // Perform Legalization
3364   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3365             Helper.lower(*UDivrem, 0, S64));
3366 
3367   const auto *CheckStr = R"(
3368   CHECK: [[DIV:%[0-9]+]]:_(s64) = G_UDIV %0:_, %1:_
3369   CHECK: [[REM:%[0-9]+]]:_(s64) = G_UREM %0:_, %1:_
3370   )";
3371 
3372   // Check
3373   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3374 }
3375 
3376 // Test widening of G_UNMERGE_VALUES
3377 TEST_F(AArch64GISelMITest, WidenUnmerge) {
3378   setUp();
3379   if (!TM)
3380     return;
3381 
3382   DefineLegalizerInfo(A, {});
3383 
3384   // Check that widening G_UNMERGE_VALUES to a larger type than the source type
3385   // works as expected
3386   LLT P0{LLT::pointer(0, 64)};
3387   LLT S32{LLT::scalar(32)};
3388   LLT S96{LLT::scalar(96)};
3389 
3390   auto IntToPtr = B.buildIntToPtr(P0, Copies[0]);
3391   auto UnmergePtr = B.buildUnmerge(S32, IntToPtr);
3392   auto UnmergeScalar = B.buildUnmerge(S32, Copies[0]);
3393 
3394   AInfo Info(MF->getSubtarget());
3395   DummyGISelObserver Observer;
3396   LegalizerHelper Helper(*MF, Info, Observer, B);
3397 
3398   // Perform Legalization
3399   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3400             Helper.widenScalar(*UnmergePtr, 0, S96));
3401 
3402   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3403             Helper.widenScalar(*UnmergeScalar, 0, S96));
3404 
3405   const auto *CheckStr = R"(
3406   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
3407   CHECK: [[PTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[COPY]]
3408   CHECK: [[INT:%[0-9]+]]:_(s64) = G_PTRTOINT [[PTR]]
3409   CHECK: [[ANYEXT:%[0-9]+]]:_(s96) = G_ANYEXT [[INT]]
3410   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[ANYEXT]]
3411   CHECK: [[C:%[0-9]+]]:_(s96) = G_CONSTANT i96 32
3412   CHECK: [[LSHR:%[0-9]+]]:_(s96) = G_LSHR [[ANYEXT]]:_, [[C]]
3413   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[LSHR]]
3414   CHECK: [[ANYEXT:%[0-9]+]]:_(s96) = G_ANYEXT [[COPY]]
3415   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[ANYEXT]]
3416   CHECK: [[C:%[0-9]+]]:_(s96) = G_CONSTANT i96 32
3417   CHECK: [[LSHR:%[0-9]+]]:_(s96) = G_LSHR [[ANYEXT]]:_, [[C]]
3418   CHECK: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC [[LSHR]]
3419   )";
3420 
3421   // Check
3422   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3423 }
3424 
3425 TEST_F(AArch64GISelMITest, BitcastLoad) {
3426   setUp();
3427   if (!TM)
3428     return;
3429 
3430   LLT P0 = LLT::pointer(0, 64);
3431   LLT S32 = LLT::scalar(32);
3432   LLT V4S8 = LLT::fixed_vector(4, 8);
3433   auto Ptr = B.buildUndef(P0);
3434 
3435   DefineLegalizerInfo(A, {});
3436 
3437   MachineMemOperand *MMO = B.getMF().getMachineMemOperand(
3438       MachinePointerInfo(), MachineMemOperand::MOLoad, 4, Align(4));
3439   auto Load = B.buildLoad(V4S8, Ptr, *MMO);
3440 
3441   AInfo Info(MF->getSubtarget());
3442   DummyGISelObserver Observer;
3443   B.setInsertPt(*EntryMBB, Load->getIterator());
3444   LegalizerHelper Helper(*MF, Info, Observer, B);
3445   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3446             Helper.bitcast(*Load, 0, S32));
3447 
3448   auto CheckStr = R"(
3449   CHECK: [[PTR:%[0-9]+]]:_(p0) = G_IMPLICIT_DEF
3450   CHECK: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD
3451   CHECK: [[CAST:%[0-9]+]]:_(<4 x s8>) = G_BITCAST [[LOAD]]
3452 
3453   )";
3454 
3455   // Check
3456   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3457 }
3458 
3459 TEST_F(AArch64GISelMITest, BitcastStore) {
3460   setUp();
3461   if (!TM)
3462     return;
3463 
3464   LLT P0 = LLT::pointer(0, 64);
3465   LLT S32 = LLT::scalar(32);
3466   LLT V4S8 = LLT::fixed_vector(4, 8);
3467   auto Ptr = B.buildUndef(P0);
3468 
3469   DefineLegalizerInfo(A, {});
3470 
3471   MachineMemOperand *MMO = B.getMF().getMachineMemOperand(
3472       MachinePointerInfo(), MachineMemOperand::MOStore, 4, Align(4));
3473   auto Val = B.buildUndef(V4S8);
3474   auto Store = B.buildStore(Val, Ptr, *MMO);
3475 
3476   AInfo Info(MF->getSubtarget());
3477   DummyGISelObserver Observer;
3478   LegalizerHelper Helper(*MF, Info, Observer, B);
3479   B.setInsertPt(*EntryMBB, Store->getIterator());
3480   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3481             Helper.bitcast(*Store, 0, S32));
3482 
3483   auto CheckStr = R"(
3484   CHECK: [[VAL:%[0-9]+]]:_(<4 x s8>) = G_IMPLICIT_DEF
3485   CHECK: [[CAST:%[0-9]+]]:_(s32) = G_BITCAST [[VAL]]
3486   CHECK: G_STORE [[CAST]]
3487   )";
3488 
3489   // Check
3490   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3491 }
3492 
3493 TEST_F(AArch64GISelMITest, BitcastSelect) {
3494   setUp();
3495   if (!TM)
3496     return;
3497 
3498   LLT S1 = LLT::scalar(1);
3499   LLT S32 = LLT::scalar(32);
3500   LLT V4S8 = LLT::fixed_vector(4, 8);
3501 
3502   DefineLegalizerInfo(A, {});
3503 
3504   auto Cond = B.buildUndef(S1);
3505   auto Val0 = B.buildConstant(V4S8, 123);
3506   auto Val1 = B.buildConstant(V4S8, 99);
3507 
3508   auto Select = B.buildSelect(V4S8, Cond, Val0, Val1);
3509 
3510   AInfo Info(MF->getSubtarget());
3511   DummyGISelObserver Observer;
3512   LegalizerHelper Helper(*MF, Info, Observer, B);
3513   B.setInsertPt(*EntryMBB, Select->getIterator());
3514   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3515             Helper.bitcast(*Select, 0, S32));
3516 
3517   auto CheckStr = R"(
3518   CHECK: [[VAL0:%[0-9]+]]:_(<4 x s8>) = G_BUILD_VECTOR
3519   CHECK: [[VAL1:%[0-9]+]]:_(<4 x s8>) = G_BUILD_VECTOR
3520   CHECK: [[CAST0:%[0-9]+]]:_(s32) = G_BITCAST [[VAL0]]
3521   CHECK: [[CAST1:%[0-9]+]]:_(s32) = G_BITCAST [[VAL1]]
3522   CHECK: [[SELECT:%[0-9]+]]:_(s32) = G_SELECT %{{[0-9]+}}:_(s1), [[CAST0]]:_, [[CAST1]]:_
3523   CHECK: [[CAST2:%[0-9]+]]:_(<4 x s8>) = G_BITCAST [[SELECT]]
3524   )";
3525 
3526   // Check
3527   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3528 
3529   // Doesn't make sense
3530   auto VCond = B.buildUndef(LLT::fixed_vector(4, 1));
3531   auto VSelect = B.buildSelect(V4S8, VCond, Val0, Val1);
3532 
3533   B.setInsertPt(*EntryMBB, VSelect->getIterator());
3534   EXPECT_EQ(LegalizerHelper::LegalizeResult::UnableToLegalize,
3535             Helper.bitcast(*VSelect, 0, S32));
3536   EXPECT_EQ(LegalizerHelper::LegalizeResult::UnableToLegalize,
3537             Helper.bitcast(*VSelect, 1, LLT::scalar(4)));
3538 }
3539 
3540 TEST_F(AArch64GISelMITest, BitcastBitOps) {
3541   setUp();
3542   if (!TM)
3543     return;
3544 
3545   LLT S32 = LLT::scalar(32);
3546   LLT V4S8 = LLT::fixed_vector(4, 8);
3547 
3548   DefineLegalizerInfo(A, {});
3549 
3550   auto Val0 = B.buildConstant(V4S8, 123);
3551   auto Val1 = B.buildConstant(V4S8, 99);
3552   auto And = B.buildAnd(V4S8, Val0, Val1);
3553   auto Or = B.buildOr(V4S8, Val0, Val1);
3554   auto Xor = B.buildXor(V4S8, Val0, Val1);
3555 
3556   AInfo Info(MF->getSubtarget());
3557   DummyGISelObserver Observer;
3558   LegalizerHelper Helper(*MF, Info, Observer, B);
3559   B.setInsertPt(*EntryMBB, And->getIterator());
3560   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3561             Helper.bitcast(*And, 0, S32));
3562 
3563   B.setInsertPt(*EntryMBB, Or->getIterator());
3564   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3565             Helper.bitcast(*Or, 0, S32));
3566 
3567   B.setInsertPt(*EntryMBB, Xor->getIterator());
3568   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3569             Helper.bitcast(*Xor, 0, S32));
3570 
3571   auto CheckStr = R"(
3572   CHECK: [[VAL0:%[0-9]+]]:_(<4 x s8>) = G_BUILD_VECTOR
3573   CHECK: [[VAL1:%[0-9]+]]:_(<4 x s8>) = G_BUILD_VECTOR
3574   CHECK: [[CAST0:%[0-9]+]]:_(s32) = G_BITCAST [[VAL0]]
3575   CHECK: [[CAST1:%[0-9]+]]:_(s32) = G_BITCAST [[VAL1]]
3576   CHECK: [[AND:%[0-9]+]]:_(s32) = G_AND [[CAST0]]:_, [[CAST1]]:_
3577   CHECK: [[CAST_AND:%[0-9]+]]:_(<4 x s8>) = G_BITCAST [[AND]]
3578   CHECK: [[CAST2:%[0-9]+]]:_(s32) = G_BITCAST [[VAL0]]
3579   CHECK: [[CAST3:%[0-9]+]]:_(s32) = G_BITCAST [[VAL1]]
3580   CHECK: [[OR:%[0-9]+]]:_(s32) = G_OR [[CAST2]]:_, [[CAST3]]:_
3581   CHECK: [[CAST_OR:%[0-9]+]]:_(<4 x s8>) = G_BITCAST [[OR]]
3582   CHECK: [[CAST4:%[0-9]+]]:_(s32) = G_BITCAST [[VAL0]]
3583   CHECK: [[CAST5:%[0-9]+]]:_(s32) = G_BITCAST [[VAL1]]
3584   CHECK: [[XOR:%[0-9]+]]:_(s32) = G_XOR [[CAST4]]:_, [[CAST5]]:_
3585   CHECK: [[CAST_XOR:%[0-9]+]]:_(<4 x s8>) = G_BITCAST [[XOR]]
3586   )";
3587 
3588   // Check
3589   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3590 }
3591 
3592 TEST_F(AArch64GISelMITest, CreateLibcall) {
3593   setUp();
3594   if (!TM)
3595     return;
3596 
3597   DefineLegalizerInfo(A, {});
3598 
3599   AInfo Info(MF->getSubtarget());
3600   DummyGISelObserver Observer;
3601 
3602   LLVMContext &Ctx = MF->getFunction().getContext();
3603   auto *RetTy = Type::getVoidTy(Ctx);
3604 
3605   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3606             createLibcall(B, "abort", {{}, RetTy, 0}, {}, CallingConv::C));
3607 
3608   auto CheckStr = R"(
3609   CHECK: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
3610   CHECK: BL &abort
3611   CHECK: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
3612   )";
3613 
3614   // Check
3615   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3616 }
3617 
3618 // Test narrowing of G_IMPLICIT_DEF
3619 TEST_F(AArch64GISelMITest, NarrowImplicitDef) {
3620   setUp();
3621   if (!TM)
3622     return;
3623 
3624   DefineLegalizerInfo(A, {});
3625 
3626   // Make sure that G_IMPLICIT_DEF can be narrowed if the original size is not a
3627   // multiple of narrow size
3628   LLT S32{LLT::scalar(32)};
3629   LLT S48{LLT::scalar(48)};
3630   LLT S64{LLT::scalar(64)};
3631   LLT V2S64{{LLT::fixed_vector(2, 64)}};
3632 
3633   auto Implicit1 = B.buildUndef(S64);
3634   auto Implicit2 = B.buildUndef(S64);
3635   auto Implicit3 = B.buildUndef(V2S64);
3636   auto Implicit4 = B.buildUndef(V2S64);
3637 
3638   AInfo Info(MF->getSubtarget());
3639   DummyGISelObserver Observer;
3640   LegalizerHelper Helper(*MF, Info, Observer, B);
3641 
3642   // Perform Legalization
3643 
3644   B.setInsertPt(*EntryMBB, Implicit1->getIterator());
3645   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3646             Helper.narrowScalar(*Implicit1, 0, S48));
3647 
3648   B.setInsertPt(*EntryMBB, Implicit2->getIterator());
3649   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3650             Helper.narrowScalar(*Implicit2, 0, S32));
3651 
3652   B.setInsertPt(*EntryMBB, Implicit3->getIterator());
3653   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3654             Helper.narrowScalar(*Implicit3, 0, S48));
3655 
3656   B.setInsertPt(*EntryMBB, Implicit4->getIterator());
3657   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3658             Helper.narrowScalar(*Implicit4, 0, S32));
3659 
3660   const auto *CheckStr = R"(
3661   CHECK: [[DEF:%[0-9]+]]:_(s48) = G_IMPLICIT_DEF
3662   CHECK: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[DEF]]
3663 
3664   CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
3665   CHECK: [[DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
3666   CHECK: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[DEF]]:_(s32), [[DEF1]]
3667 
3668   CHECK: [[DEF:%[0-9]+]]:_(<2 x s48>) = G_IMPLICIT_DEF
3669   CHECK: [[ANYEXT:%[0-9]+]]:_(<2 x s64>) = G_ANYEXT [[DEF]]
3670 
3671   CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
3672   CHECK: [[DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
3673   CHECK: [[DEF2:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
3674   CHECK: [[DEF3:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
3675   CHECK: [[BV:%[0-9]+]]:_(<2 x s64>) = G_BUILD_VECTOR [[DEF]]:_(s32), [[DEF1]]:_(s32), [[DEF2]]:_(s32), [[DEF3]]:_(s32)
3676   )";
3677 
3678   // Check
3679   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3680 }
3681 
3682 // Test widening of G_FREEZE
3683 TEST_F(AArch64GISelMITest, WidenFreeze) {
3684   setUp();
3685   if (!TM)
3686     return;
3687 
3688   DefineLegalizerInfo(A, {});
3689 
3690   // Make sure that G_FREEZE is widened with anyext
3691   LLT S64{LLT::scalar(64)};
3692   LLT S128{LLT::scalar(128)};
3693   LLT V2S32{LLT::fixed_vector(2, 32)};
3694   LLT V2S64{LLT::fixed_vector(2, 64)};
3695 
3696   auto Vector = B.buildBitcast(V2S32, Copies[0]);
3697 
3698   auto FreezeScalar = B.buildInstr(TargetOpcode::G_FREEZE, {S64}, {Copies[0]});
3699   auto FreezeVector = B.buildInstr(TargetOpcode::G_FREEZE, {V2S32}, {Vector});
3700 
3701   AInfo Info(MF->getSubtarget());
3702   DummyGISelObserver Observer;
3703   LegalizerHelper Helper(*MF, Info, Observer, B);
3704 
3705   // Perform Legalization
3706 
3707   B.setInsertPt(*EntryMBB, FreezeScalar->getIterator());
3708   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3709             Helper.widenScalar(*FreezeScalar, 0, S128));
3710 
3711   B.setInsertPt(*EntryMBB, FreezeVector->getIterator());
3712   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3713             Helper.widenScalar(*FreezeVector, 0, V2S64));
3714 
3715   const auto *CheckStr = R"(
3716   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
3717   CHECK: [[BITCAST:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[COPY]]
3718 
3719   CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT [[COPY]]
3720   CHECK: [[FREEZE:%[0-9]+]]:_(s128) = G_FREEZE [[ANYEXT]]
3721   CHECK: [[TRUNC:%[0-9]+]]:_(s64) = G_TRUNC [[FREEZE]]
3722 
3723   CHECK: [[ANYEXT1:%[0-9]+]]:_(<2 x s64>) = G_ANYEXT [[BITCAST]]
3724   CHECK: [[FREEZE1:%[0-9]+]]:_(<2 x s64>) = G_FREEZE [[ANYEXT1]]
3725   CHECK: [[TRUNC1:%[0-9]+]]:_(<2 x s32>) = G_TRUNC [[FREEZE1]]
3726   )";
3727 
3728   // Check
3729   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3730 }
3731 
3732 // Test narrowing of G_FREEZE
3733 TEST_F(AArch64GISelMITest, NarrowFreeze) {
3734   setUp();
3735   if (!TM)
3736     return;
3737 
3738   DefineLegalizerInfo(A, {});
3739 
3740   // Make sure that G_FREEZE is narrowed using unmerge/extract
3741   LLT S32{LLT::scalar(32)};
3742   LLT S33{LLT::scalar(33)};
3743   LLT S48{LLT::scalar(48)};
3744   LLT S64{LLT::scalar(64)};
3745   LLT V2S16{LLT::fixed_vector(2, 16)};
3746   LLT V3S16{LLT::fixed_vector(3, 16)};
3747   LLT V4S16{LLT::fixed_vector(4, 16)};
3748 
3749   auto Trunc = B.buildTrunc(S33, {Copies[0]});
3750   auto Trunc1 = B.buildTrunc(S48, {Copies[0]});
3751   auto Vector = B.buildBitcast(V3S16, Trunc1);
3752 
3753   auto FreezeScalar = B.buildInstr(TargetOpcode::G_FREEZE, {S64}, {Copies[0]});
3754   auto FreezeOdd = B.buildInstr(TargetOpcode::G_FREEZE, {S33}, {Trunc});
3755   auto FreezeVector = B.buildInstr(TargetOpcode::G_FREEZE, {V3S16}, {Vector});
3756   auto FreezeVector1 = B.buildInstr(TargetOpcode::G_FREEZE, {V3S16}, {Vector});
3757 
3758   AInfo Info(MF->getSubtarget());
3759   DummyGISelObserver Observer;
3760   LegalizerHelper Helper(*MF, Info, Observer, B);
3761 
3762   // Perform Legalization
3763 
3764   B.setInsertPt(*EntryMBB, FreezeScalar->getIterator());
3765   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3766             Helper.narrowScalar(*FreezeScalar, 0, S32));
3767 
3768   // This should be followed by narrowScalar to S32.
3769   B.setInsertPt(*EntryMBB, FreezeOdd->getIterator());
3770   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3771             Helper.widenScalar(*FreezeOdd, 0, S64));
3772 
3773   B.setInsertPt(*EntryMBB, FreezeVector->getIterator());
3774   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3775             Helper.fewerElementsVector(*FreezeVector, 0, V2S16));
3776 
3777   // This should be followed by fewerElements to V2S16.
3778   B.setInsertPt(*EntryMBB, FreezeVector1->getIterator());
3779   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3780             Helper.moreElementsVector(*FreezeVector1, 0, V4S16));
3781 
3782   const auto *CheckStr = R"(
3783   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
3784   CHECK: [[TRUNC:%[0-9]+]]:_(s33) = G_TRUNC [[COPY]]
3785   CHECK: [[TRUNC1:%[0-9]+]]:_(s48) = G_TRUNC [[COPY]]
3786   CHECK: [[BITCAST:%[0-9]+]]:_(<3 x s16>) = G_BITCAST [[TRUNC1]]
3787 
3788   CHECK: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[COPY]]
3789   CHECK: [[FREEZE:%[0-9]+]]:_(s32) = G_FREEZE [[UV]]
3790   CHECK: [[FREEZE1:%[0-9]+]]:_(s32) = G_FREEZE [[UV1]]
3791   CHECK: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[FREEZE]]:_(s32), [[FREEZE1]]
3792 
3793   CHECK: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[TRUNC]]
3794   CHECK: [[FREEZE2:%[0-9]+]]:_(s64) = G_FREEZE [[ANYEXT]]
3795   CHECK: [[TRUNC1:%[0-9]+]]:_(s33) = G_TRUNC [[FREEZE2]]
3796 
3797   CHECK: [[UV2:%[0-9]+]]:_(s16), [[UV3:%[0-9]+]]:_(s16), [[UV4:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[BITCAST]]
3798   CHECK: [[BV:%[0-9]+]]:_(<2 x s16>) = G_BUILD_VECTOR [[UV2]]:_(s16), [[UV3]]:_(s16)
3799   CHECK: [[FREEZE3:%[0-9]+]]:_(<2 x s16>) = G_FREEZE [[BV]]
3800   CHECK: [[FREEZE4:%[0-9]+]]:_(s16) = G_FREEZE [[UV4]]
3801   CHECK: [[FREEZE3_E0:%[0-9]+]]:_(s16), [[FREEZE3_E1:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[FREEZE3]]
3802   CHECK: [[BV1:%[0-9]+]]:_(<3 x s16>) = G_BUILD_VECTOR [[FREEZE3_E0]]:_(s16), [[FREEZE3_E1]]:_(s16), [[FREEZE4]]:_(s16)
3803 
3804   CHECK: [[UV5:%[0-9]+]]:_(s16), [[UV6:%[0-9]+]]:_(s16), [[UV7:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[BITCAST]]
3805   CHECK: [[IMP_DEF:%[0-9]+]]:_(s16) = G_IMPLICIT_DEF
3806   CHECK: [[BV1:%[0-9]+]]:_(<4 x s16>) = G_BUILD_VECTOR [[UV5]]:_(s16), [[UV6]]:_(s16), [[UV7]]:_(s16), [[IMP_DEF]]:_(s16)
3807   CHECK: [[FREEZE5:%[0-9]+]]:_(<4 x s16>) = G_FREEZE [[BV1]]
3808   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]]
3809   CHECK: [[BV2:%[0-9]+]]:_(<3 x s16>) = G_BUILD_VECTOR [[FREEZE5_E0]]:_(s16), [[FREEZE5_E1]]:_(s16), [[FREEZE5_E2]]:_(s16)
3810   )";
3811 
3812   // Check
3813   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3814 }
3815 
3816 // Test fewer elements of G_FREEZE
3817 TEST_F(AArch64GISelMITest, FewerElementsFreeze) {
3818   setUp();
3819   if (!TM)
3820     return;
3821 
3822   DefineLegalizerInfo(A, {});
3823 
3824   LLT S32{LLT::scalar(32)};
3825   LLT V2S16{LLT::fixed_vector(2, 16)};
3826   LLT V2S32{LLT::fixed_vector(2, 32)};
3827   LLT V4S16{LLT::fixed_vector(4, 16)};
3828 
3829   auto Vector1 = B.buildBitcast(V2S32, Copies[0]);
3830   auto Vector2 = B.buildBitcast(V4S16, Copies[0]);
3831 
3832   auto FreezeVector1 = B.buildInstr(TargetOpcode::G_FREEZE, {V2S32}, {Vector1});
3833   auto FreezeVector2 = B.buildInstr(TargetOpcode::G_FREEZE, {V4S16}, {Vector2});
3834 
3835   AInfo Info(MF->getSubtarget());
3836   DummyGISelObserver Observer;
3837   LegalizerHelper Helper(*MF, Info, Observer, B);
3838 
3839   // Perform Legalization
3840 
3841   B.setInsertPt(*EntryMBB, FreezeVector1->getIterator());
3842   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3843             Helper.fewerElementsVector(*FreezeVector1, 0, S32));
3844 
3845   B.setInsertPt(*EntryMBB, FreezeVector2->getIterator());
3846   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3847             Helper.fewerElementsVector(*FreezeVector2, 0, V2S16));
3848 
3849   const auto *CheckStr = R"(
3850   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
3851   CHECK: [[BITCAST:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[COPY]]
3852   CHECK: [[BITCAST1:%[0-9]+]]:_(<4 x s16>) = G_BITCAST [[COPY]]
3853 
3854   CHECK: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[BITCAST]]
3855   CHECK: [[FREEZE:%[0-9]+]]:_(s32) = G_FREEZE [[UV]]
3856   CHECK: [[FREEZE1:%[0-9]+]]:_(s32) = G_FREEZE [[UV1]]
3857   CHECK: [[MV:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[FREEZE]]:_(s32), [[FREEZE1]]
3858 
3859   CHECK: [[UV:%[0-9]+]]:_(<2 x s16>), [[UV1:%[0-9]+]]:_(<2 x s16>) = G_UNMERGE_VALUES [[BITCAST1]]
3860   CHECK: [[FREEZE2:%[0-9]+]]:_(<2 x s16>) = G_FREEZE [[UV]]
3861   CHECK: [[FREEZE3:%[0-9]+]]:_(<2 x s16>) = G_FREEZE [[UV1]]
3862   CHECK: [[MV:%[0-9]+]]:_(<4 x s16>) = G_CONCAT_VECTORS [[FREEZE2]]:_(<2 x s16>), [[FREEZE3]]
3863   )";
3864 
3865   // Check
3866   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3867 }
3868 
3869 // Test more elements of G_FREEZE
3870 TEST_F(AArch64GISelMITest, MoreElementsFreeze) {
3871   setUp();
3872   if (!TM)
3873     return;
3874 
3875   DefineLegalizerInfo(A, {});
3876 
3877   LLT V2S32{LLT::fixed_vector(2, 32)};
3878   LLT V4S32{LLT::fixed_vector(4, 32)};
3879 
3880   auto Vector1 = B.buildBitcast(V2S32, Copies[0]);
3881   auto FreezeVector1 = B.buildInstr(TargetOpcode::G_FREEZE, {V2S32}, {Vector1});
3882 
3883   AInfo Info(MF->getSubtarget());
3884   DummyGISelObserver Observer;
3885   LegalizerHelper Helper(*MF, Info, Observer, B);
3886 
3887   // Perform Legalization
3888   B.setInsertPt(*EntryMBB, FreezeVector1->getIterator());
3889   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3890             Helper.moreElementsVector(*FreezeVector1, 0, V4S32));
3891 
3892   const auto *CheckStr = R"(
3893   CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
3894   CHECK: [[BITCAST:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[COPY]]
3895   CHECK: [[BITCAST_E0:%[0-9]+]]:_(s32), [[BITCAST_E1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[BITCAST]]:_(<2 x s32>)
3896   CHECK: [[IMP_DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
3897   CHECK: [[BITCAST_LARGE:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[BITCAST_E0]]:_(s32), [[BITCAST_E1]]:_(s32), [[IMP_DEF]]:_(s32), [[IMP_DEF]]:_(s32)
3898   CHECK: [[FREEZE:%[0-9]+]]:_(<4 x s32>) = G_FREEZE [[BITCAST_LARGE]]
3899   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>)
3900   CHECK: (<2 x s32>) = G_BUILD_VECTOR [[FREEZE_E0]]:_(s32), [[FREEZE_E1]]:_(s32)
3901   )";
3902 
3903   // Check
3904   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3905 }
3906 
3907 // Test fewer elements of G_INSERT_VECTOR_ELEMENT
3908 TEST_F(AArch64GISelMITest, FewerElementsInsertVectorElt) {
3909   setUp();
3910   if (!TM)
3911     return;
3912 
3913   DefineLegalizerInfo(A, {});
3914 
3915   LLT P0{LLT::pointer(0, 64)};
3916   LLT S64{LLT::scalar(64)};
3917   LLT S16{LLT::scalar(16)};
3918   LLT V2S16{LLT::fixed_vector(2, 16)};
3919   LLT V3S16{LLT::fixed_vector(3, 16)};
3920   LLT V8S16{LLT::fixed_vector(8, 16)};
3921 
3922   auto Ptr0 = B.buildIntToPtr(P0, Copies[0]);
3923   auto VectorV8 = B.buildLoad(V8S16, Ptr0, MachinePointerInfo(), Align(8));
3924   auto Value = B.buildTrunc(S16, Copies[1]);
3925 
3926   auto Seven = B.buildConstant(S64, 7);
3927   auto InsertV8Constant7_0 =
3928       B.buildInsertVectorElement(V8S16, VectorV8, Value, Seven);
3929   auto InsertV8Constant7_1 =
3930       B.buildInsertVectorElement(V8S16, VectorV8, Value, Seven);
3931 
3932   B.buildStore(InsertV8Constant7_0, Ptr0, MachinePointerInfo(), Align(8),
3933                MachineMemOperand::MOVolatile);
3934   B.buildStore(InsertV8Constant7_1, Ptr0, MachinePointerInfo(), Align(8),
3935                MachineMemOperand::MOVolatile);
3936 
3937   AInfo Info(MF->getSubtarget());
3938   DummyGISelObserver Observer;
3939   LegalizerHelper Helper(*MF, Info, Observer, B);
3940 
3941   // Perform Legalization
3942   B.setInsertPt(*EntryMBB, InsertV8Constant7_0->getIterator());
3943 
3944   // This should index the high element of the 4th piece of an unmerge.
3945   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3946             Helper.fewerElementsVector(*InsertV8Constant7_0, 0, V2S16));
3947 
3948   // This case requires extracting an intermediate vector type into the target
3949   // v4s16.
3950   B.setInsertPt(*EntryMBB, InsertV8Constant7_1->getIterator());
3951   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3952             Helper.fewerElementsVector(*InsertV8Constant7_1, 0, V3S16));
3953 
3954   const auto *CheckStr = R"(
3955   CHECK: [[COPY0:%[0-9]+]]:_(s64) = COPY
3956   CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY
3957   CHECK: [[COPY2:%[0-9]+]]:_(s64) = COPY
3958   CHECK: [[PTR0:%[0-9]+]]:_(p0) = G_INTTOPTR [[COPY0]]
3959   CHECK: [[VEC8:%[0-9]+]]:_(<8 x s16>) = G_LOAD [[PTR0]]:_(p0) :: (load (<8 x s16>), align 8)
3960   CHECK: [[INSERT_VAL:%[0-9]+]]:_(s16) = G_TRUNC [[COPY1]]
3961 
3962 
3963   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]]
3964   CHECK: [[ONE:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
3965   CHECK: [[SUB_INSERT_7:%[0-9]+]]:_(<2 x s16>) = G_INSERT_VECTOR_ELT [[UNMERGE3]]:_, [[INSERT_VAL]]:_(s16), [[ONE]]
3966   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>)
3967 
3968 
3969   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>)
3970   CHECK: [[IMPDEF_S16:%[0-9]+]]:_(s16) = G_IMPLICIT_DEF
3971   CHECK: [[BUILD0:%[0-9]+]]:_(<3 x s16>) = G_BUILD_VECTOR [[UNMERGE1_0]]:_(s16), [[UNMERGE1_1]]:_(s16), [[UNMERGE1_2]]:_(s16)
3972   CHECK: [[BUILD1:%[0-9]+]]:_(<3 x s16>) = G_BUILD_VECTOR [[UNMERGE1_3]]:_(s16), [[UNMERGE1_4]]:_(s16), [[UNMERGE1_5]]:_(s16)
3973   CHECK: [[BUILD2:%[0-9]+]]:_(<3 x s16>) = G_BUILD_VECTOR [[UNMERGE1_6]]:_(s16), [[UNMERGE1_7]]:_(s16), [[IMPDEF_S16]]:_(s16)
3974   CHECK: [[IMPDEF_V3S16:%[0-9]+]]:_(<3 x s16>) = G_IMPLICIT_DEF
3975   CHECK: [[ONE_1:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
3976   CHECK: [[SUB_INSERT_7_V3S16:%[0-9]+]]:_(<3 x s16>) = G_INSERT_VECTOR_ELT [[BUILD2]]:_, [[INSERT_VAL]]:_(s16), [[ONE_1]]
3977 
3978   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>)
3979   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>)
3980   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>)
3981 
3982 
3983   CHECK: G_STORE [[INSERT_V8_7_0]]
3984   CHECK: G_STORE [[INSERT_V8_7_1]]
3985   )";
3986 
3987   // Check
3988   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3989 }
3990 
3991 // Test widen scalar of G_UNMERGE_VALUES
3992 TEST_F(AArch64GISelMITest, widenScalarUnmerge) {
3993   setUp();
3994   if (!TM)
3995     return;
3996 
3997   DefineLegalizerInfo(A, {});
3998 
3999   LLT S96{LLT::scalar(96)};
4000   LLT S64{LLT::scalar(64)};
4001   LLT S48{LLT::scalar(48)};
4002 
4003   auto Src = B.buildAnyExt(S96, Copies[0]);
4004   auto Unmerge = B.buildUnmerge(S48, Src);
4005 
4006   AInfo Info(MF->getSubtarget());
4007   DummyGISelObserver Observer;
4008   LegalizerHelper Helper(*MF, Info, Observer, B);
4009 
4010   // Perform Legalization
4011   B.setInsertPt(*EntryMBB, Unmerge->getIterator());
4012 
4013   // This should create unmerges to a GCD type (S16), then remerge to S48
4014   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
4015             Helper.widenScalar(*Unmerge, 0, S64));
4016 
4017   const auto *CheckStr = R"(
4018   CHECK: [[COPY0:%[0-9]+]]:_(s64) = COPY
4019   CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY
4020   CHECK: [[COPY2:%[0-9]+]]:_(s64) = COPY
4021   CHECK: [[ANYEXT:%[0-9]+]]:_(s96) = G_ANYEXT [[COPY0]]
4022   CHECK: [[ANYEXT1:%[0-9]+]]:_(s192) = G_ANYEXT [[ANYEXT]]
4023   CHECK: [[UNMERGE:%[0-9]+]]:_(s64), [[UNMERGE1:%[0-9]+]]:_(s64), [[UNMERGE2:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[ANYEXT1]]
4024   CHECK: [[UNMERGE3:%[0-9]+]]:_(s16), [[UNMERGE4:%[0-9]+]]:_(s16), [[UNMERGE5:%[0-9]+]]:_(s16), [[UNMERGE6:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[UNMERGE]]
4025   CHECK: [[UNMERGE7:%[0-9]+]]:_(s16), [[UNMERGE8:%[0-9]+]]:_(s16), [[UNMERGE9:%[0-9]+]]:_(s16), [[UNMERGE10:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[UNMERGE1]]
4026   CHECK: [[UNMERGE11:%[0-9]+]]:_(s16), [[UNMERGE12:%[0-9]+]]:_(s16), [[UNMERGE13:%[0-9]+]]:_(s16), [[UNMERGE14:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[UNMERGE2]]
4027   CHECK: [[MERGE:%[0-9]+]]:_(s48) = G_MERGE_VALUES [[UNMERGE3]]:_(s16), [[UNMERGE4]]:_(s16), [[UNMERGE5]]:_(s16)
4028   CHECK: [[MERGE1:%[0-9]+]]:_(s48) = G_MERGE_VALUES [[UNMERGE6]]:_(s16), [[UNMERGE7]]:_(s16), [[UNMERGE8]]:_(s16)
4029   )";
4030 
4031   // Check
4032   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
4033 }
4034 
4035 // Test moreElements of G_SHUFFLE_VECTOR.
4036 TEST_F(AArch64GISelMITest, moreElementsShuffle) {
4037   setUp();
4038   if (!TM)
4039     return;
4040 
4041   DefineLegalizerInfo(A, {});
4042 
4043   LLT S64{LLT::scalar(64)};
4044   LLT V6S64 = LLT::fixed_vector(6, S64);
4045 
4046   auto V1 = B.buildBuildVector(V6S64, {Copies[0], Copies[1], Copies[0],
4047                                        Copies[1], Copies[0], Copies[1]});
4048   auto V2 = B.buildBuildVector(V6S64, {Copies[0], Copies[1], Copies[0],
4049                                        Copies[1], Copies[0], Copies[1]});
4050   auto Shuffle = B.buildShuffleVector(V6S64, V1, V2, {3, 4, 7, 0, 1, 11});
4051 
4052   AInfo Info(MF->getSubtarget());
4053   DummyGISelObserver Observer;
4054   LegalizerHelper Helper(*MF, Info, Observer, B);
4055 
4056   // Perform Legalization
4057   B.setInsertPt(*EntryMBB, Shuffle->getIterator());
4058 
4059   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
4060             Helper.moreElementsVector(*Shuffle, 0, LLT::fixed_vector(8, S64)));
4061 
4062   const auto *CheckStr = R"(
4063   CHECK: [[COPY0:%[0-9]+]]:_(s64) = COPY
4064   CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY
4065   CHECK: [[COPY2:%[0-9]+]]:_(s64) = COPY
4066   CHECK: [[BV1:%[0-9]+]]:_(<6 x s64>) = G_BUILD_VECTOR
4067   CHECK: [[BV2:%[0-9]+]]:_(<6 x s64>) = G_BUILD_VECTOR
4068 
4069   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>)
4070   CHECK: [[IMP_DEF0:%[0-9]+]]:_(s64) = G_IMPLICIT_DEF
4071   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)
4072 
4073   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>)
4074   CHECK: [[IMP_DEF1:%[0-9]+]]:_(s64) = G_IMPLICIT_DEF
4075   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)
4076 
4077   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)
4078 
4079   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>)
4080   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)
4081   )";
4082 
4083   // Check
4084   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
4085 }
4086 
4087 // Test narror scalar of G_SHL with constant shift amount
4088 TEST_F(AArch64GISelMITest, narrowScalarShiftByConstant) {
4089   setUp();
4090   if (!TM)
4091     return;
4092 
4093   DefineLegalizerInfo(A, {});
4094 
4095   LLT S64{LLT::scalar(64)};
4096   LLT S32{LLT::scalar(32)};
4097 
4098   auto Constant = B.buildConstant(S64, 33);
4099   auto Trunc = B.buildTrunc(S32, Constant);
4100   auto Shift = B.buildShl(S64, Copies[0], Trunc);
4101 
4102   AInfo Info(MF->getSubtarget());
4103   DummyGISelObserver Observer;
4104   LegalizerHelper Helper(*MF, Info, Observer, B);
4105 
4106   // Perform Legalization
4107   B.setInsertPt(*EntryMBB, Shift->getIterator());
4108 
4109   // This should detect the G_CONSTANT feeding the G_SHL through a G_TRUNC
4110   EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
4111             Helper.narrowScalarShift(*Shift, 0, S32));
4112 
4113   const auto *CheckStr = R"(
4114   CHECK: [[COPY0:%[0-9]+]]:_(s64) = COPY
4115   CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY
4116   CHECK: [[COPY2:%[0-9]+]]:_(s64) = COPY
4117   CHECK: [[THIRTY3:%[0-9]+]]:_(s64) = G_CONSTANT i64 33
4118   CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC %4:_(s64)
4119   CHECK: [[UNMERGE:%[0-9]+]]:_(s32), [[UNMERGE2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[COPY0]]
4120   CHECK: [[ZERO:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
4121   CHECK: [[ONE:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
4122   CHECK: [[SHIFT:%[0-9]+]]:_(s32) = G_SHL [[UNMERGE]]:_, [[ONE]]:_(s32)
4123   CHECK: [[MERGE:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[ZERO]]:_(s32), [[SHIFT]]:_(s32)
4124   )";
4125 
4126   // Check
4127   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
4128 }
4129 
4130 } // namespace
4131