1 //===- LegalizerHelperTest.cpp
2 //-----------------------------------------------===//
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
8 //===----------------------------------------------------------------------===//
10 #include "GISelMITest.h"
11 #include "llvm/CodeGen/GlobalISel/LostDebugLocObserver.h"
13 using namespace LegalizeActions
;
14 using namespace LegalizeMutations
;
15 using namespace LegalityPredicates
;
19 class DummyGISelObserver
: public GISelChangeObserver
{
21 void changingInstr(MachineInstr
&MI
) override
{}
22 void changedInstr(MachineInstr
&MI
) override
{}
23 void createdInstr(MachineInstr
&MI
) override
{}
24 void erasingInstr(MachineInstr
&MI
) override
{}
27 // Test G_ROTL/G_ROTR lowering.
28 TEST_F(AArch64GISelMITest
, LowerRotates
) {
33 // Declare your legalization info
34 DefineLegalizerInfo(A
, {
35 getActionDefinitionsBuilder({G_ROTR
, G_ROTL
}).lower(); });
37 LLT S32
= LLT::scalar(32);
38 auto Src
= B
.buildTrunc(S32
, Copies
[0]);
39 auto Amt
= B
.buildTrunc(S32
, Copies
[1]);
40 auto ROTR
= B
.buildInstr(TargetOpcode::G_ROTR
, {S32
}, {Src
, Amt
});
41 auto ROTL
= B
.buildInstr(TargetOpcode::G_ROTL
, {S32
}, {Src
, Amt
});
43 AInfo
Info(MF
->getSubtarget());
44 DummyGISelObserver Observer
;
45 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
46 // Perform Legalization
47 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
48 Helper
.lower(*ROTR
, 0, S32
));
49 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
50 Helper
.lower(*ROTL
, 0, S32
));
54 CHECK: [[SRC:%[0-9]+]]:_(s32) = G_TRUNC
55 CHECK: [[AMT:%[0-9]+]]:_(s32) = G_TRUNC
56 CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
57 CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 31
58 CHECK: [[SUB:%[0-9]+]]:_(s32) = G_SUB [[C]]:_, [[AMT]]:_
59 CHECK: [[AND:%[0-9]+]]:_(s32) = G_AND [[AMT]]:_, [[C1]]:_
60 CHECK: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[SRC]]:_, [[AND]]:_(s32)
61 CHECK: [[AND1:%[0-9]+]]:_(s32) = G_AND [[SUB]]:_, [[C1]]:_
62 CHECK: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[SRC]]:_, [[AND1]]:_(s32)
63 CHECK: G_OR [[LSHR]]:_, [[SHL]]:_
66 CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
67 CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 31
68 CHECK: [[SUB:%[0-9]+]]:_(s32) = G_SUB [[C]]:_, [[AMT]]:_
69 CHECK: [[AND:%[0-9]+]]:_(s32) = G_AND [[AMT]]:_, [[C1]]:_
70 CHECK: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[SRC]]:_, [[AND]]:_(s32)
71 CHECK: [[AND1:%[0-9]+]]:_(s32) = G_AND [[SUB]]:_, [[C1]]:_
72 CHECK: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[SRC]]:_, [[AND1]]:_(s32)
73 CHECK: G_OR [[SHL]]:_, [[LSHR]]:_
77 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
80 // Test G_ROTL/G_ROTR non-pow2 lowering.
81 TEST_F(AArch64GISelMITest
, LowerRotatesNonPow2
) {
86 // Declare your legalization info
87 DefineLegalizerInfo(A
, {
88 getActionDefinitionsBuilder({G_ROTR
, G_ROTL
}).lower(); });
90 LLT S24
= LLT::scalar(24);
91 auto Src
= B
.buildTrunc(S24
, Copies
[0]);
92 auto Amt
= B
.buildTrunc(S24
, Copies
[1]);
93 auto ROTR
= B
.buildInstr(TargetOpcode::G_ROTR
, {S24
}, {Src
, Amt
});
94 auto ROTL
= B
.buildInstr(TargetOpcode::G_ROTL
, {S24
}, {Src
, Amt
});
96 AInfo
Info(MF
->getSubtarget());
97 DummyGISelObserver Observer
;
98 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
99 // Perform Legalization
100 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
101 Helper
.lower(*ROTR
, 0, S24
));
102 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
103 Helper
.lower(*ROTL
, 0, S24
));
107 CHECK: [[SRC:%[0-9]+]]:_(s24) = G_TRUNC
108 CHECK: [[AMT:%[0-9]+]]:_(s24) = G_TRUNC
109 CHECK: [[C:%[0-9]+]]:_(s24) = G_CONSTANT i24 0
110 CHECK: [[C1:%[0-9]+]]:_(s24) = G_CONSTANT i24 23
111 CHECK: [[C2:%[0-9]+]]:_(s24) = G_CONSTANT i24 24
112 CHECK: [[UREM:%[0-9]+]]:_(s24) = G_UREM [[AMT]]:_, [[C2]]:_
113 CHECK: [[LSHR:%[0-9]+]]:_(s24) = G_LSHR [[SRC]]:_, [[UREM]]:_(s24)
114 CHECK: [[SUB:%[0-9]+]]:_(s24) = G_SUB [[C1]]:_, [[UREM]]:_
115 CHECK: [[C4:%[0-9]+]]:_(s24) = G_CONSTANT i24 1
116 CHECK: [[SHL:%[0-9]+]]:_(s24) = G_SHL [[SRC]]:_, [[C4]]:_(s24)
117 CHECK: [[SHL2:%[0-9]+]]:_(s24) = G_SHL [[SHL]]:_, [[SUB]]:_(s24)
118 CHECK: G_OR [[LSHR]]:_, [[SHL2]]:_
121 CHECK: [[C:%[0-9]+]]:_(s24) = G_CONSTANT i24 0
122 CHECK: [[C1:%[0-9]+]]:_(s24) = G_CONSTANT i24 23
123 CHECK: [[C2:%[0-9]+]]:_(s24) = G_CONSTANT i24 24
124 CHECK: [[UREM:%[0-9]+]]:_(s24) = G_UREM [[AMT]]:_, [[C2]]:_
125 CHECK: [[SHL:%[0-9]+]]:_(s24) = G_SHL [[SRC]]:_, [[UREM]]:_(s24)
126 CHECK: [[SUB:%[0-9]+]]:_(s24) = G_SUB [[C1]]:_, [[UREM]]:_
127 CHECK: [[C4:%[0-9]+]]:_(s24) = G_CONSTANT i24 1
128 CHECK: [[LSHR:%[0-9]+]]:_(s24) = G_LSHR [[SRC]]:_, [[C4]]:_(s24)
129 CHECK: [[LSHR2:%[0-9]+]]:_(s24) = G_LSHR [[LSHR]]:_, [[SUB]]:_(s24)
130 CHECK: G_OR [[SHL]]:_, [[LSHR2]]:_
134 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
137 // Test vector G_ROTR lowering.
138 TEST_F(AArch64GISelMITest
, LowerRotatesVector
) {
143 // Declare your legalization info
144 DefineLegalizerInfo(A
, {
145 getActionDefinitionsBuilder({G_ROTR
, G_ROTL
}).lower(); });
147 LLT S32
= LLT::scalar(32);
148 LLT V4S32
= LLT::fixed_vector(4, S32
);
149 auto SrcTrunc
= B
.buildTrunc(S32
, Copies
[0]);
150 auto Src
= B
.buildSplatVector(V4S32
, SrcTrunc
);
151 auto AmtTrunc
= B
.buildTrunc(S32
, Copies
[1]);
152 auto Amt
= B
.buildSplatVector(V4S32
, AmtTrunc
);
153 auto ROTR
= B
.buildInstr(TargetOpcode::G_ROTR
, {V4S32
}, {Src
, Amt
});
155 AInfo
Info(MF
->getSubtarget());
156 DummyGISelObserver Observer
;
157 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
158 // Perform Legalization
159 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
160 Helper
.lower(*ROTR
, 0, V4S32
));
163 CHECK: [[SRCTRUNC:%[0-9]+]]:_(s32) = G_TRUNC
164 CHECK: [[SRC:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[SRCTRUNC]]
165 CHECK: [[AMTTRUNC:%[0-9]+]]:_(s32) = G_TRUNC
166 CHECK: [[AMT:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[AMTTRUNC]]
167 CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
168 CHECK: [[ZERO:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[C]]
169 CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 31
170 CHECK: [[VEC31:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[C1]]
171 CHECK: [[SUB:%[0-9]+]]:_(<4 x s32>) = G_SUB [[ZERO]]:_, [[AMT]]:_
172 CHECK: [[AND:%[0-9]+]]:_(<4 x s32>) = G_AND [[AMT]]:_, [[VEC31]]:_
173 CHECK: [[LSHR:%[0-9]+]]:_(<4 x s32>) = G_LSHR [[SRC]]:_, [[AND]]:_(<4 x s32>)
174 CHECK: [[AND1:%[0-9]+]]:_(<4 x s32>) = G_AND [[SUB]]:_, [[VEC31]]:_
175 CHECK: [[SHL:%[0-9]+]]:_(<4 x s32>) = G_SHL [[SRC]]:_, [[AND1]]:_(<4 x s32>)
176 CHECK: G_OR [[LSHR]]:_, [[SHL]]:_
180 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
183 // Test CTTZ expansion when CTTZ_ZERO_UNDEF is legal or custom,
184 // in which case it becomes CTTZ_ZERO_UNDEF with select.
185 TEST_F(AArch64GISelMITest
, LowerBitCountingCTTZ0
) {
190 // Declare your legalization info
191 DefineLegalizerInfo(A
, {
192 getActionDefinitionsBuilder(G_CTTZ_ZERO_UNDEF
).legalFor({{s32
, s64
}});
196 B
.buildInstr(TargetOpcode::G_CTTZ
, {LLT::scalar(32)}, {Copies
[0]});
197 AInfo
Info(MF
->getSubtarget());
198 DummyGISelObserver Observer
;
199 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
200 // Perform Legalization
201 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
202 Helper
.lower(*MIBCTTZ
, 0, LLT::scalar(64)));
205 CHECK: [[CZU:%[0-9]+]]:_(s32) = G_CTTZ_ZERO_UNDEF %0
206 CHECK: [[ZERO:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
207 CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), %0:_(s64), [[ZERO]]
208 CHECK: [[SIXTY4:%[0-9]+]]:_(s32) = G_CONSTANT i32 64
209 CHECK: [[SEL:%[0-9]+]]:_(s32) = G_SELECT [[CMP]]:_(s1), [[SIXTY4]]:_, [[CZU]]
213 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
216 // CTTZ expansion in terms of CTLZ
217 TEST_F(AArch64GISelMITest
, LowerBitCountingCTTZ1
) {
222 // Declare your legalization info
223 DefineLegalizerInfo(A
, {
224 getActionDefinitionsBuilder(G_CTLZ
).legalFor({{s64
, s64
}});
228 B
.buildInstr(TargetOpcode::G_CTTZ
, {LLT::scalar(64)}, {Copies
[0]});
229 AInfo
Info(MF
->getSubtarget());
230 DummyGISelObserver Observer
;
231 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
232 // Perform Legalization
233 EXPECT_TRUE(Helper
.lower(*MIBCTTZ
, 0, LLT::scalar(64)) ==
234 LegalizerHelper::LegalizeResult::Legalized
);
237 CHECK: [[NEG1:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1
238 CHECK: [[NOT:%[0-9]+]]:_(s64) = G_XOR %0:_, [[NEG1]]
239 CHECK: [[SUB1:%[0-9]+]]:_(s64) = G_ADD %0:_, [[NEG1]]
240 CHECK: [[AND1:%[0-9]+]]:_(s64) = G_AND [[NOT]]:_, [[SUB1]]:_
241 CHECK: [[CST64:%[0-9]+]]:_(s64) = G_CONSTANT i64 64
242 CHECK: [[CTLZ:%[0-9]+]]:_(s64) = G_CTLZ [[AND1]]:_
243 CHECK: G_SUB [[CST64]]:_, [[CTLZ]]:_
247 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
250 // CTLZ scalar narrowing
251 TEST_F(AArch64GISelMITest
, NarrowScalarCTLZ
) {
256 // Declare your legalization info
257 DefineLegalizerInfo(A
, {
258 getActionDefinitionsBuilder(G_CTLZ
).legalFor({{s32
, s32
}});
262 B
.buildInstr(TargetOpcode::G_CTLZ
, {LLT::scalar(32)}, {Copies
[0]});
263 AInfo
Info(MF
->getSubtarget());
264 DummyGISelObserver Observer
;
265 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
266 // Perform Legalization
267 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
268 Helper
.narrowScalar(*CTLZ
, 1, LLT::scalar(32)));
271 CHECK: [[UNMERGE_LO:%[0-9]+]]:_(s32), [[UNMERGE_HI:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES %0:_(s64)
272 CHECK: [[ZERO:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
273 CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[UNMERGE_HI]]:_(s32), [[ZERO]]:_
274 CHECK: [[CTLZ_LO:%[0-9]+]]:_(s32) = G_CTLZ [[UNMERGE_LO]]:_(s32)
275 CHECK: [[THIRTYTWO:%[0-9]+]]:_(s32) = G_CONSTANT i32 32
276 CHECK: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[CTLZ_LO]]:_, [[THIRTYTWO]]:_
277 CHECK: [[CTLZ_HI:%[0-9]+]]:_(s32) = G_CTLZ_ZERO_UNDEF [[UNMERGE_HI]]:_(s32)
278 CHECK: %{{[0-9]+}}:_(s32) = G_SELECT [[CMP]]:_(s1), [[ADD]]:_, [[CTLZ_HI]]:_
282 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
285 // CTTZ scalar narrowing
286 TEST_F(AArch64GISelMITest
, NarrowScalarCTTZ
) {
291 // Declare your legalization info
292 DefineLegalizerInfo(A
, {
293 getActionDefinitionsBuilder(G_CTTZ
).legalFor({{s32
, s64
}});
297 B
.buildInstr(TargetOpcode::G_CTTZ
, {LLT::scalar(32)}, {Copies
[0]});
298 AInfo
Info(MF
->getSubtarget());
299 DummyGISelObserver Observer
;
300 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
301 // Perform Legalization
302 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
303 Helper
.narrowScalar(*CTTZ
, 1, LLT::scalar(32)));
306 CHECK: [[UNMERGE_LO:%[0-9]+]]:_(s32), [[UNMERGE_HI:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES %0:_(s64)
307 CHECK: [[ZERO:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
308 CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[UNMERGE_LO]]:_(s32), [[ZERO]]:_
309 CHECK: [[CTTZ_HI:%[0-9]+]]:_(s32) = G_CTTZ [[UNMERGE_HI]]:_(s32)
310 CHECK: [[THIRTYTWO:%[0-9]+]]:_(s32) = G_CONSTANT i32 32
311 CHECK: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[CTTZ_HI]]:_, [[THIRTYTWO]]:_
312 CHECK: [[CTTZ_LO:%[0-9]+]]:_(s32) = G_CTTZ_ZERO_UNDEF [[UNMERGE_LO]]:_(s32)
313 CHECK: %{{[0-9]+}}:_(s32) = G_SELECT [[CMP]]:_(s1), [[ADD]]:_, [[CTTZ_LO]]:_
317 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
320 // CTTZ expansion in terms of CTPOP
321 TEST_F(AArch64GISelMITest
, LowerBitCountingCTTZ2
) {
326 // Declare your legalization info
327 DefineLegalizerInfo(A
, {
328 getActionDefinitionsBuilder(G_CTPOP
).legalFor({{s64
, s64
}});
332 B
.buildInstr(TargetOpcode::G_CTTZ
, {LLT::scalar(64)}, {Copies
[0]});
333 AInfo
Info(MF
->getSubtarget());
334 DummyGISelObserver Observer
;
335 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
337 B
.setInsertPt(*EntryMBB
, MIBCTTZ
->getIterator());
338 EXPECT_TRUE(Helper
.lower(*MIBCTTZ
, 0, LLT::scalar(64)) ==
339 LegalizerHelper::LegalizeResult::Legalized
);
342 CHECK: [[NEG1:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1
343 CHECK: [[NOT:%[0-9]+]]:_(s64) = G_XOR %0:_, [[NEG1]]
344 CHECK: [[SUB1:%[0-9]+]]:_(s64) = G_ADD %0:_, [[NEG1]]
345 CHECK: [[AND1:%[0-9]+]]:_(s64) = G_AND [[NOT]]:_, [[SUB1]]:_
346 CHECK: [[POP:%[0-9]+]]:_(s64) = G_CTPOP [[AND1]]
350 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
354 TEST_F(AArch64GISelMITest
, WidenBitCountingCTPOP1
) {
359 // Declare your legalization info
360 DefineLegalizerInfo(A
, {
361 getActionDefinitionsBuilder(G_CTPOP
).legalFor({{s16
, s16
}});
366 LLT s8
{LLT::scalar(8)};
367 LLT s16
{LLT::scalar(16)};
368 auto MIBTrunc
= B
.buildTrunc(s8
, Copies
[0]);
369 auto MIBCTPOP
= B
.buildInstr(TargetOpcode::G_CTPOP
, {s16
}, {MIBTrunc
});
370 AInfo
Info(MF
->getSubtarget());
371 DummyGISelObserver Observer
;
372 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
373 B
.setInstr(*MIBCTPOP
);
374 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
375 Helper
.widenScalar(*MIBCTPOP
, 1, s16
));
378 CHECK: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC %0:_(s64)
379 CHECK: [[ZEXT:%[0-9]+]]:_(s16) = G_ZEXT [[TRUNC]]:_(s8)
380 CHECK: [[CTPOP:%[0-9]+]]:_(s16) = G_CTPOP [[ZEXT]]
381 CHECK: [[COPY:%[0-9]+]]:_(s16) = COPY [[CTPOP]]:_(s16)
384 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
387 // Test a strange case where the result is wider than the source
388 TEST_F(AArch64GISelMITest
, WidenBitCountingCTPOP2
) {
393 // Declare your legalization info
394 DefineLegalizerInfo(A
, {
395 getActionDefinitionsBuilder(G_CTPOP
).legalFor({{s32
, s16
}});
400 LLT s8
{LLT::scalar(8)};
401 LLT s16
{LLT::scalar(16)};
402 LLT s32
{LLT::scalar(32)};
403 auto MIBTrunc
= B
.buildTrunc(s8
, Copies
[0]);
404 auto MIBCTPOP
= B
.buildInstr(TargetOpcode::G_CTPOP
, {s32
}, {MIBTrunc
});
405 AInfo
Info(MF
->getSubtarget());
406 DummyGISelObserver Observer
;
407 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
408 B
.setInstr(*MIBCTPOP
);
409 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
410 Helper
.widenScalar(*MIBCTPOP
, 1, s16
));
413 CHECK: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC %0:_(s64)
414 CHECK: [[ZEXT:%[0-9]+]]:_(s16) = G_ZEXT [[TRUNC]]:_(s8)
415 CHECK: [[CTPOP:%[0-9]+]]:_(s16) = G_CTPOP [[ZEXT]]
416 CHECK: [[COPY:%[0-9]+]]:_(s32) = G_ZEXT [[CTPOP]]:_(s16)
419 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
422 // CTTZ_ZERO_UNDEF expansion in terms of CTTZ
423 TEST_F(AArch64GISelMITest
, LowerBitCountingCTTZ3
) {
428 // Declare your legalization info
429 DefineLegalizerInfo(A
, {
430 getActionDefinitionsBuilder(G_CTTZ
).legalFor({{s64
, s64
}});
433 auto MIBCTTZ
= B
.buildInstr(TargetOpcode::G_CTTZ_ZERO_UNDEF
,
434 {LLT::scalar(64)}, {Copies
[0]});
435 AInfo
Info(MF
->getSubtarget());
436 DummyGISelObserver Observer
;
437 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
438 EXPECT_TRUE(Helper
.lower(*MIBCTTZ
, 0, LLT::scalar(64)) ==
439 LegalizerHelper::LegalizeResult::Legalized
);
446 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
449 // CTLZ expansion in terms of CTLZ_ZERO_UNDEF
450 TEST_F(AArch64GISelMITest
, LowerBitCountingCTLZ0
) {
455 // Declare your legalization info
456 DefineLegalizerInfo(A
, {
457 getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF
).legalFor({{s64
, s64
}});
461 B
.buildInstr(TargetOpcode::G_CTLZ
, {LLT::scalar(64)}, {Copies
[0]});
462 AInfo
Info(MF
->getSubtarget());
463 DummyGISelObserver Observer
;
464 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
465 EXPECT_TRUE(Helper
.lower(*MIBCTLZ
, 0, LLT::scalar(64)) ==
466 LegalizerHelper::LegalizeResult::Legalized
);
469 CHECK: [[CZU:%[0-9]+]]:_(s64) = G_CTLZ_ZERO_UNDEF %0
470 CHECK: [[ZERO:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
471 CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), %0:_(s64), [[ZERO]]
472 CHECK: [[SIXTY4:%[0-9]+]]:_(s64) = G_CONSTANT i64 64
473 CHECK: [[SEL:%[0-9]+]]:_(s64) = G_SELECT [[CMP]]:_(s1), [[SIXTY4]]:_, [[CZU]]
477 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
480 // CTLZ expansion in terms of CTLZ_ZERO_UNDEF if the latter is a libcall
481 TEST_F(AArch64GISelMITest
, LowerBitCountingCTLZLibcall
) {
486 // Declare your legalization info
487 DefineLegalizerInfo(A
, {
488 getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF
).libcallFor({{s32
, s64
}});
492 B
.buildInstr(TargetOpcode::G_CTLZ
, {LLT::scalar(32)}, {Copies
[0]});
493 AInfo
Info(MF
->getSubtarget());
494 DummyGISelObserver Observer
;
495 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
496 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
497 Helper
.lower(*MIBCTLZ
, 0, LLT::scalar(32)));
500 CHECK: [[CZU:%[0-9]+]]:_(s32) = G_CTLZ_ZERO_UNDEF %0
501 CHECK: [[ZERO:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
502 CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), %0:_(s64), [[ZERO]]
503 CHECK: [[THIRTY2:%[0-9]+]]:_(s32) = G_CONSTANT i32 64
504 CHECK: [[SEL:%[0-9]+]]:_(s32) = G_SELECT [[CMP]]:_(s1), [[THIRTY2]]:_, [[CZU]]
508 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
512 TEST_F(AArch64GISelMITest
, LowerBitCountingCTLZ1
) {
517 // Declare your legalization info
518 DefineLegalizerInfo(A
, {
519 getActionDefinitionsBuilder(G_CTPOP
).legalFor({{s8
, s8
}});
523 LLT s8
{LLT::scalar(8)};
524 auto MIBTrunc
= B
.buildTrunc(s8
, Copies
[0]);
525 auto MIBCTLZ
= B
.buildInstr(TargetOpcode::G_CTLZ
, {s8
}, {MIBTrunc
});
526 AInfo
Info(MF
->getSubtarget());
527 DummyGISelObserver Observer
;
528 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
529 EXPECT_TRUE(Helper
.lower(*MIBCTLZ
, 0, s8
) ==
530 LegalizerHelper::LegalizeResult::Legalized
);
533 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
534 CHECK: [[Cst1:%[0-9]+]]:_(s8) = G_CONSTANT i8 1
535 CHECK: [[Sh1:%[0-9]+]]:_(s8) = G_LSHR [[Trunc]]:_, [[Cst1]]:_
536 CHECK: [[Or1:%[0-9]+]]:_(s8) = G_OR [[Trunc]]:_, [[Sh1]]:_
537 CHECK: [[Cst2:%[0-9]+]]:_(s8) = G_CONSTANT i8 2
538 CHECK: [[Sh2:%[0-9]+]]:_(s8) = G_LSHR [[Or1]]:_, [[Cst2]]:_
539 CHECK: [[Or2:%[0-9]+]]:_(s8) = G_OR [[Or1]]:_, [[Sh2]]:_
540 CHECK: [[Cst4:%[0-9]+]]:_(s8) = G_CONSTANT i8 4
541 CHECK: [[Sh4:%[0-9]+]]:_(s8) = G_LSHR [[Or2]]:_, [[Cst4]]:_
542 CHECK: [[Or4:%[0-9]+]]:_(s8) = G_OR [[Or2]]:_, [[Sh4]]:_
543 CHECK: [[CTPOP:%[0-9]+]]:_(s8) = G_CTPOP [[Or4]]:_
544 CHECK: [[Len:%[0-9]+]]:_(s8) = G_CONSTANT i8 8
545 CHECK: [[Sub:%[0-9]+]]:_(s8) = G_SUB [[Len]]:_, [[CTPOP]]:_
549 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
553 TEST_F(AArch64GISelMITest
, WidenBitCountingCTLZ
) {
558 // Declare your legalization info
559 DefineLegalizerInfo(A
, {
560 getActionDefinitionsBuilder(G_CTLZ
).legalFor({{s16
, s16
}});
564 LLT s8
{LLT::scalar(8)};
565 LLT s16
{LLT::scalar(16)};
566 auto MIBTrunc
= B
.buildTrunc(s8
, Copies
[0]);
567 auto MIBCTLZ
= B
.buildInstr(TargetOpcode::G_CTLZ
, {s8
}, {MIBTrunc
});
568 AInfo
Info(MF
->getSubtarget());
569 DummyGISelObserver Observer
;
570 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
571 EXPECT_TRUE(Helper
.widenScalar(*MIBCTLZ
, 1, s16
) ==
572 LegalizerHelper::LegalizeResult::Legalized
);
575 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
576 CHECK: [[Zext:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
577 CHECK: [[Ctlz:%[0-9]+]]:_(s16) = G_CTLZ [[Zext]]
578 CHECK: [[Cst8:%[0-9]+]]:_(s16) = G_CONSTANT i16 8
579 CHECK: [[Sub:%[0-9]+]]:_(s16) = G_SUB [[Ctlz]]:_, [[Cst8]]:_
580 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC [[Sub]]
584 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
587 // CTLZ_ZERO_UNDEF widening.
588 TEST_F(AArch64GISelMITest
, WidenBitCountingCTLZZeroUndef
) {
593 // Declare your legalization info
594 DefineLegalizerInfo(A
, {
595 getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF
).legalFor({{s16
, s16
}});
599 LLT s8
{LLT::scalar(8)};
600 LLT s16
{LLT::scalar(16)};
601 auto MIBTrunc
= B
.buildTrunc(s8
, Copies
[0]);
603 B
.buildInstr(TargetOpcode::G_CTLZ_ZERO_UNDEF
, {s8
}, {MIBTrunc
});
604 AInfo
Info(MF
->getSubtarget());
605 DummyGISelObserver Observer
;
606 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
607 EXPECT_TRUE(Helper
.widenScalar(*MIBCTLZ_ZU
, 1, s16
) ==
608 LegalizerHelper::LegalizeResult::Legalized
);
611 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
612 CHECK: [[Zext:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
613 CHECK: [[CtlzZu:%[0-9]+]]:_(s16) = G_CTLZ_ZERO_UNDEF [[Zext]]
614 CHECK: [[Cst8:%[0-9]+]]:_(s16) = G_CONSTANT i16 8
615 CHECK: [[Sub:%[0-9]+]]:_(s16) = G_SUB [[CtlzZu]]:_, [[Cst8]]:_
616 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC [[Sub]]
620 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
624 TEST_F(AArch64GISelMITest
, WidenBitCountingCTPOP
) {
629 // Declare your legalization info
630 DefineLegalizerInfo(A
, {
631 getActionDefinitionsBuilder(G_CTPOP
).legalFor({{s16
, s16
}});
635 LLT s8
{LLT::scalar(8)};
636 LLT s16
{LLT::scalar(16)};
637 auto MIBTrunc
= B
.buildTrunc(s8
, Copies
[0]);
638 auto MIBCTPOP
= B
.buildInstr(TargetOpcode::G_CTPOP
, {s8
}, {MIBTrunc
});
639 AInfo
Info(MF
->getSubtarget());
640 DummyGISelObserver Observer
;
641 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
642 EXPECT_TRUE(Helper
.widenScalar(*MIBCTPOP
, 1, s16
) ==
643 LegalizerHelper::LegalizeResult::Legalized
);
646 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
647 CHECK: [[Zext:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
648 CHECK: [[Ctpop:%[0-9]+]]:_(s16) = G_CTPOP [[Zext]]
649 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC [[Ctpop]]
653 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
656 // CTTZ_ZERO_UNDEF widening.
657 TEST_F(AArch64GISelMITest
, WidenBitCountingCTTZ_ZERO_UNDEF
) {
662 // Declare your legalization info
663 DefineLegalizerInfo(A
, {
664 getActionDefinitionsBuilder(G_CTTZ_ZERO_UNDEF
).legalFor({{s16
, s16
}});
668 LLT s8
{LLT::scalar(8)};
669 LLT s16
{LLT::scalar(16)};
670 auto MIBTrunc
= B
.buildTrunc(s8
, Copies
[0]);
671 auto MIBCTTZ_ZERO_UNDEF
=
672 B
.buildInstr(TargetOpcode::G_CTTZ_ZERO_UNDEF
, {s8
}, {MIBTrunc
});
673 AInfo
Info(MF
->getSubtarget());
674 DummyGISelObserver Observer
;
675 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
676 EXPECT_TRUE(Helper
.widenScalar(*MIBCTTZ_ZERO_UNDEF
, 1, s16
) ==
677 LegalizerHelper::LegalizeResult::Legalized
);
680 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
681 CHECK: [[AnyExt:%[0-9]+]]:_(s16) = G_ANYEXT [[Trunc]]
682 CHECK: [[CttzZu:%[0-9]+]]:_(s16) = G_CTTZ_ZERO_UNDEF [[AnyExt]]
683 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC [[CttzZu]]
687 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
691 TEST_F(AArch64GISelMITest
, WidenBitCountingCTTZ
) {
696 // Declare your legalization info
697 DefineLegalizerInfo(A
, {
698 getActionDefinitionsBuilder(G_CTTZ
).legalFor({{s16
, s16
}});
702 LLT s8
{LLT::scalar(8)};
703 LLT s16
{LLT::scalar(16)};
704 auto MIBTrunc
= B
.buildTrunc(s8
, Copies
[0]);
705 auto MIBCTTZ
= B
.buildInstr(TargetOpcode::G_CTTZ
, {s8
}, {MIBTrunc
});
706 AInfo
Info(MF
->getSubtarget());
707 DummyGISelObserver Observer
;
708 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
709 EXPECT_TRUE(Helper
.widenScalar(*MIBCTTZ
, 1, s16
) ==
710 LegalizerHelper::LegalizeResult::Legalized
);
713 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
714 CHECK: [[AnyExt:%[0-9]+]]:_(s16) = G_ANYEXT [[Trunc]]
715 CHECK: [[Cst:%[0-9]+]]:_(s16) = G_CONSTANT i16 256
716 CHECK: [[Or:%[0-9]+]]:_(s16) = G_OR [[AnyExt]]:_, [[Cst]]
717 CHECK: [[Cttz:%[0-9]+]]:_(s16) = G_CTTZ_ZERO_UNDEF [[Or]]
718 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC [[Cttz]]
722 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
725 TEST_F(AArch64GISelMITest
, WidenUADDO
) {
730 // Declare your legalization info
731 DefineLegalizerInfo(A
, {
732 getActionDefinitionsBuilder(G_ADD
).legalFor({{s16
, s16
}});
736 LLT s8
{LLT::scalar(8)};
737 LLT s16
{LLT::scalar(16)};
738 auto MIBTrunc
= B
.buildTrunc(s8
, Copies
[0]);
739 unsigned CarryReg
= MRI
->createGenericVirtualRegister(LLT::scalar(1));
741 B
.buildInstr(TargetOpcode::G_UADDO
, {s8
, CarryReg
}, {MIBTrunc
, MIBTrunc
});
742 AInfo
Info(MF
->getSubtarget());
743 DummyGISelObserver Observer
;
744 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
745 EXPECT_TRUE(Helper
.widenScalar(*MIBUAddO
, 0, s16
) ==
746 LegalizerHelper::LegalizeResult::Legalized
);
749 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
750 CHECK: [[LHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
751 CHECK: [[RHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
752 CHECK: [[ADD:%[0-9]+]]:_(s16) = G_ADD [[LHS]]:_, [[RHS]]:_
753 CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[ADD]]
754 CHECK: [[ZEXT:%[0-9]+]]:_(s16) = G_ZEXT [[TRUNC1]]
755 CHECK: G_ICMP intpred(ne), [[ADD]]:_(s16), [[ZEXT]]:_
756 CHECK: G_TRUNC [[ADD]]
760 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
764 TEST_F(AArch64GISelMITest
, WidenUSUBO
) {
769 // Declare your legalization info
770 DefineLegalizerInfo(A
, {
771 getActionDefinitionsBuilder(G_SUB
).legalFor({{s16
, s16
}});
775 LLT s8
{LLT::scalar(8)};
776 LLT s16
{LLT::scalar(16)};
777 auto MIBTrunc
= B
.buildTrunc(s8
, Copies
[0]);
778 unsigned CarryReg
= MRI
->createGenericVirtualRegister(LLT::scalar(1));
780 B
.buildInstr(TargetOpcode::G_USUBO
, {s8
, CarryReg
}, {MIBTrunc
, MIBTrunc
});
781 AInfo
Info(MF
->getSubtarget());
782 DummyGISelObserver Observer
;
783 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
784 EXPECT_TRUE(Helper
.widenScalar(*MIBUSUBO
, 0, s16
) ==
785 LegalizerHelper::LegalizeResult::Legalized
);
788 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
789 CHECK: [[LHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
790 CHECK: [[RHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
791 CHECK: [[SUB:%[0-9]+]]:_(s16) = G_SUB [[LHS]]:_, [[RHS]]:_
792 CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[SUB]]
793 CHECK: [[ZEXT:%[0-9]+]]:_(s16) = G_ZEXT [[TRUNC1]]
794 CHECK: G_ICMP intpred(ne), [[SUB]]:_(s16), [[ZEXT]]:_
795 CHECK: G_TRUNC [[SUB]]
799 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
803 TEST_F(AArch64GISelMITest
, WidenSADDO
) {
808 // Declare your legalization info
809 DefineLegalizerInfo(A
, {
810 getActionDefinitionsBuilder(G_ADD
).legalFor({{s16
, s16
}});
814 LLT s8
{LLT::scalar(8)};
815 LLT s16
{LLT::scalar(16)};
816 auto MIBTrunc
= B
.buildTrunc(s8
, Copies
[0]);
817 unsigned CarryReg
= MRI
->createGenericVirtualRegister(LLT::scalar(1));
819 B
.buildInstr(TargetOpcode::G_SADDO
, {s8
, CarryReg
}, {MIBTrunc
, MIBTrunc
});
820 AInfo
Info(MF
->getSubtarget());
821 DummyGISelObserver Observer
;
822 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
823 EXPECT_TRUE(Helper
.widenScalar(*MIBSAddO
, 0, s16
) ==
824 LegalizerHelper::LegalizeResult::Legalized
);
827 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
828 CHECK: [[LHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]]
829 CHECK: [[RHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]]
830 CHECK: [[ADD:%[0-9]+]]:_(s16) = G_ADD [[LHS]]:_, [[RHS]]:_
831 CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[ADD]]
832 CHECK: [[SEXT:%[0-9]+]]:_(s16) = G_SEXT [[TRUNC1]]
833 CHECK: G_ICMP intpred(ne), [[ADD]]:_(s16), [[SEXT]]:_
834 CHECK: G_TRUNC [[ADD]]
838 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
842 TEST_F(AArch64GISelMITest
, WidenSSUBO
) {
847 // Declare your legalization info
848 DefineLegalizerInfo(A
, {
849 getActionDefinitionsBuilder(G_SUB
).legalFor({{s16
, s16
}});
853 LLT s8
{LLT::scalar(8)};
854 LLT s16
{LLT::scalar(16)};
855 auto MIBTrunc
= B
.buildTrunc(s8
, Copies
[0]);
856 unsigned CarryReg
= MRI
->createGenericVirtualRegister(LLT::scalar(1));
858 B
.buildInstr(TargetOpcode::G_SSUBO
, {s8
, CarryReg
}, {MIBTrunc
, MIBTrunc
});
859 AInfo
Info(MF
->getSubtarget());
860 DummyGISelObserver Observer
;
861 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
862 EXPECT_TRUE(Helper
.widenScalar(*MIBSSUBO
, 0, s16
) ==
863 LegalizerHelper::LegalizeResult::Legalized
);
866 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
867 CHECK: [[LHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]]
868 CHECK: [[RHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]]
869 CHECK: [[SUB:%[0-9]+]]:_(s16) = G_SUB [[LHS]]:_, [[RHS]]:_
870 CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[SUB]]
871 CHECK: [[SEXT:%[0-9]+]]:_(s16) = G_SEXT [[TRUNC1]]
872 CHECK: G_ICMP intpred(ne), [[SUB]]:_(s16), [[SEXT]]:_
873 CHECK: G_TRUNC [[SUB]]
877 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
880 TEST_F(AArch64GISelMITest
, WidenUADDE
) {
885 // Declare your legalization info
886 DefineLegalizerInfo(A
, {
887 getActionDefinitionsBuilder(G_UADDE
).legalFor({{s16
, s16
}});
891 LLT s8
{LLT::scalar(8)};
892 LLT s16
{LLT::scalar(16)};
893 auto MIBTrunc
= B
.buildTrunc(s8
, Copies
[0]);
894 auto CarryIn
= B
.buildUndef(LLT::scalar(1));
895 Register CarryReg
= MRI
->createGenericVirtualRegister(LLT::scalar(1));
896 auto MIBUAddO
= B
.buildInstr(TargetOpcode::G_UADDE
, {s8
, CarryReg
},
897 {MIBTrunc
, MIBTrunc
, CarryIn
});
898 AInfo
Info(MF
->getSubtarget());
899 DummyGISelObserver Observer
;
900 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
901 EXPECT_TRUE(Helper
.widenScalar(*MIBUAddO
, 0, s16
) ==
902 LegalizerHelper::LegalizeResult::Legalized
);
904 const char *CheckStr
= R
"(
905 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
906 CHECK: [[Implicit:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF
907 CHECK: [[LHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
908 CHECK: [[RHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
909 CHECK: [[UADDE:%[0-9]+]]:_(s16), [[CARRY:%[0-9]+]]:_(s1) = G_UADDE [[LHS]]:_, [[RHS]]:_, [[Implicit]]:_
910 CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[UADDE]]
911 CHECK: [[ZEXT:%[0-9]+]]:_(s16) = G_ZEXT [[TRUNC1]]
912 CHECK: G_ICMP intpred(ne), [[UADDE]]:_(s16), [[ZEXT]]:_
913 CHECK: G_TRUNC [[UADDE]]
917 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
920 TEST_F(AArch64GISelMITest
, WidenUSUBE
) {
925 // Declare your legalization info
926 DefineLegalizerInfo(A
, {
927 getActionDefinitionsBuilder(G_USUBE
).legalFor({{s16
, s16
}});
931 LLT s8
{LLT::scalar(8)};
932 LLT s16
{LLT::scalar(16)};
933 auto MIBTrunc
= B
.buildTrunc(s8
, Copies
[0]);
934 auto CarryIn
= B
.buildUndef(LLT::scalar(1));
935 Register CarryReg
= MRI
->createGenericVirtualRegister(LLT::scalar(1));
936 auto MIBUSUBE
= B
.buildInstr(TargetOpcode::G_USUBE
, {s8
, CarryReg
},
937 {MIBTrunc
, MIBTrunc
, CarryIn
});
938 AInfo
Info(MF
->getSubtarget());
939 DummyGISelObserver Observer
;
940 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
941 EXPECT_TRUE(Helper
.widenScalar(*MIBUSUBE
, 0, s16
) ==
942 LegalizerHelper::LegalizeResult::Legalized
);
944 const char *CheckStr
= R
"(
945 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
946 CHECK: [[Implicit:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF
947 CHECK: [[LHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
948 CHECK: [[RHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
949 CHECK: [[USUBE:%[0-9]+]]:_(s16), [[CARRY:%[0-9]+]]:_(s1) = G_USUBE [[LHS]]:_, [[RHS]]:_, [[Implicit]]:_
950 CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[USUBE]]
951 CHECK: [[ZEXT:%[0-9]+]]:_(s16) = G_ZEXT [[TRUNC1]]
952 CHECK: G_ICMP intpred(ne), [[USUBE]]:_(s16), [[ZEXT]]:_
953 CHECK: G_TRUNC [[USUBE]]
957 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
960 TEST_F(AArch64GISelMITest
, WidenSADDE
) {
965 // Declare your legalization info
966 DefineLegalizerInfo(A
, {
967 getActionDefinitionsBuilder({G_SADDE
, G_UADDE
}).legalFor({{s16
, s16
}});
971 LLT s8
{LLT::scalar(8)};
972 LLT s16
{LLT::scalar(16)};
973 auto MIBTrunc
= B
.buildTrunc(s8
, Copies
[0]);
974 auto CarryIn
= B
.buildUndef(LLT::scalar(1));
975 Register CarryReg
= MRI
->createGenericVirtualRegister(LLT::scalar(1));
976 auto MIBUAddO
= B
.buildInstr(TargetOpcode::G_SADDE
, {s8
, CarryReg
},
977 {MIBTrunc
, MIBTrunc
, CarryIn
});
978 AInfo
Info(MF
->getSubtarget());
979 DummyGISelObserver Observer
;
980 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
981 EXPECT_TRUE(Helper
.widenScalar(*MIBUAddO
, 0, s16
) ==
982 LegalizerHelper::LegalizeResult::Legalized
);
984 const char *CheckStr
= R
"(
985 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
986 CHECK: [[Implicit:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF
987 CHECK: [[LHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]]
988 CHECK: [[RHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]]
989 CHECK: [[SADDE:%[0-9]+]]:_(s16), [[CARRY:%[0-9]+]]:_(s1) = G_UADDE [[LHS]]:_, [[RHS]]:_, [[Implicit]]:_
990 CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[SADDE]]
991 CHECK: [[SEXT:%[0-9]+]]:_(s16) = G_SEXT [[TRUNC1]]
992 CHECK: G_ICMP intpred(ne), [[SADDE]]:_(s16), [[SEXT]]:_
993 CHECK: G_TRUNC [[SADDE]]
997 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
1000 TEST_F(AArch64GISelMITest
, WidenSSUBE
) {
1005 // Declare your legalization info
1006 DefineLegalizerInfo(A
, {
1007 getActionDefinitionsBuilder({G_SSUBE
, G_USUBE
}).legalFor({{s16
, s16
}});
1011 LLT s8
{LLT::scalar(8)};
1012 LLT s16
{LLT::scalar(16)};
1013 auto MIBTrunc
= B
.buildTrunc(s8
, Copies
[0]);
1014 auto CarryIn
= B
.buildUndef(LLT::scalar(1));
1015 Register CarryReg
= MRI
->createGenericVirtualRegister(LLT::scalar(1));
1016 auto MIBSSUBE
= B
.buildInstr(TargetOpcode::G_SSUBE
, {s8
, CarryReg
},
1017 {MIBTrunc
, MIBTrunc
, CarryIn
});
1018 AInfo
Info(MF
->getSubtarget());
1019 DummyGISelObserver Observer
;
1020 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
1021 EXPECT_TRUE(Helper
.widenScalar(*MIBSSUBE
, 0, s16
) ==
1022 LegalizerHelper::LegalizeResult::Legalized
);
1024 const char *CheckStr
= R
"(
1025 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
1026 CHECK: [[Implicit:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF
1027 CHECK: [[LHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]]
1028 CHECK: [[RHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]]
1029 CHECK: [[SSUBE:%[0-9]+]]:_(s16), [[CARRY:%[0-9]+]]:_(s1) = G_USUBE [[LHS]]:_, [[RHS]]:_, [[Implicit]]:_
1030 CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[SSUBE]]
1031 CHECK: [[SEXT:%[0-9]+]]:_(s16) = G_SEXT [[TRUNC1]]
1032 CHECK: G_ICMP intpred(ne), [[SSUBE]]:_(s16), [[SEXT]]:_
1033 CHECK: G_TRUNC [[SSUBE]]
1037 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
1040 TEST_F(AArch64GISelMITest
, WidenUMULOCondition
) {
1045 // Declare your legalization info
1046 DefineLegalizerInfo(A
, {
1047 getActionDefinitionsBuilder(G_ADD
).legalFor({{s16
, s16
}});
1050 LLT s32
= LLT::scalar(32);
1051 LLT s64
= LLT::scalar(64);
1054 B
.buildInstr(TargetOpcode::G_UMULO
, {s64
, LLT::scalar(1)},
1055 {Copies
[0], Copies
[1]});
1056 AInfo
Info(MF
->getSubtarget());
1057 DummyGISelObserver Observer
;
1058 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
1060 B
.setInstrAndDebugLoc(*UMulo
);
1061 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
1062 Helper
.widenScalar(*UMulo
, 1, s32
));
1065 CHECK: [[COPY0:%[0-9]+]]:_(s64) = COPY
1066 CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY
1067 CHECK: [[ADD:%[0-9]+]]:_(s64), [[OVERFLOW:%[0-9]+]]:_(s32) = G_UMULO [[COPY0]]:_, [[COPY1]]:_
1068 CHECK: {{[0-9]+}}:_(s1) = G_TRUNC [[OVERFLOW]]
1072 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
1075 TEST_F(AArch64GISelMITest
, NarrowUADDO
) {
1080 LLT S1
= LLT::scalar(1);
1081 LLT S32
= LLT::scalar(32);
1082 LLT S96
= LLT::scalar(96);
1083 DefineLegalizerInfo(A
, {
1084 getActionDefinitionsBuilder({G_UADDO
, G_UADDE
})
1085 .legalFor({{LLT::scalar(32), LLT::scalar(1)}});
1088 auto Op0
= B
.buildUndef(S96
);
1089 auto Op1
= B
.buildUndef(S96
);
1090 auto UADDO
= B
.buildUAddo(S96
, S1
, Op0
, Op1
);
1092 AInfo
Info(MF
->getSubtarget());
1093 DummyGISelObserver Observer
;
1094 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
1095 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
1096 Helper
.narrowScalar(*UADDO
, 0, S32
));
1098 const char *CheckStr
= R
"(
1099 CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
1100 CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
1101 CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]]
1102 CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]]
1103 CHECK: [[UADDO0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_UADDO [[OP0_0]]:_, [[OP1_0]]:_
1104 CHECK: [[UADDO1:%[0-9]+]]:_(s32), [[CARRY1:%[0-9]+]]:_(s1) = G_UADDE [[OP0_1]]:_, [[OP1_1]]:_, [[CARRY0]]:_
1105 CHECK: [[UADDO2:%[0-9]+]]:_(s32), [[CARRY2:%[0-9]+]]:_(s1) = G_UADDE [[OP0_2]]:_, [[OP1_2]]:_, [[CARRY1]]:_
1106 CHECK: [[UADDO:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[UADDO0]]:_(s32), [[UADDO1]]:_(s32), [[UADDO2]]:_(s32)
1109 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
1112 TEST_F(AArch64GISelMITest
, NarrowUSUBO
) {
1117 LLT S1
= LLT::scalar(1);
1118 LLT S32
= LLT::scalar(32);
1119 LLT S96
= LLT::scalar(96);
1120 DefineLegalizerInfo(A
, {
1121 getActionDefinitionsBuilder({G_USUBO
, G_USUBE
})
1122 .legalFor({{LLT::scalar(32), LLT::scalar(1)}});
1125 auto Op0
= B
.buildUndef(S96
);
1126 auto Op1
= B
.buildUndef(S96
);
1127 auto USUBO
= B
.buildUSubo(S96
, S1
, Op0
, Op1
);
1129 AInfo
Info(MF
->getSubtarget());
1130 DummyGISelObserver Observer
;
1131 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
1132 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
1133 Helper
.narrowScalar(*USUBO
, 0, S32
));
1135 const char *CheckStr
= R
"(
1136 CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
1137 CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
1138 CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]]
1139 CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]]
1140 CHECK: [[USUBO0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_USUBO [[OP0_0]]:_, [[OP1_0]]:_
1141 CHECK: [[USUBO1:%[0-9]+]]:_(s32), [[CARRY1:%[0-9]+]]:_(s1) = G_USUBE [[OP0_1]]:_, [[OP1_1]]:_, [[CARRY0]]:_
1142 CHECK: [[USUBO2:%[0-9]+]]:_(s32), [[CARRY2:%[0-9]+]]:_(s1) = G_USUBE [[OP0_2]]:_, [[OP1_2]]:_, [[CARRY1]]:_
1143 CHECK: [[USUBO:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[USUBO0]]:_(s32), [[USUBO1]]:_(s32), [[USUBO2]]:_(s32)
1146 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
1149 TEST_F(AArch64GISelMITest
, NarrowSADDO
) {
1154 LLT S1
= LLT::scalar(1);
1155 LLT S32
= LLT::scalar(32);
1156 LLT S96
= LLT::scalar(96);
1157 DefineLegalizerInfo(A
, {
1158 getActionDefinitionsBuilder({G_UADDO
, G_UADDE
, G_SADDE
})
1159 .legalFor({{LLT::scalar(32), LLT::scalar(1)}});
1162 auto Op0
= B
.buildUndef(S96
);
1163 auto Op1
= B
.buildUndef(S96
);
1164 auto SADDO
= B
.buildSAddo(S96
, S1
, Op0
, Op1
);
1166 AInfo
Info(MF
->getSubtarget());
1167 DummyGISelObserver Observer
;
1168 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
1169 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
1170 Helper
.narrowScalar(*SADDO
, 0, S32
));
1172 const char *CheckStr
= R
"(
1173 CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
1174 CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
1175 CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]]
1176 CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]]
1177 CHECK: [[SADDO0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_UADDO [[OP0_0]]:_, [[OP1_0]]:_
1178 CHECK: [[SADDO1:%[0-9]+]]:_(s32), [[CARRY1:%[0-9]+]]:_(s1) = G_UADDE [[OP0_1]]:_, [[OP1_1]]:_, [[CARRY0]]:_
1179 CHECK: [[SADDO2:%[0-9]+]]:_(s32), [[CARRY2:%[0-9]+]]:_(s1) = G_SADDE [[OP0_2]]:_, [[OP1_2]]:_, [[CARRY1]]:_
1180 CHECK: [[SADDO:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[SADDO0]]:_(s32), [[SADDO1]]:_(s32), [[SADDO2]]:_(s32)
1183 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
1186 TEST_F(AArch64GISelMITest
, NarrowSSUBO
) {
1191 LLT S1
= LLT::scalar(1);
1192 LLT S32
= LLT::scalar(32);
1193 LLT S96
= LLT::scalar(96);
1194 DefineLegalizerInfo(A
, {
1195 getActionDefinitionsBuilder({G_USUBO
, G_USUBE
, G_SSUBE
})
1196 .legalFor({{LLT::scalar(32), LLT::scalar(1)}});
1199 auto Op0
= B
.buildUndef(S96
);
1200 auto Op1
= B
.buildUndef(S96
);
1201 auto SSUBO
= B
.buildSSubo(S96
, S1
, Op0
, Op1
);
1203 AInfo
Info(MF
->getSubtarget());
1204 DummyGISelObserver Observer
;
1205 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
1206 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
1207 Helper
.narrowScalar(*SSUBO
, 0, S32
));
1209 const char *CheckStr
= R
"(
1210 CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
1211 CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
1212 CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]]
1213 CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]]
1214 CHECK: [[SSUBO0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_USUBO [[OP0_0]]:_, [[OP1_0]]:_
1215 CHECK: [[SSUBO1:%[0-9]+]]:_(s32), [[CARRY1:%[0-9]+]]:_(s1) = G_USUBE [[OP0_1]]:_, [[OP1_1]]:_, [[CARRY0]]:_
1216 CHECK: [[SSUBO2:%[0-9]+]]:_(s32), [[CARRY2:%[0-9]+]]:_(s1) = G_SSUBE [[OP0_2]]:_, [[OP1_2]]:_, [[CARRY1]]:_
1217 CHECK: [[SSUBO:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[SSUBO0]]:_(s32), [[SSUBO1]]:_(s32), [[SSUBO2]]:_(s32)
1220 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
1223 TEST_F(AArch64GISelMITest
, NarrowUADDE
) {
1228 LLT S1
= LLT::scalar(1);
1229 LLT S32
= LLT::scalar(32);
1230 LLT S96
= LLT::scalar(96);
1231 DefineLegalizerInfo(A
, {
1232 getActionDefinitionsBuilder(G_UADDE
).legalFor(
1233 {{LLT::scalar(32), LLT::scalar(1)}});
1236 auto Op0
= B
.buildUndef(S96
);
1237 auto Op1
= B
.buildUndef(S96
);
1238 auto Op2
= B
.buildUndef(S1
);
1239 auto UADDE
= B
.buildUAdde(S96
, S1
, Op0
, Op1
, Op2
);
1241 AInfo
Info(MF
->getSubtarget());
1242 DummyGISelObserver Observer
;
1243 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
1244 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
1245 Helper
.narrowScalar(*UADDE
, 0, S32
));
1247 const char *CheckStr
= R
"(
1248 CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
1249 CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
1250 CHECK: [[IMP_DEF2:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF
1251 CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]]
1252 CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]]
1253 CHECK: [[UADDE0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_UADDE [[OP0_0]]:_, [[OP1_0]]:_, [[IMP_DEF2]]:_
1254 CHECK: [[UADDE1:%[0-9]+]]:_(s32), [[CARRY1:%[0-9]+]]:_(s1) = G_UADDE [[OP0_1]]:_, [[OP1_1]]:_, [[CARRY0]]:_
1255 CHECK: [[UADDE2:%[0-9]+]]:_(s32), [[CARRY2:%[0-9]+]]:_(s1) = G_UADDE [[OP0_2]]:_, [[OP1_2]]:_, [[CARRY1]]:_
1256 CHECK: [[UADDE:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[UADDE0]]:_(s32), [[UADDE1]]:_(s32), [[UADDE2]]:_(s32)
1259 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
1262 TEST_F(AArch64GISelMITest
, NarrowUSUBE
) {
1267 LLT S1
= LLT::scalar(1);
1268 LLT S32
= LLT::scalar(32);
1269 LLT S96
= LLT::scalar(96);
1270 DefineLegalizerInfo(A
, {
1271 getActionDefinitionsBuilder(G_USUBE
).legalFor(
1272 {{LLT::scalar(32), LLT::scalar(1)}});
1275 auto Op0
= B
.buildUndef(S96
);
1276 auto Op1
= B
.buildUndef(S96
);
1277 auto Op2
= B
.buildUndef(S1
);
1278 auto USUBE
= B
.buildUSube(S96
, S1
, Op0
, Op1
, Op2
);
1280 AInfo
Info(MF
->getSubtarget());
1281 DummyGISelObserver Observer
;
1282 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
1283 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
1284 Helper
.narrowScalar(*USUBE
, 0, S32
));
1286 const char *CheckStr
= R
"(
1287 CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
1288 CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
1289 CHECK: [[IMP_DEF2:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF
1290 CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]]
1291 CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]]
1292 CHECK: [[USUBE0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_USUBE [[OP0_0]]:_, [[OP1_0]]:_, [[IMP_DEF2]]:_
1293 CHECK: [[USUBE1:%[0-9]+]]:_(s32), [[CARRY1:%[0-9]+]]:_(s1) = G_USUBE [[OP0_1]]:_, [[OP1_1]]:_, [[CARRY0]]:_
1294 CHECK: [[USUBE2:%[0-9]+]]:_(s32), [[CARRY2:%[0-9]+]]:_(s1) = G_USUBE [[OP0_2]]:_, [[OP1_2]]:_, [[CARRY1]]:_
1295 CHECK: [[USUBE:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[USUBE0]]:_(s32), [[USUBE1]]:_(s32), [[USUBE2]]:_(s32)
1298 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
1301 TEST_F(AArch64GISelMITest
, NarrowSADDE
) {
1306 LLT S1
= LLT::scalar(1);
1307 LLT S32
= LLT::scalar(32);
1308 LLT S96
= LLT::scalar(96);
1309 DefineLegalizerInfo(A
, {
1310 getActionDefinitionsBuilder({G_SADDE
, G_UADDE
})
1311 .legalFor({{LLT::scalar(32), LLT::scalar(1)}});
1314 auto Op0
= B
.buildUndef(S96
);
1315 auto Op1
= B
.buildUndef(S96
);
1316 auto Op2
= B
.buildUndef(S1
);
1317 auto SADDE
= B
.buildSAdde(S96
, S1
, Op0
, Op1
, Op2
);
1319 AInfo
Info(MF
->getSubtarget());
1320 DummyGISelObserver Observer
;
1321 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
1322 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
1323 Helper
.narrowScalar(*SADDE
, 0, S32
));
1325 const char *CheckStr
= R
"(
1326 CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
1327 CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
1328 CHECK: [[IMP_DEF2:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF
1329 CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]]
1330 CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]]
1331 CHECK: [[SADDE0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_UADDE [[OP0_0]]:_, [[OP1_0]]:_, [[IMP_DEF2]]:_
1332 CHECK: [[SADDE1:%[0-9]+]]:_(s32), [[CARRY1:%[0-9]+]]:_(s1) = G_UADDE [[OP0_1]]:_, [[OP1_1]]:_, [[CARRY0]]:_
1333 CHECK: [[SADDE2:%[0-9]+]]:_(s32), [[CARRY2:%[0-9]+]]:_(s1) = G_SADDE [[OP0_2]]:_, [[OP1_2]]:_, [[CARRY1]]:_
1334 CHECK: [[SADDE:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[SADDE0]]:_(s32), [[SADDE1]]:_(s32), [[SADDE2]]:_(s32)
1337 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
1340 TEST_F(AArch64GISelMITest
, NarrowSSUBE
) {
1345 LLT S1
= LLT::scalar(1);
1346 LLT S32
= LLT::scalar(32);
1347 LLT S96
= LLT::scalar(96);
1348 DefineLegalizerInfo(A
, {
1349 getActionDefinitionsBuilder({G_SSUBE
, G_USUBE
})
1350 .legalFor({{LLT::scalar(32), LLT::scalar(1)}});
1353 auto Op0
= B
.buildUndef(S96
);
1354 auto Op1
= B
.buildUndef(S96
);
1355 auto Op2
= B
.buildUndef(S1
);
1356 auto SSUBE
= B
.buildSSube(S96
, S1
, Op0
, Op1
, Op2
);
1358 AInfo
Info(MF
->getSubtarget());
1359 DummyGISelObserver Observer
;
1360 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
1361 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
1362 Helper
.narrowScalar(*SSUBE
, 0, S32
));
1364 const char *CheckStr
= R
"(
1365 CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
1366 CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
1367 CHECK: [[IMP_DEF2:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF
1368 CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]]
1369 CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]]
1370 CHECK: [[SSUBE0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_USUBE [[OP0_0]]:_, [[OP1_0]]:_, [[IMP_DEF2]]:_
1371 CHECK: [[SSUBE1:%[0-9]+]]:_(s32), [[CARRY1:%[0-9]+]]:_(s1) = G_USUBE [[OP0_1]]:_, [[OP1_1]]:_, [[CARRY0]]:_
1372 CHECK: [[SSUBE2:%[0-9]+]]:_(s32), [[CARRY2:%[0-9]+]]:_(s1) = G_SSUBE [[OP0_2]]:_, [[OP1_2]]:_, [[CARRY1]]:_
1373 CHECK: [[SSUBE:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[SSUBE0]]:_(s32), [[SSUBE1]]:_(s32), [[SSUBE2]]:_(s32)
1376 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
1379 TEST_F(AArch64GISelMITest
, FewerElementsAnd
) {
1384 const LLT V2S32
= LLT::fixed_vector(2, 32);
1385 const LLT V5S32
= LLT::fixed_vector(5, 32);
1387 // Declare your legalization info
1388 DefineLegalizerInfo(A
, {
1389 getActionDefinitionsBuilder(G_AND
)
1393 auto Op0
= B
.buildUndef(V5S32
);
1394 auto Op1
= B
.buildUndef(V5S32
);
1395 auto And
= B
.buildAnd(V5S32
, Op0
, Op1
);
1397 AInfo
Info(MF
->getSubtarget());
1398 DummyGISelObserver Observer
;
1399 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
1401 EXPECT_TRUE(Helper
.fewerElementsVector(*And
, 0, V2S32
) ==
1402 LegalizerHelper::LegalizeResult::Legalized
);
1405 CHECK: [[IMP_DEF0:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF
1406 CHECK: [[IMP_DEF1:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF
1407 CHECK: [[VALUE0:%[0-9]+]]:_(s32), [[VALUE1:%[0-9]+]]:_(s32), [[VALUE2:%[0-9]+]]:_(s32), [[VALUE3:%[0-9]+]]:_(s32), [[VALUE4:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]]:_(<5 x s32>)
1408 CHECK: [[VECTOR0:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[VALUE0]]:_(s32), [[VALUE1]]:_(s32)
1409 CHECK: [[VECTOR1:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[VALUE2]]:_(s32), [[VALUE3]]:_(s32)
1410 CHECK: [[VALUE5:%[0-9]+]]:_(s32), [[VALUE6:%[0-9]+]]:_(s32), [[VALUE7:%[0-9]+]]:_(s32), [[VALUE8:%[0-9]+]]:_(s32), [[VALUE9:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]]:_(<5 x s32>)
1411 CHECK: [[VECTOR2:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[VALUE5]]:_(s32), [[VALUE6]]:_(s32)
1412 CHECK: [[VECTOR3:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[VALUE7]]:_(s32), [[VALUE8]]:_(s32)
1413 CHECK: [[AND0:%[0-9]+]]:_(<2 x s32>) = G_AND [[VECTOR0]]:_, [[VECTOR2]]:_
1414 CHECK: [[AND1:%[0-9]+]]:_(<2 x s32>) = G_AND [[VECTOR1]]:_, [[VECTOR3]]:_
1415 CHECK: [[AND2:%[0-9]+]]:_(s32) = G_AND [[VALUE4]]:_, [[VALUE9]]:_
1416 CHECK: [[AND0_E0:%[0-9]+]]:_(s32), [[AND0_E1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[AND0]]:_(<2 x s32>)
1417 CHECK: [[AND1_E0:%[0-9]+]]:_(s32), [[AND1_E1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[AND1]]:_(<2 x s32>)
1418 CHECK: [[RESULT:%[0-9]+]]:_(<5 x s32>) = G_BUILD_VECTOR [[AND0_E0]]:_(s32), [[AND0_E1]]:_(s32), [[AND1_E0]]:_(s32), [[AND1_E1]]:_(s32), [[AND2]]:_(s32)
1422 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
1425 TEST_F(AArch64GISelMITest
, MoreElementsAnd
) {
1430 LLT s32
= LLT::scalar(32);
1431 LLT v2s32
= LLT::fixed_vector(2, 32);
1432 LLT v6s32
= LLT::fixed_vector(6, 32);
1435 LI
.getActionDefinitionsBuilder(TargetOpcode::G_AND
)
1437 .clampMinNumElements(0, s32
, 6);
1438 LI
.getLegacyLegalizerInfo().computeTables();
1440 DummyGISelObserver Observer
;
1441 LegalizerHelper
Helper(*MF
, LI
, Observer
, B
);
1443 B
.setInsertPt(*EntryMBB
, EntryMBB
->end());
1445 auto Val0
= B
.buildBitcast(v2s32
, Copies
[0]);
1446 auto Val1
= B
.buildBitcast(v2s32
, Copies
[1]);
1448 auto And
= B
.buildAnd(v2s32
, Val0
, Val1
);
1451 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
1452 Helper
.moreElementsVector(*And
, 0, v6s32
));
1455 CHECK: [[BITCAST0:%[0-9]+]]:_(<2 x s32>) = G_BITCAST
1456 CHECK: [[BITCAST1:%[0-9]+]]:_(<2 x s32>) = G_BITCAST
1458 CHECK: [[BITCAST0_E0:%[0-9]+]]:_(s32), [[BITCAST0_E1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[BITCAST0]]:_(<2 x s32>)
1459 CHECK: [[IMP_DEF0:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
1460 CHECK: [[BITCAST0_LARGE:%[0-9]+]]:_(<6 x s32>) = G_BUILD_VECTOR [[BITCAST0_E0]]:_(s32), [[BITCAST0_E1]]:_(s32), [[IMP_DEF0]]:_(s32), [[IMP_DEF0]]:_(s32), [[IMP_DEF0]]:_(s32), [[IMP_DEF0]]:_(s32)
1462 CHECK: [[BITCAST1_E0:%[0-9]+]]:_(s32), [[BITCAST1_E1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[BITCAST1]]:_(<2 x s32>)
1463 CHECK: [[IMP_DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
1464 CHECK: [[BITCAST1_LARGE:%[0-9]+]]:_(<6 x s32>) = G_BUILD_VECTOR [[BITCAST1_E0]]:_(s32), [[BITCAST1_E1]]:_(s32), [[IMP_DEF1]]:_(s32), [[IMP_DEF1]]:_(s32), [[IMP_DEF1]]:_(s32), [[IMP_DEF1]]:_(s32)
1466 CHECK: [[AND:%[0-9]+]]:_(<6 x s32>) = G_AND [[BITCAST0_LARGE]]:_, [[BITCAST1_LARGE]]:_
1468 CHECK: [[AND_E0:%[0-9]+]]:_(s32), [[AND_E1:%[0-9]+]]:_(s32), [[AND_E2:%[0-9]+]]:_(s32), [[AND_E3:%[0-9]+]]:_(s32), [[AND_E4:%[0-9]+]]:_(s32), [[AND_E5:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[AND]]:_(<6 x s32>)
1469 CHECK: (<2 x s32>) = G_BUILD_VECTOR [[AND_E0]]:_(s32), [[AND_E1]]:_(s32)
1472 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
1475 TEST_F(AArch64GISelMITest
, FewerElementsPhi
) {
1480 LLT s1
= LLT::scalar(1);
1481 LLT s32
= LLT::scalar(32);
1482 LLT s64
= LLT::scalar(64);
1483 LLT v2s32
= LLT::fixed_vector(2, 32);
1484 LLT v5s32
= LLT::fixed_vector(5, 32);
1487 LI
.getActionDefinitionsBuilder(TargetOpcode::G_PHI
)
1489 .clampMinNumElements(0, s32
, 2);
1490 LI
.getLegacyLegalizerInfo().computeTables();
1493 DummyGISelObserver Observer
;
1494 LegalizerHelper
Helper(*MF
, LI
, Observer
, B
);
1495 B
.setMBB(*EntryMBB
);
1497 MachineBasicBlock
*MidMBB
= MF
->CreateMachineBasicBlock();
1498 MachineBasicBlock
*EndMBB
= MF
->CreateMachineBasicBlock();
1499 MF
->insert(MF
->end(), MidMBB
);
1500 MF
->insert(MF
->end(), EndMBB
);
1502 EntryMBB
->addSuccessor(MidMBB
);
1503 EntryMBB
->addSuccessor(EndMBB
);
1504 MidMBB
->addSuccessor(EndMBB
);
1506 auto InitVal
= B
.buildUndef(PhiTy
);
1507 auto InitOtherVal
= B
.buildConstant(s64
, 999);
1509 auto ICmp
= B
.buildICmp(CmpInst::ICMP_EQ
, s1
, Copies
[0], Copies
[1]);
1510 B
.buildBrCond(ICmp
.getReg(0), *MidMBB
);
1515 auto MidVal
= B
.buildUndef(PhiTy
);
1516 auto MidOtherVal
= B
.buildConstant(s64
, 345);
1520 auto Phi
= B
.buildInstr(TargetOpcode::G_PHI
)
1521 .addDef(MRI
->createGenericVirtualRegister(PhiTy
))
1522 .addUse(InitVal
.getReg(0))
1524 .addUse(MidVal
.getReg(0))
1527 // Insert another irrelevant phi to make sure the rebuild is inserted after
1529 B
.buildInstr(TargetOpcode::G_PHI
)
1530 .addDef(MRI
->createGenericVirtualRegister(s64
))
1531 .addUse(InitOtherVal
.getReg(0))
1533 .addUse(MidOtherVal
.getReg(0))
1536 // Add some use instruction after the phis.
1537 B
.buildAnd(PhiTy
, Phi
.getReg(0), Phi
.getReg(0));
1540 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
1541 Helper
.fewerElementsVector(*Phi
, 0, v2s32
));
1544 CHECK: [[INITVAL:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF
1545 CHECK: [[INITVAL_E0:%[0-9]+]]:_(s32), [[INITVAL_E1:%[0-9]+]]:_(s32), [[INITVAL_E2:%[0-9]+]]:_(s32), [[INITVAL_E3:%[0-9]+]]:_(s32), [[INITVAL_E4:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[INITVAL]]:_(<5 x s32>)
1546 CHECK: [[INITVAL_E01:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[INITVAL_E0]]:_(s32), [[INITVAL_E1]]:_(s32)
1547 CHECK: [[INITVAL_E23:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[INITVAL_E2]]:_(s32), [[INITVAL_E3]]:_(s32)
1550 CHECK: [[MIDVAL:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF
1551 CHECK: [[MIDVAL_E0:%[0-9]+]]:_(s32), [[MIDVAL_E1:%[0-9]+]]:_(s32), [[MIDVAL_E2:%[0-9]+]]:_(s32), [[MIDVAL_E3:%[0-9]+]]:_(s32), [[MIDVAL_E4:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[MIDVAL]]:_(<5 x s32>)
1552 CHECK: [[MIDVAL_E01:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[MIDVAL_E0]]:_(s32), [[MIDVAL_E1]]:_(s32)
1553 CHECK: [[MIDVAL_E23:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[MIDVAL_E2]]:_(s32), [[MIDVAL_E3]]:_(s32)
1556 CHECK: [[PHI0:%[0-9]+]]:_(<2 x s32>) = G_PHI [[INITVAL_E01]]:_(<2 x s32>), %bb.0, [[MIDVAL_E01]]:_(<2 x s32>), %bb.1
1557 CHECK: [[PHI1:%[0-9]+]]:_(<2 x s32>) = G_PHI [[INITVAL_E23]]:_(<2 x s32>), %bb.0, [[MIDVAL_E23]]:_(<2 x s32>), %bb.1
1558 CHECK: [[PHI2:%[0-9]+]]:_(s32) = G_PHI [[INITVAL_E4]]:_(s32), %bb.0, [[MIDVAL_E4]]:_(s32), %bb.1
1559 CHECK: [[UNMERGE0:%[0-9]+]]:_(s32), [[UNMERGE1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[PHI0]]:_(<2 x s32>)
1560 CHECK: [[UNMERGE2:%[0-9]+]]:_(s32), [[UNMERGE3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[PHI1]]:_(<2 x s32>)
1561 CHECK: [[BV:%[0-9]+]]:_(<5 x s32>) = G_BUILD_VECTOR [[UNMERGE0]]:_(s32), [[UNMERGE1]]:_(s32), [[UNMERGE2]]:_(s32), [[UNMERGE3]]:_(s32), [[PHI2]]:_(s32)
1563 CHECK: [[OTHER_PHI:%[0-9]+]]:_(s64) = G_PHI
1565 CHECK: [[USE_OP:%[0-9]+]]:_(<5 x s32>) = G_AND [[BV]]:_, [[BV]]:_
1568 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
1571 // FNEG expansion in terms of XOR
1572 TEST_F(AArch64GISelMITest
, LowerFNEG
) {
1577 // Declare your legalization info
1578 DefineLegalizerInfo(A
, {
1579 getActionDefinitionsBuilder(G_FSUB
).legalFor({s64
});
1582 // Build Instr. Make sure FMF are preserved.
1584 B
.buildInstr(TargetOpcode::G_FADD
, {LLT::scalar(64)}, {Copies
[0], Copies
[1]},
1585 MachineInstr::MIFlag::FmNsz
);
1587 // Should not propagate the flags of src instruction.
1589 B
.buildInstr(TargetOpcode::G_FNEG
, {LLT::scalar(64)}, {FAdd
.getReg(0)},
1590 {MachineInstr::MIFlag::FmArcp
});
1592 // Preserve the one flag.
1594 B
.buildInstr(TargetOpcode::G_FNEG
, {LLT::scalar(64)}, {Copies
[0]},
1595 MachineInstr::MIFlag::FmNoInfs
);
1597 AInfo
Info(MF
->getSubtarget());
1598 DummyGISelObserver Observer
;
1599 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
1600 // Perform Legalization
1602 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
1603 Helper
.lower(*FNeg0
, 0, LLT::scalar(64)));
1605 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
1606 Helper
.lower(*FNeg1
, 0, LLT::scalar(64)));
1609 CHECK: [[FADD:%[0-9]+]]:_(s64) = nsz G_FADD %0:_, %1:_
1610 CHECK: [[CONST0:%[0-9]+]]:_(s64) = G_CONSTANT i64 -9223372036854775808
1611 CHECK: [[FSUB0:%[0-9]+]]:_(s64) = G_XOR [[FADD]]:_, [[CONST0]]:_
1612 CHECK: [[CONST1:%[0-9]+]]:_(s64) = G_CONSTANT i64 -9223372036854775808
1613 CHECK: [[FSUB1:%[0-9]+]]:_(s64) = G_XOR %0:_, [[CONST1]]:_
1617 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
1620 TEST_F(AArch64GISelMITest
, LowerMinMax
) {
1625 LLT s64
= LLT::scalar(64);
1626 LLT v2s32
= LLT::fixed_vector(2, 32);
1628 DefineLegalizerInfo(A
, {
1629 getActionDefinitionsBuilder({G_SMIN
, G_SMAX
, G_UMIN
, G_UMAX
})
1630 .lowerFor({s64
, LLT::fixed_vector(2, s32
)});
1633 auto SMin
= B
.buildSMin(s64
, Copies
[0], Copies
[1]);
1634 auto SMax
= B
.buildSMax(s64
, Copies
[0], Copies
[1]);
1635 auto UMin
= B
.buildUMin(s64
, Copies
[0], Copies
[1]);
1636 auto UMax
= B
.buildUMax(s64
, Copies
[0], Copies
[1]);
1638 auto VecVal0
= B
.buildBitcast(v2s32
, Copies
[0]);
1639 auto VecVal1
= B
.buildBitcast(v2s32
, Copies
[1]);
1641 auto SMinV
= B
.buildSMin(v2s32
, VecVal0
, VecVal1
);
1642 auto SMaxV
= B
.buildSMax(v2s32
, VecVal0
, VecVal1
);
1643 auto UMinV
= B
.buildUMin(v2s32
, VecVal0
, VecVal1
);
1644 auto UMaxV
= B
.buildUMax(v2s32
, VecVal0
, VecVal1
);
1646 AInfo
Info(MF
->getSubtarget());
1647 DummyGISelObserver Observer
;
1648 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
1650 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
1651 Helper
.lower(*SMin
, 0, s64
));
1653 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
1654 Helper
.lower(*SMax
, 0, s64
));
1656 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
1657 Helper
.lower(*UMin
, 0, s64
));
1659 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
1660 Helper
.lower(*UMax
, 0, s64
));
1663 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
1664 Helper
.lower(*SMinV
, 0, v2s32
));
1666 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
1667 Helper
.lower(*SMaxV
, 0, v2s32
));
1669 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
1670 Helper
.lower(*UMinV
, 0, v2s32
));
1672 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
1673 Helper
.lower(*UMaxV
, 0, v2s32
));
1676 CHECK: [[CMP0:%[0-9]+]]:_(s1) = G_ICMP intpred(slt), %0:_(s64), %1:_
1677 CHECK: [[SMIN:%[0-9]+]]:_(s64) = G_SELECT [[CMP0]]:_(s1), %0:_, %1:_
1679 CHECK: [[CMP1:%[0-9]+]]:_(s1) = G_ICMP intpred(sgt), %0:_(s64), %1:_
1680 CHECK: [[SMAX:%[0-9]+]]:_(s64) = G_SELECT [[CMP1]]:_(s1), %0:_, %1:_
1682 CHECK: [[CMP2:%[0-9]+]]:_(s1) = G_ICMP intpred(ult), %0:_(s64), %1:_
1683 CHECK: [[UMIN:%[0-9]+]]:_(s64) = G_SELECT [[CMP2]]:_(s1), %0:_, %1:_
1685 CHECK: [[CMP3:%[0-9]+]]:_(s1) = G_ICMP intpred(ugt), %0:_(s64), %1:_
1686 CHECK: [[UMAX:%[0-9]+]]:_(s64) = G_SELECT [[CMP3]]:_(s1), %0:_, %1:_
1688 CHECK: [[VEC0:%[0-9]+]]:_(<2 x s32>) = G_BITCAST %0:_(s64)
1689 CHECK: [[VEC1:%[0-9]+]]:_(<2 x s32>) = G_BITCAST %1:_(s64)
1691 CHECK: [[VCMP0:%[0-9]+]]:_(<2 x s1>) = G_ICMP intpred(slt), [[VEC0]]:_(<2 x s32>), [[VEC1]]:_
1692 CHECK: [[SMINV:%[0-9]+]]:_(<2 x s32>) = G_SELECT [[VCMP0]]:_(<2 x s1>), [[VEC0]]:_, [[VEC1]]:_
1694 CHECK: [[VCMP1:%[0-9]+]]:_(<2 x s1>) = G_ICMP intpred(sgt), [[VEC0]]:_(<2 x s32>), [[VEC1]]:_
1695 CHECK: [[SMAXV:%[0-9]+]]:_(<2 x s32>) = G_SELECT [[VCMP1]]:_(<2 x s1>), [[VEC0]]:_, [[VEC1]]:_
1697 CHECK: [[VCMP2:%[0-9]+]]:_(<2 x s1>) = G_ICMP intpred(ult), [[VEC0]]:_(<2 x s32>), [[VEC1]]:_
1698 CHECK: [[UMINV:%[0-9]+]]:_(<2 x s32>) = G_SELECT [[VCMP2]]:_(<2 x s1>), [[VEC0]]:_, [[VEC1]]:_
1700 CHECK: [[VCMP3:%[0-9]+]]:_(<2 x s1>) = G_ICMP intpred(ugt), [[VEC0]]:_(<2 x s32>), [[VEC1]]:_
1701 CHECK: [[UMAXV:%[0-9]+]]:_(<2 x s32>) = G_SELECT [[VCMP3]]:_(<2 x s1>), [[VEC0]]:_, [[VEC1]]:_
1704 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
1707 TEST_F(AArch64GISelMITest
, WidenScalarBuildVector
) {
1712 LLT S32
= LLT::scalar(32);
1713 LLT S16
= LLT::scalar(16);
1714 LLT V2S16
= LLT::fixed_vector(2, S16
);
1715 LLT V2S32
= LLT::fixed_vector(2, S32
);
1717 DefineLegalizerInfo(A
, {
1718 getActionDefinitionsBuilder({G_SMIN
, G_SMAX
, G_UMIN
, G_UMAX
})
1719 .lowerFor({s64
, LLT::fixed_vector(2, s32
)});
1722 AInfo
Info(MF
->getSubtarget());
1723 DummyGISelObserver Observer
;
1724 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
1725 B
.setInsertPt(*EntryMBB
, EntryMBB
->end());
1727 Register Constant0
= B
.buildConstant(S16
, 1).getReg(0);
1728 Register Constant1
= B
.buildConstant(S16
, 2).getReg(0);
1729 auto BV0
= B
.buildBuildVector(V2S16
, {Constant0
, Constant1
});
1730 auto BV1
= B
.buildBuildVector(V2S16
, {Constant0
, Constant1
});
1733 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
1734 Helper
.widenScalar(*BV0
, 0, V2S32
));
1736 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
1737 Helper
.widenScalar(*BV1
, 1, S32
));
1740 CHECK: [[K0:%[0-9]+]]:_(s16) = G_CONSTANT i16 1
1741 CHECK-NEXT: [[K1:%[0-9]+]]:_(s16) = G_CONSTANT i16 2
1742 CHECK-NEXT: [[EXT_K0_0:%[0-9]+]]:_(s32) = G_ANYEXT [[K0]]
1743 CHECK-NEXT: [[EXT_K1_0:%[0-9]+]]:_(s32) = G_ANYEXT [[K1]]
1744 CHECK-NEXT: [[BV0:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[EXT_K0_0]]:_(s32), [[EXT_K1_0]]:_(s32)
1745 CHECK-NEXT: [[BV0_TRUNC:%[0-9]+]]:_(<2 x s16>) = G_TRUNC [[BV0]]
1747 CHECK: [[EXT_K0_1:%[0-9]+]]:_(s32) = G_ANYEXT [[K0]]
1748 CHECK-NEXT: [[EXT_K1_1:%[0-9]+]]:_(s32) = G_ANYEXT [[K1]]
1750 CHECK-NEXT: [[BV1:%[0-9]+]]:_(<2 x s16>) = G_BUILD_VECTOR_TRUNC [[EXT_K0_1]]:_(s32), [[EXT_K1_1]]:_(s32)
1753 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
1756 TEST_F(AArch64GISelMITest
, LowerMergeValues
) {
1761 const LLT S32
= LLT::scalar(32);
1762 const LLT S24
= LLT::scalar(24);
1763 const LLT S21
= LLT::scalar(21);
1764 const LLT S16
= LLT::scalar(16);
1765 const LLT S9
= LLT::scalar(9);
1766 const LLT S8
= LLT::scalar(8);
1767 const LLT S3
= LLT::scalar(3);
1769 DefineLegalizerInfo(A
, {
1770 getActionDefinitionsBuilder(G_UNMERGE_VALUES
)
1771 .widenScalarIf(typeIs(1, LLT::scalar(3)), changeTo(1, LLT::scalar(9)));
1774 AInfo
Info(MF
->getSubtarget());
1775 DummyGISelObserver Observer
;
1776 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
1777 B
.setInsertPt(*EntryMBB
, EntryMBB
->end());
1779 // 24 = 3 3 3 3 3 3 3 3
1782 // This can do 3 merges, but need an extra implicit_def.
1783 SmallVector
<Register
, 8> Merge0Ops
;
1784 for (int I
= 0; I
!= 8; ++I
)
1785 Merge0Ops
.push_back(B
.buildConstant(S3
, I
).getReg(0));
1787 auto Merge0
= B
.buildMerge(S24
, Merge0Ops
);
1789 // 21 = 3 3 3 3 3 3 3
1790 // => 9, 2 extra implicit_def needed
1792 SmallVector
<Register
, 8> Merge1Ops
;
1793 for (int I
= 0; I
!= 7; ++I
)
1794 Merge1Ops
.push_back(B
.buildConstant(S3
, I
).getReg(0));
1796 auto Merge1
= B
.buildMerge(S21
, Merge1Ops
);
1798 SmallVector
<Register
, 8> Merge2Ops
;
1799 for (int I
= 0; I
!= 2; ++I
)
1800 Merge2Ops
.push_back(B
.buildConstant(S8
, I
).getReg(0));
1802 auto Merge2
= B
.buildMerge(S16
, Merge2Ops
);
1804 B
.setInstr(*Merge0
);
1805 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
1806 Helper
.widenScalar(*Merge0
, 1, S9
));
1807 B
.setInstr(*Merge1
);
1808 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
1809 Helper
.widenScalar(*Merge1
, 1, S9
));
1811 // Request a source size greater than the original destination size.
1812 B
.setInstr(*Merge2
);
1813 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
1814 Helper
.widenScalar(*Merge2
, 1, S32
));
1817 CHECK: [[K0:%[0-9]+]]:_(s3) = G_CONSTANT i3 0
1818 CHECK-NEXT: [[K1:%[0-9]+]]:_(s3) = G_CONSTANT i3 1
1819 CHECK-NEXT: [[K2:%[0-9]+]]:_(s3) = G_CONSTANT i3 2
1820 CHECK-NEXT: [[K3:%[0-9]+]]:_(s3) = G_CONSTANT i3 3
1821 CHECK-NEXT: [[K4:%[0-9]+]]:_(s3) = G_CONSTANT i3 -4
1822 CHECK-NEXT: [[K5:%[0-9]+]]:_(s3) = G_CONSTANT i3 -3
1823 CHECK-NEXT: [[K6:%[0-9]+]]:_(s3) = G_CONSTANT i3 -2
1824 CHECK-NEXT: [[K7:%[0-9]+]]:_(s3) = G_CONSTANT i3 -1
1825 CHECK-NEXT: [[IMPDEF0:%[0-9]+]]:_(s3) = G_IMPLICIT_DEF
1826 CHECK-NEXT: [[MERGE0:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K0]]:_(s3), [[K1]]:_(s3), [[K2]]:_(s3)
1827 CHECK-NEXT: [[MERGE1:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K3]]:_(s3), [[K4]]:_(s3), [[K5]]:_(s3)
1828 CHECK-NEXT: [[MERGE2:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K6]]:_(s3), [[K7]]:_(s3), [[IMPDEF0]]:_(s3)
1829 CHECK-NEXT: [[MERGE3:%[0-9]+]]:_(s27) = G_MERGE_VALUES [[MERGE0]]:_(s9), [[MERGE1]]:_(s9), [[MERGE2]]:_(s9)
1830 CHECK-NEXT: (s24) = G_TRUNC [[MERGE3]]:_(s27)
1833 CHECK: [[K8:%[0-9]+]]:_(s3) = G_CONSTANT i3 0
1834 CHECK-NEXT: [[K9:%[0-9]+]]:_(s3) = G_CONSTANT i3 1
1835 CHECK-NEXT: [[K10:%[0-9]+]]:_(s3) = G_CONSTANT i3 2
1836 CHECK-NEXT: [[K11:%[0-9]+]]:_(s3) = G_CONSTANT i3 3
1837 CHECK-NEXT: [[K12:%[0-9]+]]:_(s3) = G_CONSTANT i3 -4
1838 CHECK-NEXT: [[K13:%[0-9]+]]:_(s3) = G_CONSTANT i3 -3
1839 CHECK-NEXT: [[K14:%[0-9]+]]:_(s3) = G_CONSTANT i3 -2
1840 CHECK-NEXT: [[IMPDEF1:%[0-9]+]]:_(s3) = G_IMPLICIT_DEF
1841 CHECK-NEXT: [[MERGE4:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K8]]:_(s3), [[K9]]:_(s3), [[K10]]:_(s3)
1842 CHECK-NEXT: [[MERGE5:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K11]]:_(s3), [[K12]]:_(s3), [[K13]]:_(s3)
1843 CHECK-NEXT: [[MERGE6:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K14]]:_(s3), [[IMPDEF1]]:_(s3), [[IMPDEF1]]:_(s3)
1844 CHECK-NEXT: [[MERGE7:%[0-9]+]]:_(s27) = G_MERGE_VALUES [[MERGE4]]:_(s9), [[MERGE5]]:_(s9), [[MERGE6]]:_(s9)
1845 CHECK-NEXT: (s21) = G_TRUNC [[MERGE7]]:_(s27)
1848 CHECK: [[K15:%[0-9]+]]:_(s8) = G_CONSTANT i8 0
1849 CHECK-NEXT: [[K16:%[0-9]+]]:_(s8) = G_CONSTANT i8 1
1850 CHECK-NEXT: [[ZEXT_K15:[0-9]+]]:_(s32) = G_ZEXT [[K15]]:_(s8)
1851 CHECK-NEXT: [[ZEXT_K16:[0-9]+]]:_(s32) = G_ZEXT [[K16]]:_(s8)
1852 [[K16:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
1853 [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ZEXT_K16]]:_, [[K16]]:_(s32)
1854 [[OR:%[0-9]+]]:_(s32) = G_OR [[ZEXT_K16]]:_, [[SHL]]:_
1855 (s16) = G_TRUNC [[OR]]:_(s32)
1858 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
1861 TEST_F(AArch64GISelMITest
, WidenScalarMergeValuesPointer
) {
1866 DefineLegalizerInfo(A
, {});
1868 AInfo
Info(MF
->getSubtarget());
1869 DummyGISelObserver Observer
;
1870 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
1871 B
.setInsertPt(*EntryMBB
, EntryMBB
->end());
1873 const LLT S32
= LLT::scalar(32);
1874 const LLT S64
= LLT::scalar(64);
1875 const LLT P0
= LLT::pointer(0, 64);
1877 auto Lo
= B
.buildTrunc(S32
, Copies
[0]);
1878 auto Hi
= B
.buildTrunc(S32
, Copies
[1]);
1880 auto Merge
= B
.buildMerge(P0
, {Lo
, Hi
});
1883 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
1884 Helper
.widenScalar(*Merge
, 1, S64
));
1887 CHECK: [[TRUNC0:%[0-9]+]]:_(s32) = G_TRUNC
1888 CHECK: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC
1889 CHECK: [[ZEXT_TRUNC0:%[0-9]+]]:_(s64) = G_ZEXT [[TRUNC0]]
1890 CHECK: [[ZEXT_TRUNC1:%[0-9]+]]:_(s64) = G_ZEXT [[TRUNC1]]
1891 CHECK: [[SHIFT_AMT:%[0-9]+]]:_(s64) = G_CONSTANT i64 32
1892 CHECK: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ZEXT_TRUNC1]]:_, [[SHIFT_AMT]]
1893 CHECK: [[OR:%[0-9]+]]:_(s64) = G_OR [[ZEXT_TRUNC0]]:_, [[SHL]]
1894 CHECK: [[INTTOPTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[OR]]:_(s64)
1897 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
1900 TEST_F(AArch64GISelMITest
, WidenSEXTINREG
) {
1905 // Declare your legalization info
1906 DefineLegalizerInfo(A
, {
1907 getActionDefinitionsBuilder(G_SEXT_INREG
).legalForTypeWithAnyImm({s64
});
1910 auto MIB
= B
.buildInstr(
1911 TargetOpcode::G_SEXT_INREG
, {LLT::scalar(32)},
1912 {B
.buildInstr(TargetOpcode::G_TRUNC
, {LLT::scalar(32)}, {Copies
[0]}),
1914 AInfo
Info(MF
->getSubtarget());
1915 DummyGISelObserver Observer
;
1916 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
1917 // Perform Legalization
1919 ASSERT_TRUE(Helper
.widenScalar(*MIB
, 0, LLT::scalar(64)) ==
1920 LegalizerHelper::LegalizeResult::Legalized
);
1923 CHECK: [[T0:%[0-9]+]]:_(s32) = G_TRUNC
1924 CHECK: [[T1:%[0-9]+]]:_(s64) = G_ANYEXT [[T0]]:_(s32)
1925 CHECK: [[T2:%[0-9]+]]:_(s64) = G_SEXT_INREG [[T1]]:_, 8
1926 CHECK: [[T3:%[0-9]+]]:_(s32) = G_TRUNC [[T2]]:_(s64)
1930 ASSERT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
1933 TEST_F(AArch64GISelMITest
, NarrowSEXTINREG
) {
1938 // Declare your legalization info, these aren't actually relevant to the test.
1939 DefineLegalizerInfo(A
, {
1940 getActionDefinitionsBuilder(G_SEXT_INREG
).legalForTypeWithAnyImm({s64
});
1943 auto MIB
= B
.buildInstr(
1944 TargetOpcode::G_SEXT_INREG
, {LLT::scalar(16)},
1945 {B
.buildInstr(TargetOpcode::G_TRUNC
, {LLT::scalar(16)}, {Copies
[0]}),
1947 AInfo
Info(MF
->getSubtarget());
1948 DummyGISelObserver Observer
;
1949 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
1950 // Perform Legalization
1952 ASSERT_TRUE(Helper
.narrowScalar(*MIB
, 0, LLT::scalar(10)) ==
1953 LegalizerHelper::LegalizeResult::Legalized
);
1956 CHECK: [[T0:%[0-9]+]]:_(s16) = G_TRUNC
1957 CHECK: [[T1:%[0-9]+]]:_(s10) = G_TRUNC [[T0]]:_(s16)
1958 CHECK: [[T2:%[0-9]+]]:_(s10) = G_SEXT_INREG [[T1]]:_, 8
1959 CHECK: [[T3:%[0-9]+]]:_(s16) = G_SEXT [[T2]]:_(s10)
1963 ASSERT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
1966 TEST_F(AArch64GISelMITest
, NarrowSEXTINREG2
) {
1971 // Declare your legalization info, these aren't actually relevant to the test.
1972 DefineLegalizerInfo(
1973 A
, { getActionDefinitionsBuilder(G_SEXT_INREG
).legalForTypeWithAnyImm({s64
}); });
1975 auto MIB
= B
.buildInstr(
1976 TargetOpcode::G_SEXT_INREG
, {LLT::scalar(32)},
1977 {B
.buildInstr(TargetOpcode::G_TRUNC
, {LLT::scalar(32)}, {Copies
[0]}),
1979 AInfo
Info(MF
->getSubtarget());
1980 DummyGISelObserver Observer
;
1981 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
1982 // Perform Legalization
1984 ASSERT_TRUE(Helper
.narrowScalar(*MIB
, 0, LLT::scalar(8)) ==
1985 LegalizerHelper::LegalizeResult::Legalized
);
1988 CHECK: [[T0:%[0-9]+]]:_(s32) = G_TRUNC
1989 CHECK: [[T1:%[0-9]+]]:_(s8), [[T2:%[0-9]+]]:_(s8), [[T3:%[0-9]+]]:_(s8), [[T4:%[0-9]+]]:_(s8) = G_UNMERGE_VALUES [[T0]]:_(s32)
1990 CHECK: [[CST2:%[0-9]+]]:_(s8) = G_CONSTANT i8 7
1991 CHECK: [[T5:%[0-9]+]]:_(s8) = G_SEXT_INREG [[T2]]:_, 1
1992 CHECK: [[T6:%[0-9]+]]:_(s8) = G_ASHR [[T5]]:_, [[CST2]]:_
1993 CHECK: [[T7:%[0-9]+]]:_(s32) = G_MERGE_VALUES [[T1]]:_(s8), [[T5]]:_(s8), [[T6]]:_(s8), [[T6]]:_(s8)
1997 ASSERT_TRUE(CheckMachineFunction(*MF
, CheckStr
));
2000 TEST_F(AArch64GISelMITest
, LowerSEXTINREG
) {
2005 // Declare your legalization info, these aren't actually relevant to the test.
2006 DefineLegalizerInfo(
2007 A
, { getActionDefinitionsBuilder(G_SEXT_INREG
).legalForTypeWithAnyImm({s64
}); });
2009 auto MIB
= B
.buildInstr(
2010 TargetOpcode::G_SEXT_INREG
, {LLT::scalar(32)},
2011 {B
.buildInstr(TargetOpcode::G_TRUNC
, {LLT::scalar(32)}, {Copies
[0]}),
2013 AInfo
Info(MF
->getSubtarget());
2014 DummyGISelObserver Observer
;
2015 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
2016 // Perform Legalization
2018 ASSERT_TRUE(Helper
.lower(*MIB
, 0, LLT()) ==
2019 LegalizerHelper::LegalizeResult::Legalized
);
2022 CHECK: [[T1:%[0-9]+]]:_(s32) = G_TRUNC
2023 CHECK: [[CST:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
2024 CHECK: [[T2:%[0-9]+]]:_(s32) = G_SHL [[T1]]:_, [[CST]]:_
2025 CHECK: [[T3:%[0-9]+]]:_(s32) = G_ASHR [[T2]]:_, [[CST]]:_
2029 ASSERT_TRUE(CheckMachineFunction(*MF
, CheckStr
));
2032 TEST_F(AArch64GISelMITest
, LibcallFPExt
) {
2037 // Declare your legalization info
2038 DefineLegalizerInfo(A
, {
2039 getActionDefinitionsBuilder(G_FPEXT
).libcallFor({{s32
, s16
}, {s128
, s64
}});
2042 LLT S16
{LLT::scalar(16)};
2043 LLT S32
{LLT::scalar(32)};
2044 LLT S128
{LLT::scalar(128)};
2045 auto MIBTrunc
= B
.buildTrunc(S16
, Copies
[0]);
2047 B
.buildInstr(TargetOpcode::G_FPEXT
, {S32
}, {MIBTrunc
});
2050 B
.buildInstr(TargetOpcode::G_FPEXT
, {S128
}, {Copies
[1]});
2051 AInfo
Info(MF
->getSubtarget());
2052 DummyGISelObserver Observer
;
2053 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
2054 LostDebugLocObserver
DummyLocObserver("");
2055 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2056 Helper
.libcall(*MIBFPExt1
, DummyLocObserver
));
2058 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2059 Helper
.libcall(*MIBFPExt2
, DummyLocObserver
));
2061 CHECK: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC
2062 CHECK: $h0 = COPY [[TRUNC]]
2063 CHECK: BL &__gnu_h2f_ieee
2065 CHECK: BL &__extenddftf2
2069 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
2072 TEST_F(AArch64GISelMITest
, LibcallFPTrunc
) {
2077 // Declare your legalization info
2078 DefineLegalizerInfo(A
, {
2079 getActionDefinitionsBuilder(G_FPTRUNC
).libcallFor({{s16
, s32
}, {s64
, s128
}});
2082 LLT S16
{LLT::scalar(16)};
2083 LLT S32
{LLT::scalar(32)};
2084 LLT S64
{LLT::scalar(64)};
2085 LLT S128
{LLT::scalar(128)};
2086 auto MIBTrunc
= B
.buildTrunc(S32
, Copies
[0]);
2088 B
.buildInstr(TargetOpcode::G_FPTRUNC
, {S16
}, {MIBTrunc
});
2090 auto MIBMerge
= B
.buildMerge(S128
, {Copies
[1], Copies
[2]});
2093 B
.buildInstr(TargetOpcode::G_FPTRUNC
, {S64
}, {MIBMerge
});
2094 AInfo
Info(MF
->getSubtarget());
2095 DummyGISelObserver Observer
;
2096 LostDebugLocObserver
DummyLocObserver("");
2097 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
2098 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2099 Helper
.libcall(*MIBFPTrunc1
, DummyLocObserver
));
2101 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2102 Helper
.libcall(*MIBFPTrunc2
, DummyLocObserver
));
2104 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2105 CHECK: $s0 = COPY [[TRUNC]]
2106 CHECK: BL &__gnu_f2h_ieee
2108 CHECK: BL &__trunctfdf2
2112 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
2115 TEST_F(AArch64GISelMITest
, LibcallSimple
) {
2120 // Declare your legalization info
2121 DefineLegalizerInfo(A
, {
2122 getActionDefinitionsBuilder(G_FADD
).libcallFor({s16
});
2125 LLT S16
{LLT::scalar(16)};
2126 auto MIBTrunc
= B
.buildTrunc(S16
, Copies
[0]);
2128 B
.buildInstr(TargetOpcode::G_FADD
, {S16
}, {MIBTrunc
, MIBTrunc
});
2130 AInfo
Info(MF
->getSubtarget());
2131 DummyGISelObserver Observer
;
2132 LostDebugLocObserver
DummyLocObserver("");
2133 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
2134 // Make sure we do not crash anymore
2135 EXPECT_EQ(LegalizerHelper::LegalizeResult::UnableToLegalize
,
2136 Helper
.libcall(*MIBFADD
, DummyLocObserver
));
2139 TEST_F(AArch64GISelMITest
, LibcallMul
) {
2144 // Declare your legalization info
2145 DefineLegalizerInfo(A
, {
2146 getActionDefinitionsBuilder(G_MUL
).libcallFor({s32
, s64
, s128
});
2149 LLT S32
{LLT::scalar(32)};
2150 LLT S64
{LLT::scalar(64)};
2151 LLT S128
{LLT::scalar(128)};
2152 auto MIBTrunc
= B
.buildTrunc(S32
, Copies
[0]);
2153 auto MIBExt
= B
.buildAnyExt(S128
, Copies
[0]);
2156 B
.buildInstr(TargetOpcode::G_MUL
, {S32
}, {MIBTrunc
, MIBTrunc
});
2158 B
.buildInstr(TargetOpcode::G_MUL
, {S64
}, {Copies
[0], Copies
[0]});
2160 B
.buildInstr(TargetOpcode::G_MUL
, {S128
}, {MIBExt
, MIBExt
});
2162 AInfo
Info(MF
->getSubtarget());
2163 DummyGISelObserver Observer
;
2164 LostDebugLocObserver
DummyLocObserver("");
2165 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
2167 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2168 Helper
.libcall(*MIBMul32
, DummyLocObserver
));
2169 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2170 Helper
.libcall(*MIBMul64
, DummyLocObserver
));
2171 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2172 Helper
.libcall(*MIBMul128
, DummyLocObserver
));
2175 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2176 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2177 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2178 CHECK: $w0 = COPY [[TRUNC]]
2179 CHECK: $w1 = COPY [[TRUNC]]
2181 CHECK: $x0 = COPY [[COPY]]
2182 CHECK: $x1 = COPY [[COPY]]
2184 CHECK: [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[ANYEXT]]
2185 CHECK: [[UV2:%[0-9]+]]:_(s64), [[UV3:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[ANYEXT]]
2186 CHECK: $x0 = COPY [[UV]]
2187 CHECK: $x1 = COPY [[UV1]]
2188 CHECK: $x2 = COPY [[UV2]]
2189 CHECK: $x3 = COPY [[UV3]]
2194 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
2197 TEST_F(AArch64GISelMITest
, LibcallSRem
) {
2202 // Declare your legalization info
2203 DefineLegalizerInfo(A
, {
2204 getActionDefinitionsBuilder(G_SREM
).libcallFor({s32
, s64
, s128
});
2207 LLT S32
{LLT::scalar(32)};
2208 LLT S64
{LLT::scalar(64)};
2209 LLT S128
{LLT::scalar(128)};
2210 auto MIBTrunc
= B
.buildTrunc(S32
, Copies
[0]);
2211 auto MIBExt
= B
.buildAnyExt(S128
, Copies
[0]);
2214 B
.buildInstr(TargetOpcode::G_SREM
, {S32
}, {MIBTrunc
, MIBTrunc
});
2216 B
.buildInstr(TargetOpcode::G_SREM
, {S64
}, {Copies
[0], Copies
[0]});
2218 B
.buildInstr(TargetOpcode::G_SREM
, {S128
}, {MIBExt
, MIBExt
});
2220 AInfo
Info(MF
->getSubtarget());
2221 DummyGISelObserver Observer
;
2222 LostDebugLocObserver
DummyLocObserver("");
2223 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
2225 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2226 Helper
.libcall(*MIBSRem32
, DummyLocObserver
));
2227 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2228 Helper
.libcall(*MIBSRem64
, DummyLocObserver
));
2229 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2230 Helper
.libcall(*MIBSRem128
, DummyLocObserver
));
2233 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2234 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2235 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2236 CHECK: $w0 = COPY [[TRUNC]]
2237 CHECK: $w1 = COPY [[TRUNC]]
2239 CHECK: $x0 = COPY [[COPY]]
2240 CHECK: $x1 = COPY [[COPY]]
2242 CHECK: [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[ANYEXT]]
2243 CHECK: [[UV2:%[0-9]+]]:_(s64), [[UV3:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[ANYEXT]]
2244 CHECK: $x0 = COPY [[UV]]
2245 CHECK: $x1 = COPY [[UV1]]
2246 CHECK: $x2 = COPY [[UV2]]
2247 CHECK: $x3 = COPY [[UV3]]
2252 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
2255 TEST_F(AArch64GISelMITest
, LibcallURem
) {
2260 // Declare your legalization info
2261 DefineLegalizerInfo(A
, {
2262 getActionDefinitionsBuilder(G_UREM
).libcallFor({s32
, s64
, s128
});
2265 LLT S32
{LLT::scalar(32)};
2266 LLT S64
{LLT::scalar(64)};
2267 LLT S128
{LLT::scalar(128)};
2268 auto MIBTrunc
= B
.buildTrunc(S32
, Copies
[0]);
2269 auto MIBExt
= B
.buildAnyExt(S128
, Copies
[0]);
2272 B
.buildInstr(TargetOpcode::G_UREM
, {S32
}, {MIBTrunc
, MIBTrunc
});
2274 B
.buildInstr(TargetOpcode::G_UREM
, {S64
}, {Copies
[0], Copies
[0]});
2276 B
.buildInstr(TargetOpcode::G_UREM
, {S128
}, {MIBExt
, MIBExt
});
2278 AInfo
Info(MF
->getSubtarget());
2279 DummyGISelObserver Observer
;
2280 LostDebugLocObserver
DummyLocObserver("");
2281 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
2283 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2284 Helper
.libcall(*MIBURem32
, DummyLocObserver
));
2285 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2286 Helper
.libcall(*MIBURem64
, DummyLocObserver
));
2287 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2288 Helper
.libcall(*MIBURem128
, DummyLocObserver
));
2290 const auto *CheckStr
= R
"(
2291 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2292 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2293 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2294 CHECK: $w0 = COPY [[TRUNC]]
2295 CHECK: $w1 = COPY [[TRUNC]]
2296 CHECK: BL &__umodsi3
2297 CHECK: $x0 = COPY [[COPY]]
2298 CHECK: $x1 = COPY [[COPY]]
2299 CHECK: BL &__umoddi3
2300 CHECK: [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[ANYEXT]]
2301 CHECK: [[UV2:%[0-9]+]]:_(s64), [[UV3:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[ANYEXT]]
2302 CHECK: $x0 = COPY [[UV]]
2303 CHECK: $x1 = COPY [[UV1]]
2304 CHECK: $x2 = COPY [[UV2]]
2305 CHECK: $x3 = COPY [[UV3]]
2306 CHECK: BL &__umodti3
2310 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
2313 TEST_F(AArch64GISelMITest
, LibcallCtlzZeroUndef
) {
2318 // Declare your legalization info
2319 DefineLegalizerInfo(A
, {
2320 getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF
)
2321 .libcallFor({{s32
, s32
}, {s64
, s64
}, {s128
, s128
}});
2324 LLT S32
{LLT::scalar(32)};
2325 LLT S64
{LLT::scalar(64)};
2326 LLT S128
{LLT::scalar(128)};
2327 auto MIBTrunc
= B
.buildTrunc(S32
, Copies
[0]);
2328 auto MIBExt
= B
.buildAnyExt(S128
, Copies
[0]);
2331 B
.buildInstr(TargetOpcode::G_CTLZ_ZERO_UNDEF
, {S32
}, {MIBTrunc
});
2333 B
.buildInstr(TargetOpcode::G_CTLZ_ZERO_UNDEF
, {S64
}, {Copies
[0]});
2335 B
.buildInstr(TargetOpcode::G_CTLZ_ZERO_UNDEF
, {S128
}, {MIBExt
});
2337 AInfo
Info(MF
->getSubtarget());
2338 DummyGISelObserver Observer
;
2339 LostDebugLocObserver
DummyLocObserver("");
2340 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
2342 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2343 Helper
.libcall(*MIBCtlz32
, DummyLocObserver
));
2344 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2345 Helper
.libcall(*MIBCtlz64
, DummyLocObserver
));
2346 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2347 Helper
.libcall(*MIBCtlz128
, DummyLocObserver
));
2349 const auto *CheckStr
= R
"(
2350 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2351 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2352 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2353 CHECK: $w0 = COPY [[TRUNC]]
2355 CHECK: $x0 = COPY [[COPY]]
2357 CHECK: [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[ANYEXT]]
2358 CHECK: $x0 = COPY [[UV]]
2359 CHECK: $x1 = COPY [[UV1]]
2364 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
2367 TEST_F(AArch64GISelMITest
, LibcallFAdd
) {
2372 // Declare your legalization info
2373 DefineLegalizerInfo(A
, {
2374 getActionDefinitionsBuilder(G_FADD
).libcallFor({s32
, s64
, s128
});
2377 LLT S32
{LLT::scalar(32)};
2378 LLT S64
{LLT::scalar(64)};
2379 LLT S128
{LLT::scalar(128)};
2380 auto MIBTrunc
= B
.buildTrunc(S32
, Copies
[0]);
2381 auto MIBExt
= B
.buildAnyExt(S128
, Copies
[0]);
2384 B
.buildInstr(TargetOpcode::G_FADD
, {S32
}, {MIBTrunc
, MIBTrunc
});
2386 B
.buildInstr(TargetOpcode::G_FADD
, {S64
}, {Copies
[0], Copies
[0]});
2387 auto MIBAdd128
= B
.buildInstr(TargetOpcode::G_FADD
, {S128
}, {MIBExt
, MIBExt
});
2389 AInfo
Info(MF
->getSubtarget());
2390 DummyGISelObserver Observer
;
2391 LostDebugLocObserver
DummyLocObserver("");
2392 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
2394 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2395 Helper
.libcall(*MIBAdd32
, DummyLocObserver
));
2396 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2397 Helper
.libcall(*MIBAdd64
, DummyLocObserver
));
2398 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2399 Helper
.libcall(*MIBAdd128
, DummyLocObserver
));
2401 const auto *CheckStr
= R
"(
2402 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2403 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2404 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2405 CHECK: $s0 = COPY [[TRUNC]]
2406 CHECK: $s1 = COPY [[TRUNC]]
2408 CHECK: $d0 = COPY [[COPY]]
2409 CHECK: $d1 = COPY [[COPY]]
2411 CHECK: $q0 = COPY [[ANYEXT]]
2412 CHECK: $q1 = COPY [[ANYEXT]]
2417 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
2420 TEST_F(AArch64GISelMITest
, LibcallFSub
) {
2425 // Declare your legalization info
2426 DefineLegalizerInfo(A
, {
2427 getActionDefinitionsBuilder(G_FSUB
).libcallFor({s32
, s64
, s128
});
2430 LLT S32
{LLT::scalar(32)};
2431 LLT S64
{LLT::scalar(64)};
2432 LLT S128
{LLT::scalar(128)};
2433 auto MIBTrunc
= B
.buildTrunc(S32
, Copies
[0]);
2434 auto MIBExt
= B
.buildAnyExt(S128
, Copies
[0]);
2437 B
.buildInstr(TargetOpcode::G_FSUB
, {S32
}, {MIBTrunc
, MIBTrunc
});
2439 B
.buildInstr(TargetOpcode::G_FSUB
, {S64
}, {Copies
[0], Copies
[0]});
2440 auto MIBSub128
= B
.buildInstr(TargetOpcode::G_FSUB
, {S128
}, {MIBExt
, MIBExt
});
2442 AInfo
Info(MF
->getSubtarget());
2443 DummyGISelObserver Observer
;
2444 LostDebugLocObserver
DummyLocObserver("");
2445 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
2447 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2448 Helper
.libcall(*MIBSub32
, DummyLocObserver
));
2449 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2450 Helper
.libcall(*MIBSub64
, DummyLocObserver
));
2451 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2452 Helper
.libcall(*MIBSub128
, DummyLocObserver
));
2454 const auto *CheckStr
= R
"(
2455 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2456 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2457 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2458 CHECK: $s0 = COPY [[TRUNC]]
2459 CHECK: $s1 = COPY [[TRUNC]]
2461 CHECK: $d0 = COPY [[COPY]]
2462 CHECK: $d1 = COPY [[COPY]]
2464 CHECK: $q0 = COPY [[ANYEXT]]
2465 CHECK: $q1 = COPY [[ANYEXT]]
2470 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
2473 TEST_F(AArch64GISelMITest
, LibcallFMul
) {
2478 // Declare your legalization info
2479 DefineLegalizerInfo(A
, {
2480 getActionDefinitionsBuilder(G_FMUL
).libcallFor({s32
, s64
, s128
});
2483 LLT S32
{LLT::scalar(32)};
2484 LLT S64
{LLT::scalar(64)};
2485 LLT S128
{LLT::scalar(128)};
2486 auto MIBTrunc
= B
.buildTrunc(S32
, Copies
[0]);
2487 auto MIBExt
= B
.buildAnyExt(S128
, Copies
[0]);
2490 B
.buildInstr(TargetOpcode::G_FMUL
, {S32
}, {MIBTrunc
, MIBTrunc
});
2492 B
.buildInstr(TargetOpcode::G_FMUL
, {S64
}, {Copies
[0], Copies
[0]});
2493 auto MIBMul128
= B
.buildInstr(TargetOpcode::G_FMUL
, {S128
}, {MIBExt
, MIBExt
});
2495 AInfo
Info(MF
->getSubtarget());
2496 DummyGISelObserver Observer
;
2497 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
2498 LostDebugLocObserver
DummyLocObserver("");
2500 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2501 Helper
.libcall(*MIBMul32
, DummyLocObserver
));
2502 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2503 Helper
.libcall(*MIBMul64
, DummyLocObserver
));
2504 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2505 Helper
.libcall(*MIBMul128
, DummyLocObserver
));
2507 const auto *CheckStr
= R
"(
2508 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2509 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2510 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2511 CHECK: $s0 = COPY [[TRUNC]]
2512 CHECK: $s1 = COPY [[TRUNC]]
2514 CHECK: $d0 = COPY [[COPY]]
2515 CHECK: $d1 = COPY [[COPY]]
2517 CHECK: $q0 = COPY [[ANYEXT]]
2518 CHECK: $q1 = COPY [[ANYEXT]]
2523 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
2526 TEST_F(AArch64GISelMITest
, LibcallFDiv
) {
2531 // Declare your legalization info
2532 DefineLegalizerInfo(A
, {
2533 getActionDefinitionsBuilder(G_FDIV
).libcallFor({s32
, s64
, s128
});
2536 LLT S32
{LLT::scalar(32)};
2537 LLT S64
{LLT::scalar(64)};
2538 LLT S128
{LLT::scalar(128)};
2539 auto MIBTrunc
= B
.buildTrunc(S32
, Copies
[0]);
2540 auto MIBExt
= B
.buildAnyExt(S128
, Copies
[0]);
2543 B
.buildInstr(TargetOpcode::G_FDIV
, {S32
}, {MIBTrunc
, MIBTrunc
});
2545 B
.buildInstr(TargetOpcode::G_FDIV
, {S64
}, {Copies
[0], Copies
[0]});
2546 auto MIBDiv128
= B
.buildInstr(TargetOpcode::G_FDIV
, {S128
}, {MIBExt
, MIBExt
});
2548 AInfo
Info(MF
->getSubtarget());
2549 DummyGISelObserver Observer
;
2550 LostDebugLocObserver
DummyLocObserver("");
2551 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
2553 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2554 Helper
.libcall(*MIBDiv32
, DummyLocObserver
));
2555 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2556 Helper
.libcall(*MIBDiv64
, DummyLocObserver
));
2557 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2558 Helper
.libcall(*MIBDiv128
, DummyLocObserver
));
2560 const auto *CheckStr
= R
"(
2561 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2562 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2563 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2564 CHECK: $s0 = COPY [[TRUNC]]
2565 CHECK: $s1 = COPY [[TRUNC]]
2567 CHECK: $d0 = COPY [[COPY]]
2568 CHECK: $d1 = COPY [[COPY]]
2570 CHECK: $q0 = COPY [[ANYEXT]]
2571 CHECK: $q1 = COPY [[ANYEXT]]
2576 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
2579 TEST_F(AArch64GISelMITest
, LibcallFExp
) {
2584 // Declare your legalization info
2585 DefineLegalizerInfo(A
, {
2586 getActionDefinitionsBuilder(G_FEXP
).libcallFor({s32
, s64
, s128
});
2589 LLT S32
{LLT::scalar(32)};
2590 LLT S64
{LLT::scalar(64)};
2591 LLT S128
{LLT::scalar(128)};
2592 auto MIBTrunc
= B
.buildTrunc(S32
, Copies
[0]);
2593 auto MIBExt
= B
.buildAnyExt(S128
, Copies
[0]);
2595 auto MIBExp32
= B
.buildInstr(TargetOpcode::G_FEXP
, {S32
}, {MIBTrunc
});
2596 auto MIBExp64
= B
.buildInstr(TargetOpcode::G_FEXP
, {S64
}, {Copies
[0]});
2597 auto MIBExp128
= B
.buildInstr(TargetOpcode::G_FEXP
, {S128
}, {MIBExt
});
2599 AInfo
Info(MF
->getSubtarget());
2600 DummyGISelObserver Observer
;
2601 LostDebugLocObserver
DummyLocObserver("");
2602 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
2604 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2605 Helper
.libcall(*MIBExp32
, DummyLocObserver
));
2606 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2607 Helper
.libcall(*MIBExp64
, DummyLocObserver
));
2608 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2609 Helper
.libcall(*MIBExp128
, DummyLocObserver
));
2611 const auto *CheckStr
= R
"(
2612 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2613 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2614 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2615 CHECK: $s0 = COPY [[TRUNC]]
2617 CHECK: $d0 = COPY [[COPY]]
2619 CHECK: $q0 = COPY [[ANYEXT]]
2624 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
2627 TEST_F(AArch64GISelMITest
, LibcallFExp2
) {
2632 // Declare your legalization info
2633 DefineLegalizerInfo(A
, {
2634 getActionDefinitionsBuilder(G_FEXP2
).libcallFor({s32
, s64
, s128
});
2637 LLT S32
{LLT::scalar(32)};
2638 LLT S64
{LLT::scalar(64)};
2639 LLT S128
{LLT::scalar(128)};
2640 auto MIBTrunc
= B
.buildTrunc(S32
, Copies
[0]);
2641 auto MIBExt
= B
.buildAnyExt(S128
, Copies
[0]);
2643 auto MIBExp232
= B
.buildInstr(TargetOpcode::G_FEXP2
, {S32
}, {MIBTrunc
});
2644 auto MIBExp264
= B
.buildInstr(TargetOpcode::G_FEXP2
, {S64
}, {Copies
[0]});
2645 auto MIBExp2128
= B
.buildInstr(TargetOpcode::G_FEXP2
, {S128
}, {MIBExt
});
2647 AInfo
Info(MF
->getSubtarget());
2648 DummyGISelObserver Observer
;
2649 LostDebugLocObserver
DummyLocObserver("");
2650 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
2652 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2653 Helper
.libcall(*MIBExp232
, DummyLocObserver
));
2654 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2655 Helper
.libcall(*MIBExp264
, DummyLocObserver
));
2656 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2657 Helper
.libcall(*MIBExp2128
, DummyLocObserver
));
2659 const auto *CheckStr
= R
"(
2660 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2661 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2662 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2663 CHECK: $s0 = COPY [[TRUNC]]
2665 CHECK: $d0 = COPY [[COPY]]
2667 CHECK: $q0 = COPY [[ANYEXT]]
2672 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
2675 TEST_F(AArch64GISelMITest
, LibcallFRem
) {
2680 // Declare your legalization info
2681 DefineLegalizerInfo(A
, {
2682 getActionDefinitionsBuilder(G_FREM
).libcallFor({s32
, s64
, s128
});
2685 LLT S32
{LLT::scalar(32)};
2686 LLT S64
{LLT::scalar(64)};
2687 LLT S128
{LLT::scalar(128)};
2688 auto MIBTrunc
= B
.buildTrunc(S32
, Copies
[0]);
2689 auto MIBExt
= B
.buildAnyExt(S128
, Copies
[0]);
2691 auto MIBFRem32
= B
.buildInstr(TargetOpcode::G_FREM
, {S32
}, {MIBTrunc
});
2692 auto MIBFRem64
= B
.buildInstr(TargetOpcode::G_FREM
, {S64
}, {Copies
[0]});
2693 auto MIBFRem128
= B
.buildInstr(TargetOpcode::G_FREM
, {S128
}, {MIBExt
});
2695 AInfo
Info(MF
->getSubtarget());
2696 DummyGISelObserver Observer
;
2697 LostDebugLocObserver
DummyLocObserver("");
2698 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
2700 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2701 Helper
.libcall(*MIBFRem32
, DummyLocObserver
));
2702 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2703 Helper
.libcall(*MIBFRem64
, DummyLocObserver
));
2704 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2705 Helper
.libcall(*MIBFRem128
, DummyLocObserver
));
2707 const auto *CheckStr
= R
"(
2708 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2709 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2710 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2711 CHECK: $s0 = COPY [[TRUNC]]
2713 CHECK: $d0 = COPY [[COPY]]
2715 CHECK: $q0 = COPY [[ANYEXT]]
2720 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
2723 TEST_F(AArch64GISelMITest
, LibcallFPow
) {
2728 // Declare your legalization info
2729 DefineLegalizerInfo(A
, {
2730 getActionDefinitionsBuilder(G_FPOW
).libcallFor({s32
, s64
, s128
});
2733 LLT S32
{LLT::scalar(32)};
2734 LLT S64
{LLT::scalar(64)};
2735 LLT S128
{LLT::scalar(128)};
2736 auto MIBTrunc
= B
.buildTrunc(S32
, Copies
[0]);
2737 auto MIBExt
= B
.buildAnyExt(S128
, Copies
[0]);
2739 auto MIBPow32
= B
.buildInstr(TargetOpcode::G_FPOW
, {S32
}, {MIBTrunc
});
2740 auto MIBPow64
= B
.buildInstr(TargetOpcode::G_FPOW
, {S64
}, {Copies
[0]});
2741 auto MIBPow128
= B
.buildInstr(TargetOpcode::G_FPOW
, {S128
}, {MIBExt
});
2743 AInfo
Info(MF
->getSubtarget());
2744 DummyGISelObserver Observer
;
2745 LostDebugLocObserver
DummyLocObserver("");
2746 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
2748 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2749 Helper
.libcall(*MIBPow32
, DummyLocObserver
));
2750 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2751 Helper
.libcall(*MIBPow64
, DummyLocObserver
));
2752 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2753 Helper
.libcall(*MIBPow128
, DummyLocObserver
));
2755 const auto *CheckStr
= R
"(
2756 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2757 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2758 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2759 CHECK: $s0 = COPY [[TRUNC]]
2761 CHECK: $d0 = COPY [[COPY]]
2763 CHECK: $q0 = COPY [[ANYEXT]]
2768 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
2771 TEST_F(AArch64GISelMITest
, LibcallFMa
) {
2776 // Declare your legalization info
2777 DefineLegalizerInfo(A
, {
2778 getActionDefinitionsBuilder(G_FMA
).libcallFor({s32
, s64
, s128
});
2781 LLT S32
{LLT::scalar(32)};
2782 LLT S64
{LLT::scalar(64)};
2783 LLT S128
{LLT::scalar(128)};
2784 auto MIBTrunc
= B
.buildTrunc(S32
, Copies
[0]);
2785 auto MIBExt
= B
.buildAnyExt(S128
, Copies
[0]);
2787 auto MIBMa32
= B
.buildInstr(TargetOpcode::G_FMA
, {S32
}, {MIBTrunc
, MIBTrunc
});
2789 B
.buildInstr(TargetOpcode::G_FMA
, {S64
}, {Copies
[0], Copies
[0]});
2790 auto MIBMa128
= B
.buildInstr(TargetOpcode::G_FMA
, {S128
}, {MIBExt
, MIBExt
});
2792 AInfo
Info(MF
->getSubtarget());
2793 DummyGISelObserver Observer
;
2794 LostDebugLocObserver
DummyLocObserver("");
2795 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
2797 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2798 Helper
.libcall(*MIBMa32
, DummyLocObserver
));
2799 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2800 Helper
.libcall(*MIBMa64
, DummyLocObserver
));
2801 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2802 Helper
.libcall(*MIBMa128
, DummyLocObserver
));
2804 const auto *CheckStr
= R
"(
2805 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2806 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2807 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2808 CHECK: $s0 = COPY [[TRUNC]]
2810 CHECK: $d0 = COPY [[COPY]]
2812 CHECK: $q0 = COPY [[ANYEXT]]
2817 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
2820 TEST_F(AArch64GISelMITest
, LibcallFCeil
) {
2825 // Declare your legalization info
2826 DefineLegalizerInfo(A
, {
2827 getActionDefinitionsBuilder(G_FCEIL
).libcallFor({s32
, s64
, s128
});
2830 LLT S32
{LLT::scalar(32)};
2831 LLT S64
{LLT::scalar(64)};
2832 LLT S128
{LLT::scalar(128)};
2833 auto MIBTrunc
= B
.buildTrunc(S32
, Copies
[0]);
2834 auto MIBExt
= B
.buildAnyExt(S128
, Copies
[0]);
2836 auto MIBCeil32
= B
.buildInstr(TargetOpcode::G_FCEIL
, {S32
}, {MIBTrunc
});
2837 auto MIBCeil64
= B
.buildInstr(TargetOpcode::G_FCEIL
, {S64
}, {Copies
[0]});
2838 auto MIBCeil128
= B
.buildInstr(TargetOpcode::G_FCEIL
, {S128
}, {MIBExt
});
2840 AInfo
Info(MF
->getSubtarget());
2841 DummyGISelObserver Observer
;
2842 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
2843 LostDebugLocObserver
DummyLocObserver("");
2845 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2846 Helper
.libcall(*MIBCeil32
, DummyLocObserver
));
2847 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2848 Helper
.libcall(*MIBCeil64
, DummyLocObserver
));
2849 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2850 Helper
.libcall(*MIBCeil128
, DummyLocObserver
));
2852 const auto *CheckStr
= R
"(
2853 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2854 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2855 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2856 CHECK: $s0 = COPY [[TRUNC]]
2858 CHECK: $d0 = COPY [[COPY]]
2860 CHECK: $q0 = COPY [[ANYEXT]]
2865 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
2868 TEST_F(AArch64GISelMITest
, LibcallFFloor
) {
2873 // Declare your legalization info
2874 DefineLegalizerInfo(A
, {
2875 getActionDefinitionsBuilder(G_FFLOOR
).libcallFor({s32
, s64
, s128
});
2878 LLT S32
{LLT::scalar(32)};
2879 LLT S64
{LLT::scalar(64)};
2880 LLT S128
{LLT::scalar(128)};
2881 auto MIBTrunc
= B
.buildTrunc(S32
, Copies
[0]);
2882 auto MIBExt
= B
.buildAnyExt(S128
, Copies
[0]);
2884 auto MIBFloor32
= B
.buildInstr(TargetOpcode::G_FFLOOR
, {S32
}, {MIBTrunc
});
2885 auto MIBFloor64
= B
.buildInstr(TargetOpcode::G_FFLOOR
, {S64
}, {Copies
[0]});
2886 auto MIBFloor128
= B
.buildInstr(TargetOpcode::G_FFLOOR
, {S128
}, {MIBExt
});
2888 AInfo
Info(MF
->getSubtarget());
2889 DummyGISelObserver Observer
;
2890 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
2891 LostDebugLocObserver
DummyLocObserver("");
2893 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2894 Helper
.libcall(*MIBFloor32
, DummyLocObserver
));
2895 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2896 Helper
.libcall(*MIBFloor64
, DummyLocObserver
));
2897 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2898 Helper
.libcall(*MIBFloor128
, DummyLocObserver
));
2900 const auto *CheckStr
= R
"(
2901 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2902 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2903 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2904 CHECK: $s0 = COPY [[TRUNC]]
2906 CHECK: $d0 = COPY [[COPY]]
2908 CHECK: $q0 = COPY [[ANYEXT]]
2913 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
2916 TEST_F(AArch64GISelMITest
, LibcallFMinNum
) {
2921 // Declare your legalization info
2922 DefineLegalizerInfo(A
, {
2923 getActionDefinitionsBuilder(G_FMINNUM
).libcallFor({s32
, s64
, s128
});
2926 LLT S32
{LLT::scalar(32)};
2927 LLT S64
{LLT::scalar(64)};
2928 LLT S128
{LLT::scalar(128)};
2929 auto MIBTrunc
= B
.buildTrunc(S32
, Copies
[0]);
2930 auto MIBExt
= B
.buildAnyExt(S128
, Copies
[0]);
2932 auto MIBMin32
= B
.buildFMinNum(S32
, MIBTrunc
, MIBTrunc
);
2933 auto MIBMin64
= B
.buildFMinNum(S64
, Copies
[0], Copies
[0]);
2934 auto MIBMin128
= B
.buildFMinNum(S128
, MIBExt
, MIBExt
);
2936 AInfo
Info(MF
->getSubtarget());
2937 DummyGISelObserver Observer
;
2938 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
2939 LostDebugLocObserver
DummyLocObserver("");
2941 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2942 Helper
.libcall(*MIBMin32
, DummyLocObserver
));
2943 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2944 Helper
.libcall(*MIBMin64
, DummyLocObserver
));
2945 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2946 Helper
.libcall(*MIBMin128
, DummyLocObserver
));
2948 const auto *CheckStr
= R
"(
2949 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
2950 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
2951 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
2952 CHECK: $s0 = COPY [[TRUNC]]
2953 CHECK: $s1 = COPY [[TRUNC]]
2955 CHECK: $d0 = COPY [[COPY]]
2956 CHECK: $d1 = COPY [[COPY]]
2958 CHECK: $q0 = COPY [[ANYEXT]]
2959 CHECK: $q1 = COPY [[ANYEXT]]
2964 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
2967 TEST_F(AArch64GISelMITest
, LibcallFMaxNum
) {
2972 // Declare your legalization info
2973 DefineLegalizerInfo(A
, {
2974 getActionDefinitionsBuilder(G_FMAXNUM
).libcallFor({s32
, s64
, s128
});
2977 LLT S32
{LLT::scalar(32)};
2978 LLT S64
{LLT::scalar(64)};
2979 LLT S128
{LLT::scalar(128)};
2980 auto MIBTrunc
= B
.buildTrunc(S32
, Copies
[0]);
2981 auto MIBExt
= B
.buildAnyExt(S128
, Copies
[0]);
2983 auto MIBMax32
= B
.buildFMaxNum(S32
, MIBTrunc
, MIBTrunc
);
2984 auto MIBMax64
= B
.buildFMaxNum(S64
, Copies
[0], Copies
[0]);
2985 auto MIBMax128
= B
.buildFMaxNum(S128
, MIBExt
, MIBExt
);
2987 AInfo
Info(MF
->getSubtarget());
2988 DummyGISelObserver Observer
;
2989 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
2990 LostDebugLocObserver
DummyLocObserver("");
2992 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2993 Helper
.libcall(*MIBMax32
, DummyLocObserver
));
2994 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2995 Helper
.libcall(*MIBMax64
, DummyLocObserver
));
2996 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
2997 Helper
.libcall(*MIBMax128
, DummyLocObserver
));
2999 const auto *CheckStr
= R
"(
3000 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
3001 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
3002 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
3003 CHECK: $s0 = COPY [[TRUNC]]
3004 CHECK: $s1 = COPY [[TRUNC]]
3006 CHECK: $d0 = COPY [[COPY]]
3007 CHECK: $d1 = COPY [[COPY]]
3009 CHECK: $q0 = COPY [[ANYEXT]]
3010 CHECK: $q1 = COPY [[ANYEXT]]
3015 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
3018 TEST_F(AArch64GISelMITest
, LibcallFSqrt
) {
3023 // Declare your legalization info
3024 DefineLegalizerInfo(A
, {
3025 getActionDefinitionsBuilder(G_FSQRT
).libcallFor({s32
, s64
, s128
});
3028 LLT S32
{LLT::scalar(32)};
3029 LLT S64
{LLT::scalar(64)};
3030 LLT S128
{LLT::scalar(128)};
3031 auto MIBTrunc
= B
.buildTrunc(S32
, Copies
[0]);
3032 auto MIBExt
= B
.buildAnyExt(S128
, Copies
[0]);
3034 auto MIBSqrt32
= B
.buildInstr(TargetOpcode::G_FSQRT
, {S32
}, {MIBTrunc
});
3035 auto MIBSqrt64
= B
.buildInstr(TargetOpcode::G_FSQRT
, {S64
}, {Copies
[0]});
3036 auto MIBSqrt128
= B
.buildInstr(TargetOpcode::G_FSQRT
, {S128
}, {MIBExt
});
3038 AInfo
Info(MF
->getSubtarget());
3039 DummyGISelObserver Observer
;
3040 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
3041 LostDebugLocObserver
DummyLocObserver("");
3043 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
3044 Helper
.libcall(*MIBSqrt32
, DummyLocObserver
));
3045 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
3046 Helper
.libcall(*MIBSqrt64
, DummyLocObserver
));
3047 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
3048 Helper
.libcall(*MIBSqrt128
, DummyLocObserver
));
3050 const auto *CheckStr
= R
"(
3051 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
3052 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
3053 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
3054 CHECK: $s0 = COPY [[TRUNC]]
3056 CHECK: $d0 = COPY [[COPY]]
3058 CHECK: $q0 = COPY [[ANYEXT]]
3063 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
3066 TEST_F(AArch64GISelMITest
, LibcallFRint
) {
3071 // Declare your legalization info
3072 DefineLegalizerInfo(A
, {
3073 getActionDefinitionsBuilder(G_FRINT
).libcallFor({s32
, s64
, s128
});
3076 LLT S32
{LLT::scalar(32)};
3077 LLT S64
{LLT::scalar(64)};
3078 LLT S128
{LLT::scalar(128)};
3079 auto MIBTrunc
= B
.buildTrunc(S32
, Copies
[0]);
3080 auto MIBExt
= B
.buildAnyExt(S128
, Copies
[0]);
3082 auto MIBRint32
= B
.buildInstr(TargetOpcode::G_FRINT
, {S32
}, {MIBTrunc
});
3083 auto MIBRint64
= B
.buildInstr(TargetOpcode::G_FRINT
, {S64
}, {Copies
[0]});
3084 auto MIBRint128
= B
.buildInstr(TargetOpcode::G_FRINT
, {S128
}, {MIBExt
});
3086 AInfo
Info(MF
->getSubtarget());
3087 DummyGISelObserver Observer
;
3088 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
3089 LostDebugLocObserver
DummyLocObserver("");
3091 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
3092 Helper
.libcall(*MIBRint32
, DummyLocObserver
));
3093 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
3094 Helper
.libcall(*MIBRint64
, DummyLocObserver
));
3095 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
3096 Helper
.libcall(*MIBRint128
, DummyLocObserver
));
3098 const auto *CheckStr
= R
"(
3099 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
3100 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
3101 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
3102 CHECK: $s0 = COPY [[TRUNC]]
3104 CHECK: $d0 = COPY [[COPY]]
3106 CHECK: $q0 = COPY [[ANYEXT]]
3111 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
3114 TEST_F(AArch64GISelMITest
, LibcallFNearbyInt
) {
3119 // Declare your legalization info
3120 DefineLegalizerInfo(A
, {
3121 getActionDefinitionsBuilder(G_FNEARBYINT
).libcallFor({s32
, s64
, s128
});
3124 LLT S32
{LLT::scalar(32)};
3125 LLT S64
{LLT::scalar(64)};
3126 LLT S128
{LLT::scalar(128)};
3127 auto MIBTrunc
= B
.buildTrunc(S32
, Copies
[0]);
3128 auto MIBExt
= B
.buildAnyExt(S128
, Copies
[0]);
3130 auto MIBNearbyInt32
=
3131 B
.buildInstr(TargetOpcode::G_FNEARBYINT
, {S32
}, {MIBTrunc
});
3132 auto MIBNearbyInt64
=
3133 B
.buildInstr(TargetOpcode::G_FNEARBYINT
, {S64
}, {Copies
[0]});
3134 auto MIBNearbyInt128
=
3135 B
.buildInstr(TargetOpcode::G_FNEARBYINT
, {S128
}, {MIBExt
});
3137 AInfo
Info(MF
->getSubtarget());
3138 DummyGISelObserver Observer
;
3139 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
3140 LostDebugLocObserver
DummyLocObserver("");
3142 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
3143 Helper
.libcall(*MIBNearbyInt32
, DummyLocObserver
));
3144 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
3145 Helper
.libcall(*MIBNearbyInt64
, DummyLocObserver
));
3146 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
3147 Helper
.libcall(*MIBNearbyInt128
, DummyLocObserver
));
3149 const auto *CheckStr
= R
"(
3150 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
3151 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC
3152 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT
3153 CHECK: $s0 = COPY [[TRUNC]]
3154 CHECK: BL &nearbyintf
3155 CHECK: $d0 = COPY [[COPY]]
3156 CHECK: BL &nearbyint
3157 CHECK: $q0 = COPY [[ANYEXT]]
3158 CHECK: BL &nearbyintl
3162 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
3165 TEST_F(AArch64GISelMITest
, NarrowScalarExtract
) {
3170 // Declare your legalization info
3171 DefineLegalizerInfo(A
, {
3172 getActionDefinitionsBuilder(G_UNMERGE_VALUES
).legalFor({{s32
, s64
}});
3173 getActionDefinitionsBuilder(G_EXTRACT
).legalForTypeWithAnyImm({{s16
, s32
}});
3176 LLT S16
{LLT::scalar(16)};
3177 LLT S32
{LLT::scalar(32)};
3179 auto MIBExtractS32
= B
.buildExtract(S32
, Copies
[1], 32);
3180 auto MIBExtractS16
= B
.buildExtract(S16
, Copies
[1], 0);
3182 AInfo
Info(MF
->getSubtarget());
3183 DummyGISelObserver Observer
;
3184 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
3186 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
3187 Helper
.narrowScalar(*MIBExtractS32
, 1, S32
));
3189 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
3190 Helper
.narrowScalar(*MIBExtractS16
, 1, S32
));
3192 const auto *CheckStr
= R
"(
3193 CHECK: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES
3194 CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY [[UV1]]
3195 CHECK: [[UV3:%[0-9]+]]:_(s32), [[UV4:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES
3196 CHECK: [[EXTR:%[0-9]+]]:_(s16) = G_EXTRACT [[UV3]]:_(s32), 0
3197 CHECK: [[COPY:%[0-9]+]]:_(s16) = COPY [[EXTR]]
3201 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
3204 TEST_F(AArch64GISelMITest
, LowerInsert
) {
3209 // Declare your legalization info
3210 DefineLegalizerInfo(A
, { getActionDefinitionsBuilder(G_INSERT
).lower(); });
3212 LLT S32
{LLT::scalar(32)};
3213 LLT S64
{LLT::scalar(64)};
3214 LLT P0
{LLT::pointer(0, 64)};
3215 LLT P1
{LLT::pointer(1, 32)};
3216 LLT V2S32
{LLT::fixed_vector(2, 32)};
3218 auto TruncS32
= B
.buildTrunc(S32
, Copies
[0]);
3219 auto IntToPtrP0
= B
.buildIntToPtr(P0
, Copies
[0]);
3220 auto IntToPtrP1
= B
.buildIntToPtr(P1
, TruncS32
);
3221 auto BitcastV2S32
= B
.buildBitcast(V2S32
, Copies
[0]);
3223 auto InsertS64S32
= B
.buildInsert(S64
, Copies
[0], TruncS32
, 0);
3224 auto InsertS64P1
= B
.buildInsert(S64
, Copies
[0], IntToPtrP1
, 8);
3225 auto InsertP0S32
= B
.buildInsert(P0
, IntToPtrP0
, TruncS32
, 16);
3226 auto InsertP0P1
= B
.buildInsert(P0
, IntToPtrP0
, IntToPtrP1
, 4);
3227 auto InsertV2S32S32
= B
.buildInsert(V2S32
, BitcastV2S32
, TruncS32
, 32);
3228 auto InsertV2S32P1
= B
.buildInsert(V2S32
, BitcastV2S32
, IntToPtrP1
, 0);
3230 AInfo
Info(MF
->getSubtarget());
3231 DummyGISelObserver Observer
;
3232 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
3234 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
3235 Helper
.lower(*InsertS64S32
, 0, LLT
{}));
3237 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
3238 Helper
.lower(*InsertS64P1
, 0, LLT
{}));
3240 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
3241 Helper
.lower(*InsertP0S32
, 0, LLT
{}));
3243 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
3244 Helper
.lower(*InsertP0P1
, 0, LLT
{}));
3246 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
3247 Helper
.lower(*InsertV2S32S32
, 0, LLT
{}));
3249 EXPECT_EQ(LegalizerHelper::LegalizeResult::UnableToLegalize
,
3250 Helper
.lower(*InsertV2S32P1
, 0, LLT
{}));
3252 const auto *CheckStr
= R
"(
3253 CHECK: [[S64:%[0-9]+]]:_(s64) = COPY
3254 CHECK: [[S32:%[0-9]+]]:_(s32) = G_TRUNC [[S64]]
3255 CHECK: [[P0:%[0-9]+]]:_(p0) = G_INTTOPTR [[S64]]
3256 CHECK: [[P1:%[0-9]+]]:_(p1) = G_INTTOPTR [[S32]]
3257 CHECK: [[V2S32:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[S64]]
3258 CHECK: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[S32]]
3259 CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT
3260 CHECK: [[AND:%[0-9]+]]:_(s64) = G_AND [[S64]]:_, [[C]]:_
3261 CHECK: [[OR:%[0-9]+]]:_(s64) = G_OR [[AND]]:_, [[ZEXT]]:_
3263 CHECK: [[PTRTOINT:%[0-9]+]]:_(s32) = G_PTRTOINT [[P1]]
3264 CHECK: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[PTRTOINT]]
3265 CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT
3266 CHECK: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ZEXT]]:_, [[C]]:_(s64)
3267 CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT
3268 CHECK: [[AND:%[0-9]+]]:_(s64) = G_AND [[S64]]:_, [[C]]:_
3269 CHECK: [[OR:%[0-9]+]]:_(s64) = G_OR [[AND]]:_, [[SHL]]:_
3271 CHECK: [[PTRTOINT:%[0-9]+]]:_(s64) = G_PTRTOINT [[P0]]
3272 CHECK: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[S32]]
3273 CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT
3274 CHECK: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ZEXT]]:_, [[C]]:_(s64)
3275 CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT
3276 CHECK: [[AND:%[0-9]+]]:_(s64) = G_AND [[PTRTOINT]]:_, [[C]]:_
3277 CHECK: [[OR:%[0-9]+]]:_(s64) = G_OR [[AND]]:_, [[SHL]]:_
3278 CHECK: [[INTTOPTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[OR]]
3280 CHECK: [[PTRTOINT:%[0-9]+]]:_(s64) = G_PTRTOINT [[P0]]
3281 CHECK: [[PTRTOINT1:%[0-9]+]]:_(s32) = G_PTRTOINT [[P1]]
3282 CHECK: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[PTRTOINT1]]
3283 CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT
3284 CHECK: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ZEXT]]:_, [[C]]:_(s64)
3285 CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT
3286 CHECK: [[AND:%[0-9]+]]:_(s64) = G_AND [[PTRTOINT]]:_, [[C]]:_
3287 CHECK: [[OR:%[0-9]+]]:_(s64) = G_OR [[AND]]:_, [[SHL]]:_
3288 CHECK: [[INTTOPTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[OR]]
3290 CHECK: [[V2S32_E0:%[0-9]+]]:_(s32), [[V2S32_E1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[V2S32]]
3291 CHECK: [[BV:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[V2S32_E0]]:_(s32), [[S32]]:_(s32)
3295 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
3298 // Test lowering of G_FFLOOR
3299 TEST_F(AArch64GISelMITest
, LowerFFloor
) {
3304 // Declare your legalization info
3305 DefineLegalizerInfo(A
, {});
3307 auto Floor
= B
.buildFFloor(LLT::scalar(64), Copies
[0], MachineInstr::MIFlag::FmNoInfs
);
3308 AInfo
Info(MF
->getSubtarget());
3309 DummyGISelObserver Observer
;
3310 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
3311 // Perform Legalization
3312 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
3313 Helper
.lower(*Floor
, 0, LLT()));
3316 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
3317 CHECK: [[TRUNC:%[0-9]+]]:_(s64) = ninf G_INTRINSIC_TRUNC [[COPY]]
3318 CHECK: [[ZERO:%[0-9]+]]:_(s64) = G_FCONSTANT double 0.000000e+00
3319 CHECK: [[CMP0:%[0-9]+]]:_(s1) = ninf G_FCMP floatpred(olt), [[COPY]]:_(s64), [[ZERO]]:_
3320 CHECK: [[CMP1:%[0-9]+]]:_(s1) = ninf G_FCMP floatpred(one), [[COPY]]:_(s64), [[TRUNC]]:_
3321 CHECK: [[AND:%[0-9]+]]:_(s1) = G_AND [[CMP0]]:_, [[CMP1]]:_
3322 CHECK: [[ITOFP:%[0-9]+]]:_(s64) = G_SITOFP [[AND]]
3323 = ninf G_FADD [[TRUNC]]:_, [[ITOFP]]:_
3327 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
3330 // Test lowering of G_BSWAP
3331 TEST_F(AArch64GISelMITest
, LowerBSWAP
) {
3336 DefineLegalizerInfo(A
, {});
3338 // Make sure vector lowering doesn't assert.
3339 auto Cast
= B
.buildBitcast(LLT::fixed_vector(2, 32), Copies
[0]);
3340 auto BSwap
= B
.buildBSwap(LLT::fixed_vector(2, 32), Cast
);
3341 AInfo
Info(MF
->getSubtarget());
3342 DummyGISelObserver Observer
;
3343 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
3344 // Perform Legalization
3345 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
3346 Helper
.lower(*BSwap
, 0, LLT()));
3349 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
3350 CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[COPY]]
3351 CHECK: [[K24:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
3352 CHECK: [[SPLAT24:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[K24]]:_(s32), [[K24]]:_(s32)
3353 CHECK: [[SHL0:%[0-9]+]]:_(<2 x s32>) = G_SHL [[VEC]]:_, [[SPLAT24]]
3354 CHECK: [[SHR0:%[0-9]+]]:_(<2 x s32>) = G_LSHR [[VEC]]:_, [[SPLAT24]]
3355 CHECK: [[OR0:%[0-9]+]]:_(<2 x s32>) = G_OR [[SHR0]]:_, [[SHL0]]:_
3356 CHECK: [[KMASK:%[0-9]+]]:_(s32) = G_CONSTANT i32 65280
3357 CHECK: [[SPLATMASK:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[KMASK]]:_(s32), [[KMASK]]:_(s32)
3358 CHECK: [[K8:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
3359 CHECK: [[SPLAT8:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[K8]]:_(s32), [[K8]]:_(s32)
3360 CHECK: [[AND0:%[0-9]+]]:_(<2 x s32>) = G_AND [[VEC]]:_, [[SPLATMASK]]:_
3361 CHECK: [[SHL1:%[0-9]+]]:_(<2 x s32>) = G_SHL [[AND0]]:_, [[SPLAT8]]
3362 CHECK: [[OR1:%[0-9]+]]:_(<2 x s32>) = G_OR [[OR0]]:_, [[SHL1]]:_
3363 CHECK: [[SHR1:%[0-9]+]]:_(<2 x s32>) = G_LSHR [[VEC]]:_, [[SPLAT8]]
3364 CHECK: [[AND1:%[0-9]+]]:_(<2 x s32>) = G_AND [[SHR1]]:_, [[SPLATMASK]]:_
3365 CHECK: [[BSWAP:%[0-9]+]]:_(<2 x s32>) = G_OR [[OR1]]:_, [[AND1]]:_
3369 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
3372 // Test lowering of G_SDIVREM into G_SDIV and G_SREM
3373 TEST_F(AArch64GISelMITest
, LowerSDIVREM
) {
3378 // Declare your legalization info
3379 DefineLegalizerInfo(
3380 A
, { getActionDefinitionsBuilder(G_SDIVREM
).lowerFor({s64
}); });
3382 LLT S64
{LLT::scalar(64)};
3386 B
.buildInstr(TargetOpcode::G_SDIVREM
, {S64
, S64
}, {Copies
[0], Copies
[1]});
3387 AInfo
Info(MF
->getSubtarget());
3388 DummyGISelObserver Observer
;
3389 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
3390 // Perform Legalization
3391 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
3392 Helper
.lower(*SDivrem
, 0, S64
));
3394 const auto *CheckStr
= R
"(
3395 CHECK: [[DIV:%[0-9]+]]:_(s64) = G_SDIV %0:_, %1:_
3396 CHECK: [[REM:%[0-9]+]]:_(s64) = G_SREM %0:_, %1:_
3400 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
3403 // Test lowering of G_UDIVREM into G_UDIV and G_UREM
3404 TEST_F(AArch64GISelMITest
, LowerUDIVREM
) {
3409 // Declare your legalization info
3410 DefineLegalizerInfo(
3411 A
, { getActionDefinitionsBuilder(G_UDIVREM
).lowerFor({s64
}); });
3413 LLT S64
{LLT::scalar(64)};
3417 B
.buildInstr(TargetOpcode::G_UDIVREM
, {S64
, S64
}, {Copies
[0], Copies
[1]});
3418 AInfo
Info(MF
->getSubtarget());
3419 DummyGISelObserver Observer
;
3420 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
3421 // Perform Legalization
3422 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
3423 Helper
.lower(*UDivrem
, 0, S64
));
3425 const auto *CheckStr
= R
"(
3426 CHECK: [[DIV:%[0-9]+]]:_(s64) = G_UDIV %0:_, %1:_
3427 CHECK: [[REM:%[0-9]+]]:_(s64) = G_UREM %0:_, %1:_
3431 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
3434 // Test widening of G_UNMERGE_VALUES
3435 TEST_F(AArch64GISelMITest
, WidenUnmerge
) {
3440 DefineLegalizerInfo(A
, {});
3442 // Check that widening G_UNMERGE_VALUES to a larger type than the source type
3443 // works as expected
3444 LLT P0
{LLT::pointer(0, 64)};
3445 LLT S32
{LLT::scalar(32)};
3446 LLT S96
{LLT::scalar(96)};
3448 auto IntToPtr
= B
.buildIntToPtr(P0
, Copies
[0]);
3449 auto UnmergePtr
= B
.buildUnmerge(S32
, IntToPtr
);
3450 auto UnmergeScalar
= B
.buildUnmerge(S32
, Copies
[0]);
3452 AInfo
Info(MF
->getSubtarget());
3453 DummyGISelObserver Observer
;
3454 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
3456 // Perform Legalization
3457 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
3458 Helper
.widenScalar(*UnmergePtr
, 0, S96
));
3460 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
3461 Helper
.widenScalar(*UnmergeScalar
, 0, S96
));
3463 const auto *CheckStr
= R
"(
3464 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
3465 CHECK: [[PTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[COPY]]
3466 CHECK: [[INT:%[0-9]+]]:_(s64) = G_PTRTOINT [[PTR]]
3467 CHECK: [[ANYEXT:%[0-9]+]]:_(s96) = G_ANYEXT [[INT]]
3468 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[ANYEXT]]
3469 CHECK: [[C:%[0-9]+]]:_(s96) = G_CONSTANT i96 32
3470 CHECK: [[LSHR:%[0-9]+]]:_(s96) = G_LSHR [[ANYEXT]]:_, [[C]]
3471 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[LSHR]]
3472 CHECK: [[ANYEXT:%[0-9]+]]:_(s96) = G_ANYEXT [[COPY]]
3473 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[ANYEXT]]
3474 CHECK: [[C:%[0-9]+]]:_(s96) = G_CONSTANT i96 32
3475 CHECK: [[LSHR:%[0-9]+]]:_(s96) = G_LSHR [[ANYEXT]]:_, [[C]]
3476 CHECK: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC [[LSHR]]
3480 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
3483 TEST_F(AArch64GISelMITest
, BitcastLoad
) {
3488 LLT P0
= LLT::pointer(0, 64);
3489 LLT S32
= LLT::scalar(32);
3490 LLT V4S8
= LLT::fixed_vector(4, 8);
3491 auto Ptr
= B
.buildUndef(P0
);
3493 DefineLegalizerInfo(A
, {});
3495 MachineMemOperand
*MMO
= B
.getMF().getMachineMemOperand(
3496 MachinePointerInfo(), MachineMemOperand::MOLoad
, 4, Align(4));
3497 auto Load
= B
.buildLoad(V4S8
, Ptr
, *MMO
);
3499 AInfo
Info(MF
->getSubtarget());
3500 DummyGISelObserver Observer
;
3501 B
.setInsertPt(*EntryMBB
, Load
->getIterator());
3502 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
3503 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
3504 Helper
.bitcast(*Load
, 0, S32
));
3507 CHECK: [[PTR:%[0-9]+]]:_(p0) = G_IMPLICIT_DEF
3508 CHECK: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD
3509 CHECK: [[CAST:%[0-9]+]]:_(<4 x s8>) = G_BITCAST [[LOAD]]
3514 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
3517 TEST_F(AArch64GISelMITest
, BitcastStore
) {
3522 LLT P0
= LLT::pointer(0, 64);
3523 LLT S32
= LLT::scalar(32);
3524 LLT V4S8
= LLT::fixed_vector(4, 8);
3525 auto Ptr
= B
.buildUndef(P0
);
3527 DefineLegalizerInfo(A
, {});
3529 MachineMemOperand
*MMO
= B
.getMF().getMachineMemOperand(
3530 MachinePointerInfo(), MachineMemOperand::MOStore
, 4, Align(4));
3531 auto Val
= B
.buildUndef(V4S8
);
3532 auto Store
= B
.buildStore(Val
, Ptr
, *MMO
);
3534 AInfo
Info(MF
->getSubtarget());
3535 DummyGISelObserver Observer
;
3536 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
3537 B
.setInsertPt(*EntryMBB
, Store
->getIterator());
3538 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
3539 Helper
.bitcast(*Store
, 0, S32
));
3542 CHECK: [[VAL:%[0-9]+]]:_(<4 x s8>) = G_IMPLICIT_DEF
3543 CHECK: [[CAST:%[0-9]+]]:_(s32) = G_BITCAST [[VAL]]
3544 CHECK: G_STORE [[CAST]]
3548 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
3551 TEST_F(AArch64GISelMITest
, BitcastSelect
) {
3556 LLT S1
= LLT::scalar(1);
3557 LLT S32
= LLT::scalar(32);
3558 LLT V4S8
= LLT::fixed_vector(4, 8);
3560 DefineLegalizerInfo(A
, {});
3562 auto Cond
= B
.buildUndef(S1
);
3563 auto Val0
= B
.buildConstant(V4S8
, 123);
3564 auto Val1
= B
.buildConstant(V4S8
, 99);
3566 auto Select
= B
.buildSelect(V4S8
, Cond
, Val0
, Val1
);
3568 AInfo
Info(MF
->getSubtarget());
3569 DummyGISelObserver Observer
;
3570 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
3571 B
.setInsertPt(*EntryMBB
, Select
->getIterator());
3572 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
3573 Helper
.bitcast(*Select
, 0, S32
));
3576 CHECK: [[VAL0:%[0-9]+]]:_(<4 x s8>) = G_BUILD_VECTOR
3577 CHECK: [[VAL1:%[0-9]+]]:_(<4 x s8>) = G_BUILD_VECTOR
3578 CHECK: [[CAST0:%[0-9]+]]:_(s32) = G_BITCAST [[VAL0]]
3579 CHECK: [[CAST1:%[0-9]+]]:_(s32) = G_BITCAST [[VAL1]]
3580 CHECK: [[SELECT:%[0-9]+]]:_(s32) = G_SELECT %{{[0-9]+}}:_(s1), [[CAST0]]:_, [[CAST1]]:_
3581 CHECK: [[CAST2:%[0-9]+]]:_(<4 x s8>) = G_BITCAST [[SELECT]]
3585 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
3587 // Doesn't make sense
3588 auto VCond
= B
.buildUndef(LLT::fixed_vector(4, 1));
3589 auto VSelect
= B
.buildSelect(V4S8
, VCond
, Val0
, Val1
);
3591 B
.setInsertPt(*EntryMBB
, VSelect
->getIterator());
3592 EXPECT_EQ(LegalizerHelper::LegalizeResult::UnableToLegalize
,
3593 Helper
.bitcast(*VSelect
, 0, S32
));
3594 EXPECT_EQ(LegalizerHelper::LegalizeResult::UnableToLegalize
,
3595 Helper
.bitcast(*VSelect
, 1, LLT::scalar(4)));
3598 TEST_F(AArch64GISelMITest
, BitcastBitOps
) {
3603 LLT S32
= LLT::scalar(32);
3604 LLT V4S8
= LLT::fixed_vector(4, 8);
3606 DefineLegalizerInfo(A
, {});
3608 auto Val0
= B
.buildConstant(V4S8
, 123);
3609 auto Val1
= B
.buildConstant(V4S8
, 99);
3610 auto And
= B
.buildAnd(V4S8
, Val0
, Val1
);
3611 auto Or
= B
.buildOr(V4S8
, Val0
, Val1
);
3612 auto Xor
= B
.buildXor(V4S8
, Val0
, Val1
);
3614 AInfo
Info(MF
->getSubtarget());
3615 DummyGISelObserver Observer
;
3616 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
3617 B
.setInsertPt(*EntryMBB
, And
->getIterator());
3618 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
3619 Helper
.bitcast(*And
, 0, S32
));
3621 B
.setInsertPt(*EntryMBB
, Or
->getIterator());
3622 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
3623 Helper
.bitcast(*Or
, 0, S32
));
3625 B
.setInsertPt(*EntryMBB
, Xor
->getIterator());
3626 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
3627 Helper
.bitcast(*Xor
, 0, S32
));
3630 CHECK: [[VAL0:%[0-9]+]]:_(<4 x s8>) = G_BUILD_VECTOR
3631 CHECK: [[VAL1:%[0-9]+]]:_(<4 x s8>) = G_BUILD_VECTOR
3632 CHECK: [[CAST0:%[0-9]+]]:_(s32) = G_BITCAST [[VAL0]]
3633 CHECK: [[CAST1:%[0-9]+]]:_(s32) = G_BITCAST [[VAL1]]
3634 CHECK: [[AND:%[0-9]+]]:_(s32) = G_AND [[CAST0]]:_, [[CAST1]]:_
3635 CHECK: [[CAST_AND:%[0-9]+]]:_(<4 x s8>) = G_BITCAST [[AND]]
3636 CHECK: [[CAST2:%[0-9]+]]:_(s32) = G_BITCAST [[VAL0]]
3637 CHECK: [[CAST3:%[0-9]+]]:_(s32) = G_BITCAST [[VAL1]]
3638 CHECK: [[OR:%[0-9]+]]:_(s32) = G_OR [[CAST2]]:_, [[CAST3]]:_
3639 CHECK: [[CAST_OR:%[0-9]+]]:_(<4 x s8>) = G_BITCAST [[OR]]
3640 CHECK: [[CAST4:%[0-9]+]]:_(s32) = G_BITCAST [[VAL0]]
3641 CHECK: [[CAST5:%[0-9]+]]:_(s32) = G_BITCAST [[VAL1]]
3642 CHECK: [[XOR:%[0-9]+]]:_(s32) = G_XOR [[CAST4]]:_, [[CAST5]]:_
3643 CHECK: [[CAST_XOR:%[0-9]+]]:_(<4 x s8>) = G_BITCAST [[XOR]]
3647 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
3650 TEST_F(AArch64GISelMITest
, CreateLibcall
) {
3655 DefineLegalizerInfo(A
, {});
3657 AInfo
Info(MF
->getSubtarget());
3658 DummyGISelObserver Observer
;
3660 LLVMContext
&Ctx
= MF
->getFunction().getContext();
3661 auto *RetTy
= Type::getVoidTy(Ctx
);
3663 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
3664 createLibcall(B
, "abort", {{}, RetTy
, 0}, {}, CallingConv::C
));
3667 CHECK: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
3669 CHECK: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
3673 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
3676 // Test narrowing of G_IMPLICIT_DEF
3677 TEST_F(AArch64GISelMITest
, NarrowImplicitDef
) {
3682 DefineLegalizerInfo(A
, {});
3684 // Make sure that G_IMPLICIT_DEF can be narrowed if the original size is not a
3685 // multiple of narrow size
3686 LLT S32
{LLT::scalar(32)};
3687 LLT S48
{LLT::scalar(48)};
3688 LLT S64
{LLT::scalar(64)};
3689 LLT V2S64
{{LLT::fixed_vector(2, 64)}};
3691 auto Implicit1
= B
.buildUndef(S64
);
3692 auto Implicit2
= B
.buildUndef(S64
);
3693 auto Implicit3
= B
.buildUndef(V2S64
);
3694 auto Implicit4
= B
.buildUndef(V2S64
);
3696 AInfo
Info(MF
->getSubtarget());
3697 DummyGISelObserver Observer
;
3698 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
3700 // Perform Legalization
3702 B
.setInsertPt(*EntryMBB
, Implicit1
->getIterator());
3703 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
3704 Helper
.narrowScalar(*Implicit1
, 0, S48
));
3706 B
.setInsertPt(*EntryMBB
, Implicit2
->getIterator());
3707 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
3708 Helper
.narrowScalar(*Implicit2
, 0, S32
));
3710 B
.setInsertPt(*EntryMBB
, Implicit3
->getIterator());
3711 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
3712 Helper
.narrowScalar(*Implicit3
, 0, S48
));
3714 B
.setInsertPt(*EntryMBB
, Implicit4
->getIterator());
3715 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
3716 Helper
.narrowScalar(*Implicit4
, 0, S32
));
3718 const auto *CheckStr
= R
"(
3719 CHECK: [[DEF:%[0-9]+]]:_(s48) = G_IMPLICIT_DEF
3720 CHECK: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[DEF]]
3722 CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
3723 CHECK: [[DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
3724 CHECK: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[DEF]]:_(s32), [[DEF1]]
3726 CHECK: [[DEF:%[0-9]+]]:_(<2 x s48>) = G_IMPLICIT_DEF
3727 CHECK: [[ANYEXT:%[0-9]+]]:_(<2 x s64>) = G_ANYEXT [[DEF]]
3729 CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
3730 CHECK: [[DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
3731 CHECK: [[DEF2:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
3732 CHECK: [[DEF3:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
3733 CHECK: [[BV:%[0-9]+]]:_(<2 x s64>) = G_BUILD_VECTOR [[DEF]]:_(s32), [[DEF1]]:_(s32), [[DEF2]]:_(s32), [[DEF3]]:_(s32)
3737 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
3740 // Test widening of G_FREEZE
3741 TEST_F(AArch64GISelMITest
, WidenFreeze
) {
3746 DefineLegalizerInfo(A
, {});
3748 // Make sure that G_FREEZE is widened with anyext
3749 LLT S64
{LLT::scalar(64)};
3750 LLT S128
{LLT::scalar(128)};
3751 LLT V2S32
{LLT::fixed_vector(2, 32)};
3752 LLT V2S64
{LLT::fixed_vector(2, 64)};
3754 auto Vector
= B
.buildBitcast(V2S32
, Copies
[0]);
3756 auto FreezeScalar
= B
.buildInstr(TargetOpcode::G_FREEZE
, {S64
}, {Copies
[0]});
3757 auto FreezeVector
= B
.buildInstr(TargetOpcode::G_FREEZE
, {V2S32
}, {Vector
});
3759 AInfo
Info(MF
->getSubtarget());
3760 DummyGISelObserver Observer
;
3761 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
3763 // Perform Legalization
3765 B
.setInsertPt(*EntryMBB
, FreezeScalar
->getIterator());
3766 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
3767 Helper
.widenScalar(*FreezeScalar
, 0, S128
));
3769 B
.setInsertPt(*EntryMBB
, FreezeVector
->getIterator());
3770 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
3771 Helper
.widenScalar(*FreezeVector
, 0, V2S64
));
3773 const auto *CheckStr
= R
"(
3774 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
3775 CHECK: [[BITCAST:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[COPY]]
3777 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT [[COPY]]
3778 CHECK: [[FREEZE:%[0-9]+]]:_(s128) = G_FREEZE [[ANYEXT]]
3779 CHECK: [[TRUNC:%[0-9]+]]:_(s64) = G_TRUNC [[FREEZE]]
3781 CHECK: [[ANYEXT1:%[0-9]+]]:_(<2 x s64>) = G_ANYEXT [[BITCAST]]
3782 CHECK: [[FREEZE1:%[0-9]+]]:_(<2 x s64>) = G_FREEZE [[ANYEXT1]]
3783 CHECK: [[TRUNC1:%[0-9]+]]:_(<2 x s32>) = G_TRUNC [[FREEZE1]]
3787 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
3790 // Test narrowing of G_FREEZE
3791 TEST_F(AArch64GISelMITest
, NarrowFreeze
) {
3796 DefineLegalizerInfo(A
, {});
3798 // Make sure that G_FREEZE is narrowed using unmerge/extract
3799 LLT S32
{LLT::scalar(32)};
3800 LLT S33
{LLT::scalar(33)};
3801 LLT S48
{LLT::scalar(48)};
3802 LLT S64
{LLT::scalar(64)};
3803 LLT V2S16
{LLT::fixed_vector(2, 16)};
3804 LLT V3S16
{LLT::fixed_vector(3, 16)};
3805 LLT V4S16
{LLT::fixed_vector(4, 16)};
3807 auto Trunc
= B
.buildTrunc(S33
, {Copies
[0]});
3808 auto Trunc1
= B
.buildTrunc(S48
, {Copies
[0]});
3809 auto Vector
= B
.buildBitcast(V3S16
, Trunc1
);
3811 auto FreezeScalar
= B
.buildInstr(TargetOpcode::G_FREEZE
, {S64
}, {Copies
[0]});
3812 auto FreezeOdd
= B
.buildInstr(TargetOpcode::G_FREEZE
, {S33
}, {Trunc
});
3813 auto FreezeVector
= B
.buildInstr(TargetOpcode::G_FREEZE
, {V3S16
}, {Vector
});
3814 auto FreezeVector1
= B
.buildInstr(TargetOpcode::G_FREEZE
, {V3S16
}, {Vector
});
3816 AInfo
Info(MF
->getSubtarget());
3817 DummyGISelObserver Observer
;
3818 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
3820 // Perform Legalization
3822 B
.setInsertPt(*EntryMBB
, FreezeScalar
->getIterator());
3823 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
3824 Helper
.narrowScalar(*FreezeScalar
, 0, S32
));
3826 // This should be followed by narrowScalar to S32.
3827 B
.setInsertPt(*EntryMBB
, FreezeOdd
->getIterator());
3828 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
3829 Helper
.widenScalar(*FreezeOdd
, 0, S64
));
3831 B
.setInsertPt(*EntryMBB
, FreezeVector
->getIterator());
3832 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
3833 Helper
.fewerElementsVector(*FreezeVector
, 0, V2S16
));
3835 // This should be followed by fewerElements to V2S16.
3836 B
.setInsertPt(*EntryMBB
, FreezeVector1
->getIterator());
3837 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
3838 Helper
.moreElementsVector(*FreezeVector1
, 0, V4S16
));
3840 const auto *CheckStr
= R
"(
3841 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
3842 CHECK: [[TRUNC:%[0-9]+]]:_(s33) = G_TRUNC [[COPY]]
3843 CHECK: [[TRUNC1:%[0-9]+]]:_(s48) = G_TRUNC [[COPY]]
3844 CHECK: [[BITCAST:%[0-9]+]]:_(<3 x s16>) = G_BITCAST [[TRUNC1]]
3846 CHECK: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[COPY]]
3847 CHECK: [[FREEZE:%[0-9]+]]:_(s32) = G_FREEZE [[UV]]
3848 CHECK: [[FREEZE1:%[0-9]+]]:_(s32) = G_FREEZE [[UV1]]
3849 CHECK: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[FREEZE]]:_(s32), [[FREEZE1]]
3851 CHECK: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[TRUNC]]
3852 CHECK: [[FREEZE2:%[0-9]+]]:_(s64) = G_FREEZE [[ANYEXT]]
3853 CHECK: [[TRUNC1:%[0-9]+]]:_(s33) = G_TRUNC [[FREEZE2]]
3855 CHECK: [[UV2:%[0-9]+]]:_(s16), [[UV3:%[0-9]+]]:_(s16), [[UV4:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[BITCAST]]
3856 CHECK: [[BV:%[0-9]+]]:_(<2 x s16>) = G_BUILD_VECTOR [[UV2]]:_(s16), [[UV3]]:_(s16)
3857 CHECK: [[FREEZE3:%[0-9]+]]:_(<2 x s16>) = G_FREEZE [[BV]]
3858 CHECK: [[FREEZE4:%[0-9]+]]:_(s16) = G_FREEZE [[UV4]]
3859 CHECK: [[FREEZE3_E0:%[0-9]+]]:_(s16), [[FREEZE3_E1:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[FREEZE3]]
3860 CHECK: [[BV1:%[0-9]+]]:_(<3 x s16>) = G_BUILD_VECTOR [[FREEZE3_E0]]:_(s16), [[FREEZE3_E1]]:_(s16), [[FREEZE4]]:_(s16)
3862 CHECK: [[UV5:%[0-9]+]]:_(s16), [[UV6:%[0-9]+]]:_(s16), [[UV7:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[BITCAST]]
3863 CHECK: [[IMP_DEF:%[0-9]+]]:_(s16) = G_IMPLICIT_DEF
3864 CHECK: [[BV1:%[0-9]+]]:_(<4 x s16>) = G_BUILD_VECTOR [[UV5]]:_(s16), [[UV6]]:_(s16), [[UV7]]:_(s16), [[IMP_DEF]]:_(s16)
3865 CHECK: [[FREEZE5:%[0-9]+]]:_(<4 x s16>) = G_FREEZE [[BV1]]
3866 CHECK: [[FREEZE5_E0:%[0-9]+]]:_(s16), [[FREEZE5_E1:%[0-9]+]]:_(s16), [[FREEZE5_E2:%[0-9]+]]:_(s16), [[FREEZE5_E3:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[FREEZE5]]
3867 CHECK: [[BV2:%[0-9]+]]:_(<3 x s16>) = G_BUILD_VECTOR [[FREEZE5_E0]]:_(s16), [[FREEZE5_E1]]:_(s16), [[FREEZE5_E2]]:_(s16)
3871 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
3874 // Test fewer elements of G_FREEZE
3875 TEST_F(AArch64GISelMITest
, FewerElementsFreeze
) {
3880 DefineLegalizerInfo(A
, {});
3882 LLT S32
{LLT::scalar(32)};
3883 LLT V2S16
{LLT::fixed_vector(2, 16)};
3884 LLT V2S32
{LLT::fixed_vector(2, 32)};
3885 LLT V4S16
{LLT::fixed_vector(4, 16)};
3887 auto Vector1
= B
.buildBitcast(V2S32
, Copies
[0]);
3888 auto Vector2
= B
.buildBitcast(V4S16
, Copies
[0]);
3890 auto FreezeVector1
= B
.buildInstr(TargetOpcode::G_FREEZE
, {V2S32
}, {Vector1
});
3891 auto FreezeVector2
= B
.buildInstr(TargetOpcode::G_FREEZE
, {V4S16
}, {Vector2
});
3893 AInfo
Info(MF
->getSubtarget());
3894 DummyGISelObserver Observer
;
3895 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
3897 // Perform Legalization
3899 B
.setInsertPt(*EntryMBB
, FreezeVector1
->getIterator());
3900 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
3901 Helper
.fewerElementsVector(*FreezeVector1
, 0, S32
));
3903 B
.setInsertPt(*EntryMBB
, FreezeVector2
->getIterator());
3904 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
3905 Helper
.fewerElementsVector(*FreezeVector2
, 0, V2S16
));
3907 const auto *CheckStr
= R
"(
3908 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
3909 CHECK: [[BITCAST:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[COPY]]
3910 CHECK: [[BITCAST1:%[0-9]+]]:_(<4 x s16>) = G_BITCAST [[COPY]]
3912 CHECK: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[BITCAST]]
3913 CHECK: [[FREEZE:%[0-9]+]]:_(s32) = G_FREEZE [[UV]]
3914 CHECK: [[FREEZE1:%[0-9]+]]:_(s32) = G_FREEZE [[UV1]]
3915 CHECK: [[MV:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[FREEZE]]:_(s32), [[FREEZE1]]
3917 CHECK: [[UV:%[0-9]+]]:_(<2 x s16>), [[UV1:%[0-9]+]]:_(<2 x s16>) = G_UNMERGE_VALUES [[BITCAST1]]
3918 CHECK: [[FREEZE2:%[0-9]+]]:_(<2 x s16>) = G_FREEZE [[UV]]
3919 CHECK: [[FREEZE3:%[0-9]+]]:_(<2 x s16>) = G_FREEZE [[UV1]]
3920 CHECK: [[MV:%[0-9]+]]:_(<4 x s16>) = G_CONCAT_VECTORS [[FREEZE2]]:_(<2 x s16>), [[FREEZE3]]
3924 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
3927 // Test more elements of G_FREEZE
3928 TEST_F(AArch64GISelMITest
, MoreElementsFreeze
) {
3933 DefineLegalizerInfo(A
, {});
3935 LLT V2S32
{LLT::fixed_vector(2, 32)};
3936 LLT V4S32
{LLT::fixed_vector(4, 32)};
3938 auto Vector1
= B
.buildBitcast(V2S32
, Copies
[0]);
3939 auto FreezeVector1
= B
.buildInstr(TargetOpcode::G_FREEZE
, {V2S32
}, {Vector1
});
3941 AInfo
Info(MF
->getSubtarget());
3942 DummyGISelObserver Observer
;
3943 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
3945 // Perform Legalization
3946 B
.setInsertPt(*EntryMBB
, FreezeVector1
->getIterator());
3947 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
3948 Helper
.moreElementsVector(*FreezeVector1
, 0, V4S32
));
3950 const auto *CheckStr
= R
"(
3951 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
3952 CHECK: [[BITCAST:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[COPY]]
3953 CHECK: [[BITCAST_E0:%[0-9]+]]:_(s32), [[BITCAST_E1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[BITCAST]]:_(<2 x s32>)
3954 CHECK: [[IMP_DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
3955 CHECK: [[BITCAST_LARGE:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[BITCAST_E0]]:_(s32), [[BITCAST_E1]]:_(s32), [[IMP_DEF]]:_(s32), [[IMP_DEF]]:_(s32)
3956 CHECK: [[FREEZE:%[0-9]+]]:_(<4 x s32>) = G_FREEZE [[BITCAST_LARGE]]
3957 CHECK: [[FREEZE_E0:%[0-9]+]]:_(s32), [[FREEZE_E1:%[0-9]+]]:_(s32), [[FREEZE_E2:%[0-9]+]]:_(s32), [[FREEZE_E3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[FREEZE]]:_(<4 x s32>)
3958 CHECK: (<2 x s32>) = G_BUILD_VECTOR [[FREEZE_E0]]:_(s32), [[FREEZE_E1]]:_(s32)
3962 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
3965 // Test fewer elements of G_INSERT_VECTOR_ELEMENT
3966 TEST_F(AArch64GISelMITest
, FewerElementsInsertVectorElt
) {
3971 DefineLegalizerInfo(A
, {});
3973 LLT P0
{LLT::pointer(0, 64)};
3974 LLT S64
{LLT::scalar(64)};
3975 LLT S16
{LLT::scalar(16)};
3976 LLT V2S16
{LLT::fixed_vector(2, 16)};
3977 LLT V3S16
{LLT::fixed_vector(3, 16)};
3978 LLT V8S16
{LLT::fixed_vector(8, 16)};
3980 auto Ptr0
= B
.buildIntToPtr(P0
, Copies
[0]);
3981 auto VectorV8
= B
.buildLoad(V8S16
, Ptr0
, MachinePointerInfo(), Align(8));
3982 auto Value
= B
.buildTrunc(S16
, Copies
[1]);
3984 auto Seven
= B
.buildConstant(S64
, 7);
3985 auto InsertV8Constant7_0
=
3986 B
.buildInsertVectorElement(V8S16
, VectorV8
, Value
, Seven
);
3987 auto InsertV8Constant7_1
=
3988 B
.buildInsertVectorElement(V8S16
, VectorV8
, Value
, Seven
);
3990 B
.buildStore(InsertV8Constant7_0
, Ptr0
, MachinePointerInfo(), Align(8),
3991 MachineMemOperand::MOVolatile
);
3992 B
.buildStore(InsertV8Constant7_1
, Ptr0
, MachinePointerInfo(), Align(8),
3993 MachineMemOperand::MOVolatile
);
3995 AInfo
Info(MF
->getSubtarget());
3996 DummyGISelObserver Observer
;
3997 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
3999 // Perform Legalization
4000 B
.setInsertPt(*EntryMBB
, InsertV8Constant7_0
->getIterator());
4002 // This should index the high element of the 4th piece of an unmerge.
4003 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
4004 Helper
.fewerElementsVector(*InsertV8Constant7_0
, 0, V2S16
));
4006 // This case requires extracting an intermediate vector type into the target
4008 B
.setInsertPt(*EntryMBB
, InsertV8Constant7_1
->getIterator());
4009 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
4010 Helper
.fewerElementsVector(*InsertV8Constant7_1
, 0, V3S16
));
4012 const auto *CheckStr
= R
"(
4013 CHECK: [[COPY0:%[0-9]+]]:_(s64) = COPY
4014 CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY
4015 CHECK: [[COPY2:%[0-9]+]]:_(s64) = COPY
4016 CHECK: [[PTR0:%[0-9]+]]:_(p0) = G_INTTOPTR [[COPY0]]
4017 CHECK: [[VEC8:%[0-9]+]]:_(<8 x s16>) = G_LOAD [[PTR0]]:_(p0) :: (load (<8 x s16>), align 8)
4018 CHECK: [[INSERT_VAL:%[0-9]+]]:_(s16) = G_TRUNC [[COPY1]]
4021 CHECK: [[UNMERGE0:%[0-9]+]]:_(<2 x s16>), [[UNMERGE1:%[0-9]+]]:_(<2 x s16>), [[UNMERGE2:%[0-9]+]]:_(<2 x s16>), [[UNMERGE3:%[0-9]+]]:_(<2 x s16>) = G_UNMERGE_VALUES [[VEC8]]
4022 CHECK: [[ONE:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
4023 CHECK: [[SUB_INSERT_7:%[0-9]+]]:_(<2 x s16>) = G_INSERT_VECTOR_ELT [[UNMERGE3]]:_, [[INSERT_VAL]]:_(s16), [[ONE]]
4024 CHECK: [[INSERT_V8_7_0:%[0-9]+]]:_(<8 x s16>) = G_CONCAT_VECTORS [[UNMERGE0]]:_(<2 x s16>), [[UNMERGE1]]:_(<2 x s16>), [[UNMERGE2]]:_(<2 x s16>), [[SUB_INSERT_7]]:_(<2 x s16>)
4027 CHECK: [[UNMERGE1_0:%[0-9]+]]:_(s16), [[UNMERGE1_1:%[0-9]+]]:_(s16), [[UNMERGE1_2:%[0-9]+]]:_(s16), [[UNMERGE1_3:%[0-9]+]]:_(s16), [[UNMERGE1_4:%[0-9]+]]:_(s16), [[UNMERGE1_5:%[0-9]+]]:_(s16), [[UNMERGE1_6:%[0-9]+]]:_(s16), [[UNMERGE1_7:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[VEC8]]:_(<8 x s16>)
4028 CHECK: [[IMPDEF_S16:%[0-9]+]]:_(s16) = G_IMPLICIT_DEF
4029 CHECK: [[BUILD0:%[0-9]+]]:_(<3 x s16>) = G_BUILD_VECTOR [[UNMERGE1_0]]:_(s16), [[UNMERGE1_1]]:_(s16), [[UNMERGE1_2]]:_(s16)
4030 CHECK: [[BUILD1:%[0-9]+]]:_(<3 x s16>) = G_BUILD_VECTOR [[UNMERGE1_3]]:_(s16), [[UNMERGE1_4]]:_(s16), [[UNMERGE1_5]]:_(s16)
4031 CHECK: [[BUILD2:%[0-9]+]]:_(<3 x s16>) = G_BUILD_VECTOR [[UNMERGE1_6]]:_(s16), [[UNMERGE1_7]]:_(s16), [[IMPDEF_S16]]:_(s16)
4032 CHECK: [[IMPDEF_V3S16:%[0-9]+]]:_(<3 x s16>) = G_IMPLICIT_DEF
4033 CHECK: [[ONE_1:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
4034 CHECK: [[SUB_INSERT_7_V3S16:%[0-9]+]]:_(<3 x s16>) = G_INSERT_VECTOR_ELT [[BUILD2]]:_, [[INSERT_VAL]]:_(s16), [[ONE_1]]
4036 CHECK: [[WIDE_CONCAT_DEAD:%[0-9]+]]:_(<24 x s16>) = G_CONCAT_VECTORS [[BUILD0]]:_(<3 x s16>), [[BUILD1]]:_(<3 x s16>), [[SUB_INSERT_7_V3S16]]:_(<3 x s16>), [[IMPDEF_V3S16]]:_(<3 x s16>), [[IMPDEF_V3S16]]:_(<3 x s16>), [[IMPDEF_V3S16]]:_(<3 x s16>), [[IMPDEF_V3S16]]:_(<3 x s16>), [[IMPDEF_V3S16]]:_(<3 x s16>)
4037 CHECK: [[WIDE_CONCAT:%[0-9]+]]:_(<24 x s16>) = G_CONCAT_VECTORS [[BUILD0]]:_(<3 x s16>), [[BUILD1]]:_(<3 x s16>), [[SUB_INSERT_7_V3S16]]:_(<3 x s16>), [[IMPDEF_V3S16]]:_(<3 x s16>), [[IMPDEF_V3S16]]:_(<3 x s16>), [[IMPDEF_V3S16]]:_(<3 x s16>), [[IMPDEF_V3S16]]:_(<3 x s16>), [[IMPDEF_V3S16]]:_(<3 x s16>)
4038 CHECK: [[INSERT_V8_7_1:%[0-9]+]]:_(<8 x s16>), %{{[0-9]+}}:_(<8 x s16>), %{{[0-9]+}}:_(<8 x s16>) = G_UNMERGE_VALUES [[WIDE_CONCAT]]:_(<24 x s16>)
4041 CHECK: G_STORE [[INSERT_V8_7_0]]
4042 CHECK: G_STORE [[INSERT_V8_7_1]]
4046 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
4049 // Test widen scalar of G_UNMERGE_VALUES
4050 TEST_F(AArch64GISelMITest
, widenScalarUnmerge
) {
4055 DefineLegalizerInfo(A
, {});
4057 LLT S96
{LLT::scalar(96)};
4058 LLT S64
{LLT::scalar(64)};
4059 LLT S48
{LLT::scalar(48)};
4061 auto Src
= B
.buildAnyExt(S96
, Copies
[0]);
4062 auto Unmerge
= B
.buildUnmerge(S48
, Src
);
4064 AInfo
Info(MF
->getSubtarget());
4065 DummyGISelObserver Observer
;
4066 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
4068 // Perform Legalization
4069 B
.setInsertPt(*EntryMBB
, Unmerge
->getIterator());
4071 // This should create unmerges to a GCD type (S16), then remerge to S48
4072 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
4073 Helper
.widenScalar(*Unmerge
, 0, S64
));
4075 const auto *CheckStr
= R
"(
4076 CHECK: [[COPY0:%[0-9]+]]:_(s64) = COPY
4077 CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY
4078 CHECK: [[COPY2:%[0-9]+]]:_(s64) = COPY
4079 CHECK: [[ANYEXT:%[0-9]+]]:_(s96) = G_ANYEXT [[COPY0]]
4080 CHECK: [[ANYEXT1:%[0-9]+]]:_(s192) = G_ANYEXT [[ANYEXT]]
4081 CHECK: [[UNMERGE:%[0-9]+]]:_(s64), [[UNMERGE1:%[0-9]+]]:_(s64), [[UNMERGE2:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[ANYEXT1]]
4082 CHECK: [[UNMERGE3:%[0-9]+]]:_(s16), [[UNMERGE4:%[0-9]+]]:_(s16), [[UNMERGE5:%[0-9]+]]:_(s16), [[UNMERGE6:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[UNMERGE]]
4083 CHECK: [[UNMERGE7:%[0-9]+]]:_(s16), [[UNMERGE8:%[0-9]+]]:_(s16), [[UNMERGE9:%[0-9]+]]:_(s16), [[UNMERGE10:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[UNMERGE1]]
4084 CHECK: [[UNMERGE11:%[0-9]+]]:_(s16), [[UNMERGE12:%[0-9]+]]:_(s16), [[UNMERGE13:%[0-9]+]]:_(s16), [[UNMERGE14:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[UNMERGE2]]
4085 CHECK: [[MERGE:%[0-9]+]]:_(s48) = G_MERGE_VALUES [[UNMERGE3]]:_(s16), [[UNMERGE4]]:_(s16), [[UNMERGE5]]:_(s16)
4086 CHECK: [[MERGE1:%[0-9]+]]:_(s48) = G_MERGE_VALUES [[UNMERGE6]]:_(s16), [[UNMERGE7]]:_(s16), [[UNMERGE8]]:_(s16)
4090 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
4093 // Test moreElements of G_SHUFFLE_VECTOR.
4094 TEST_F(AArch64GISelMITest
, moreElementsShuffle
) {
4099 DefineLegalizerInfo(A
, {});
4101 LLT S64
{LLT::scalar(64)};
4102 LLT V6S64
= LLT::fixed_vector(6, S64
);
4104 auto V1
= B
.buildBuildVector(V6S64
, {Copies
[0], Copies
[1], Copies
[0],
4105 Copies
[1], Copies
[0], Copies
[1]});
4106 auto V2
= B
.buildBuildVector(V6S64
, {Copies
[0], Copies
[1], Copies
[0],
4107 Copies
[1], Copies
[0], Copies
[1]});
4108 auto Shuffle
= B
.buildShuffleVector(V6S64
, V1
, V2
, {3, 4, 7, 0, 1, 11});
4110 AInfo
Info(MF
->getSubtarget());
4111 DummyGISelObserver Observer
;
4112 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
4114 // Perform Legalization
4115 B
.setInsertPt(*EntryMBB
, Shuffle
->getIterator());
4117 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
4118 Helper
.moreElementsVector(*Shuffle
, 0, LLT::fixed_vector(8, S64
)));
4120 const auto *CheckStr
= R
"(
4121 CHECK: [[COPY0:%[0-9]+]]:_(s64) = COPY
4122 CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY
4123 CHECK: [[COPY2:%[0-9]+]]:_(s64) = COPY
4124 CHECK: [[BV1:%[0-9]+]]:_(<6 x s64>) = G_BUILD_VECTOR
4125 CHECK: [[BV2:%[0-9]+]]:_(<6 x s64>) = G_BUILD_VECTOR
4127 CHECK: [[BV1_E0:%[0-9]+]]:_(s64), [[BV1_E1:%[0-9]+]]:_(s64), [[BV1_E2:%[0-9]+]]:_(s64), [[BV1_E3:%[0-9]+]]:_(s64), [[BV1_E4:%[0-9]+]]:_(s64), [[BV1_E5:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[BV1]]:_(<6 x s64>)
4128 CHECK: [[IMP_DEF0:%[0-9]+]]:_(s64) = G_IMPLICIT_DEF
4129 CHECK: [[BV1_LARGE:%[0-9]+]]:_(<8 x s64>) = G_BUILD_VECTOR [[BV1_E0]]:_(s64), [[BV1_E1]]:_(s64), [[BV1_E2]]:_(s64), [[BV1_E3]]:_(s64), [[BV1_E4]]:_(s64), [[BV1_E5]]:_(s64), [[IMP_DEF0]]:_(s64), [[IMP_DEF0]]:_(s64)
4131 CHECK: [[BV2_E0:%[0-9]+]]:_(s64), [[BV2_E1:%[0-9]+]]:_(s64), [[BV2_E2:%[0-9]+]]:_(s64), [[BV2_E3:%[0-9]+]]:_(s64), [[BV2_E4:%[0-9]+]]:_(s64), [[BV2_E5:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[BV2]]:_(<6 x s64>)
4132 CHECK: [[IMP_DEF1:%[0-9]+]]:_(s64) = G_IMPLICIT_DEF
4133 CHECK: [[BV2_LARGE:%[0-9]+]]:_(<8 x s64>) = G_BUILD_VECTOR [[BV2_E0]]:_(s64), [[BV2_E1]]:_(s64), [[BV2_E2]]:_(s64), [[BV2_E3]]:_(s64), [[BV2_E4]]:_(s64), [[BV2_E5]]:_(s64), [[IMP_DEF1]]:_(s64), [[IMP_DEF1]]:_(s64)
4135 CHECK: [[SHUF:%[0-9]+]]:_(<8 x s64>) = G_SHUFFLE_VECTOR [[BV1_LARGE]]:_(<8 x s64>), [[BV2_LARGE]]:_, shufflemask(3, 4, 9, 0, 1, 13, undef, undef)
4137 CHECK: [[SHUF_E0:%[0-9]+]]:_(s64), [[SHUF_E1:%[0-9]+]]:_(s64), [[SHUF_E2:%[0-9]+]]:_(s64), [[SHUF_E3:%[0-9]+]]:_(s64), [[SHUF_E4:%[0-9]+]]:_(s64), [[SHUF_E5:%[0-9]+]]:_(s64), [[SHUF_E6:%[0-9]+]]:_(s64), [[SHUF_E7:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[SHUF]]:_(<8 x s64>)
4138 CHECK: (<6 x s64>) = G_BUILD_VECTOR [[SHUF_E0]]:_(s64), [[SHUF_E1]]:_(s64), [[SHUF_E2]]:_(s64), [[SHUF_E3]]:_(s64), [[SHUF_E4]]:_(s64), [[SHUF_E5]]:_(s64)
4142 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
4145 // Test narror scalar of G_SHL with constant shift amount
4146 TEST_F(AArch64GISelMITest
, narrowScalarShiftByConstant
) {
4151 DefineLegalizerInfo(A
, {});
4153 LLT S64
{LLT::scalar(64)};
4154 LLT S32
{LLT::scalar(32)};
4156 auto Constant
= B
.buildConstant(S64
, 33);
4157 auto Trunc
= B
.buildTrunc(S32
, Constant
);
4158 auto Shift
= B
.buildShl(S64
, Copies
[0], Trunc
);
4160 AInfo
Info(MF
->getSubtarget());
4161 DummyGISelObserver Observer
;
4162 LegalizerHelper
Helper(*MF
, Info
, Observer
, B
);
4164 // Perform Legalization
4165 B
.setInsertPt(*EntryMBB
, Shift
->getIterator());
4167 // This should detect the G_CONSTANT feeding the G_SHL through a G_TRUNC
4168 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
4169 Helper
.narrowScalarShift(*Shift
, 0, S32
));
4171 const auto *CheckStr
= R
"(
4172 CHECK: [[COPY0:%[0-9]+]]:_(s64) = COPY
4173 CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY
4174 CHECK: [[COPY2:%[0-9]+]]:_(s64) = COPY
4175 CHECK: [[THIRTY3:%[0-9]+]]:_(s64) = G_CONSTANT i64 33
4176 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC %4:_(s64)
4177 CHECK: [[UNMERGE:%[0-9]+]]:_(s32), [[UNMERGE2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[COPY0]]
4178 CHECK: [[ZERO:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
4179 CHECK: [[ONE:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
4180 CHECK: [[SHIFT:%[0-9]+]]:_(s32) = G_SHL [[UNMERGE]]:_, [[ONE]]:_(s32)
4181 CHECK: [[MERGE:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[ZERO]]:_(s32), [[SHIFT]]:_(s32)
4185 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;
4188 TEST_F(AArch64GISelMITest
, MoreElementsSelect
) {
4193 LLT s1
= LLT::scalar(1);
4194 LLT s64
= LLT::scalar(64);
4195 LLT v2s1
= LLT::fixed_vector(2, 1);
4196 LLT v2s32
= LLT::fixed_vector(2, 32);
4199 DummyGISelObserver Observer
;
4200 LegalizerHelper
Helper(*MF
, LI
, Observer
, B
);
4202 B
.setInsertPt(*EntryMBB
, EntryMBB
->end());
4204 auto Val0
= B
.buildBitcast(v2s32
, Copies
[0]);
4205 auto Val1
= B
.buildBitcast(v2s32
, Copies
[1]);
4207 // Build select of vectors with scalar condition.
4208 auto Zero
= B
.buildConstant(s64
, 0);
4209 auto Cond
= B
.buildICmp(CmpInst::ICMP_EQ
, s1
, Copies
[2], Zero
);
4210 auto Select
= B
.buildSelect(v2s32
, Cond
, Val0
, Val1
);
4212 // Splat the condition into a vector select
4213 B
.setInstr(*Select
);
4215 EXPECT_EQ(LegalizerHelper::LegalizeResult::UnableToLegalize
,
4216 Helper
.moreElementsVector(*Select
, 1, LLT::fixed_vector(3, 1)));
4217 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized
,
4218 Helper
.moreElementsVector(*Select
, 1, v2s1
));
4221 CHECK: [[BITCAST0:%[0-9]+]]:_(<2 x s32>) = G_BITCAST
4222 CHECK: [[BITCAST1:%[0-9]+]]:_(<2 x s32>) = G_BITCAST
4223 CHECK: [[ZERO0:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
4224 CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), %{{[0-9]+}}:_(s64), [[ZERO0]]
4225 CHECK: [[IMPDEF:%[0-9]+]]:_(<2 x s1>) = G_IMPLICIT_DEF
4226 CHECK: [[ZERO1:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
4227 CHECK: [[INSERT:%[0-9]+]]:_(<2 x s1>) = G_INSERT_VECTOR_ELT [[IMPDEF]]:_, [[CMP]]:_(s1), [[ZERO1]]
4228 CHECK: [[SHUFFLE:%[0-9]+]]:_(<2 x s1>) = G_SHUFFLE_VECTOR [[INSERT]]:_(<2 x s1>), [[IMPDEF]]:_, shufflemask(0, 0)
4229 CHECK: [[SELECT:%[0-9]+]]:_(<2 x s32>) = G_SELECT [[SHUFFLE]]:_(<2 x s1>), [[BITCAST0]]:_, [[BITCAST1]]:_
4232 EXPECT_TRUE(CheckMachineFunction(*MF
, CheckStr
)) << *MF
;