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