1 //===- PatternMatchTest.cpp -----------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "LegalizerHelperTest.h"
14 // Test CTTZ expansion when CTTZ_ZERO_UNDEF is legal or custom,
15 // in which case it becomes CTTZ_ZERO_UNDEF with select.
16 TEST_F(LegalizerHelperTest
, LowerBitCountingCTTZ0
) {
20 // Declare your legalization info
22 A
, { getActionDefinitionsBuilder(G_CTTZ_ZERO_UNDEF
).legalFor({s64
}); });
24 auto MIBCTTZ
= B
.buildInstr(TargetOpcode::G_CTTZ
, LLT::scalar(64), Copies
[0]);
25 AInfo
Info(MF
->getSubtarget());
26 LegalizerHelper
Helper(*MF
, Info
);
27 // Perform Legalization
28 ASSERT_TRUE(Helper
.lower(*MIBCTTZ
, 0, LLT::scalar(64)) ==
29 LegalizerHelper::LegalizeResult::Legalized
);
32 CHECK: [[CZU:%[0-9]+]]:_(s64) = G_CTTZ_ZERO_UNDEF %0
33 CHECK: [[ZERO:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
34 CHECK: [[SIXTY4:%[0-9]+]]:_(s64) = G_CONSTANT i64 64
35 CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), %0:_(s64), [[ZERO]]
36 CHECK: [[SEL:%[0-9]+]]:_(s64) = G_SELECT [[CMP]]:_(s1), [[SIXTY4]]:_, [[CZU]]
40 ASSERT_TRUE(CheckMachineFunction(*MF
, CheckStr
));
43 // CTTZ expansion in terms of CTLZ
44 TEST_F(LegalizerHelperTest
, LowerBitCountingCTTZ1
) {
48 // Declare your legalization info
49 DefineLegalizerInfo(A
,
50 { getActionDefinitionsBuilder(G_CTLZ
).legalFor({s64
}); });
52 auto MIBCTTZ
= B
.buildInstr(TargetOpcode::G_CTTZ
, LLT::scalar(64), Copies
[0]);
53 AInfo
Info(MF
->getSubtarget());
54 LegalizerHelper
Helper(*MF
, Info
);
55 // Perform Legalization
56 ASSERT_TRUE(Helper
.lower(*MIBCTTZ
, 0, LLT::scalar(64)) ==
57 LegalizerHelper::LegalizeResult::Legalized
);
60 CHECK: [[NEG1:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1
61 CHECK: [[NOT:%[0-9]+]]:_(s64) = G_XOR %0:_, [[NEG1]]
62 CHECK: [[SUB1:%[0-9]+]]:_(s64) = G_ADD %0:_, [[NEG1]]
63 CHECK: [[AND1:%[0-9]+]]:_(s64) = G_AND [[NOT]]:_, [[SUB1]]:_
64 CHECK: [[CST64:%[0-9]+]]:_(s64) = G_CONSTANT i64 64
65 CHECK: [[CTLZ:%[0-9]+]]:_(s64) = G_CTLZ [[AND1]]:_
66 CHECK: G_SUB [[CST64]]:_, [[CTLZ]]:_
70 ASSERT_TRUE(CheckMachineFunction(*MF
, CheckStr
));
73 // CTTZ expansion in terms of CTPOP
74 TEST_F(LegalizerHelperTest
, LowerBitCountingCTTZ2
) {
78 // Declare your legalization info
80 A
, { getActionDefinitionsBuilder(G_CTPOP
).legalFor({s64
}); });
82 auto MIBCTTZ
= B
.buildInstr(TargetOpcode::G_CTTZ
, LLT::scalar(64), Copies
[0]);
83 AInfo
Info(MF
->getSubtarget());
84 LegalizerHelper
Helper(*MF
, Info
);
85 ASSERT_TRUE(Helper
.lower(*MIBCTTZ
, 0, LLT::scalar(64)) ==
86 LegalizerHelper::LegalizeResult::Legalized
);
89 CHECK: [[NEG1:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1
90 CHECK: [[NOT:%[0-9]+]]:_(s64) = G_XOR %0:_, [[NEG1]]
91 CHECK: [[SUB1:%[0-9]+]]:_(s64) = G_ADD %0:_, [[NEG1]]
92 CHECK: [[AND1:%[0-9]+]]:_(s64) = G_AND [[NOT]]:_, [[SUB1]]:_
93 CHECK: [[POP:%[0-9]+]]:_(s64) = G_CTPOP [[AND1]]
97 ASSERT_TRUE(CheckMachineFunction(*MF
, CheckStr
));
100 // CTTZ_ZERO_UNDEF expansion in terms of CTTZ
101 TEST_F(LegalizerHelperTest
, LowerBitCountingCTTZ3
) {
105 // Declare your legalization info
106 DefineLegalizerInfo(A
,
107 { getActionDefinitionsBuilder(G_CTTZ
).legalFor({s64
}); });
110 B
.buildInstr(TargetOpcode::G_CTTZ_ZERO_UNDEF
, LLT::scalar(64), Copies
[0]);
111 AInfo
Info(MF
->getSubtarget());
112 LegalizerHelper
Helper(*MF
, Info
);
113 ASSERT_TRUE(Helper
.lower(*MIBCTTZ
, 0, LLT::scalar(64)) ==
114 LegalizerHelper::LegalizeResult::Legalized
);
121 ASSERT_TRUE(CheckMachineFunction(*MF
, CheckStr
));
124 // CTLZ expansion in terms of CTLZ_ZERO_UNDEF
125 TEST_F(LegalizerHelperTest
, LowerBitCountingCTLZ0
) {
129 // Declare your legalization info
131 A
, { getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF
).legalFor({s64
}); });
133 auto MIBCTLZ
= B
.buildInstr(TargetOpcode::G_CTLZ
, LLT::scalar(64), Copies
[0]);
134 AInfo
Info(MF
->getSubtarget());
135 LegalizerHelper
Helper(*MF
, Info
);
136 ASSERT_TRUE(Helper
.lower(*MIBCTLZ
, 0, LLT::scalar(64)) ==
137 LegalizerHelper::LegalizeResult::Legalized
);
140 CHECK: [[CZU:%[0-9]+]]:_(s64) = G_CTLZ_ZERO_UNDEF %0
141 CHECK: [[ZERO:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
142 CHECK: [[SIXTY4:%[0-9]+]]:_(s64) = G_CONSTANT i64 64
143 CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), %0:_(s64), [[ZERO]]
144 CHECK: [[SEL:%[0-9]+]]:_(s64) = G_SELECT [[CMP]]:_(s1), [[SIXTY4]]:_, [[CZU]]
148 ASSERT_TRUE(CheckMachineFunction(*MF
, CheckStr
));
152 TEST_F(LegalizerHelperTest
, LowerBitCountingCTLZ1
) {
156 // Declare your legalization info
157 DefineLegalizerInfo(A
,
158 { getActionDefinitionsBuilder(G_CTPOP
).legalFor({s8
}); });
161 LLT s8
{LLT::scalar(8)};
162 auto MIBTrunc
= B
.buildTrunc(s8
, Copies
[0]);
163 auto MIBCTLZ
= B
.buildInstr(TargetOpcode::G_CTLZ
, s8
, MIBTrunc
);
164 AInfo
Info(MF
->getSubtarget());
165 LegalizerHelper
Helper(*MF
, Info
);
166 ASSERT_TRUE(Helper
.lower(*MIBCTLZ
, 0, s8
) ==
167 LegalizerHelper::LegalizeResult::Legalized
);
170 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
171 CHECK: [[Cst1:%[0-9]+]]:_(s8) = G_CONSTANT i8 1
172 CHECK: [[Sh1:%[0-9]+]]:_(s8) = G_LSHR [[Trunc]]:_, [[Cst1]]:_
173 CHECK: [[Or1:%[0-9]+]]:_(s8) = G_OR [[Trunc]]:_, [[Sh1]]:_
174 CHECK: [[Cst2:%[0-9]+]]:_(s8) = G_CONSTANT i8 2
175 CHECK: [[Sh2:%[0-9]+]]:_(s8) = G_LSHR [[Or1]]:_, [[Cst2]]:_
176 CHECK: [[Or2:%[0-9]+]]:_(s8) = G_OR [[Or1]]:_, [[Sh2]]:_
177 CHECK: [[Cst4:%[0-9]+]]:_(s8) = G_CONSTANT i8 4
178 CHECK: [[Sh4:%[0-9]+]]:_(s8) = G_LSHR [[Or2]]:_, [[Cst4]]:_
179 CHECK: [[Or4:%[0-9]+]]:_(s8) = G_OR [[Or2]]:_, [[Sh4]]:_
180 CHECK: [[CTPOP:%[0-9]+]]:_(s8) = G_CTPOP [[Or4]]:_
181 CHECK: [[Len:%[0-9]+]]:_(s8) = G_CONSTANT i8 8
182 CHECK: [[Sub:%[0-9]+]]:_(s8) = G_SUB [[Len]]:_, [[CTPOP]]:_
186 ASSERT_TRUE(CheckMachineFunction(*MF
, CheckStr
));
190 TEST_F(LegalizerHelperTest
, WidenBitCountingCTLZ
) {
194 // Declare your legalization info
195 DefineLegalizerInfo(A
,
196 { getActionDefinitionsBuilder(G_CTLZ
).legalFor({s16
}); });
199 LLT s8
{LLT::scalar(8)};
200 LLT s16
{LLT::scalar(16)};
201 auto MIBTrunc
= B
.buildTrunc(s8
, Copies
[0]);
202 auto MIBCTLZ
= B
.buildInstr(TargetOpcode::G_CTLZ
, s8
, MIBTrunc
);
203 AInfo
Info(MF
->getSubtarget());
204 LegalizerHelper
Helper(*MF
, Info
);
205 ASSERT_TRUE(Helper
.widenScalar(*MIBCTLZ
, 0, s16
) ==
206 LegalizerHelper::LegalizeResult::Legalized
);
209 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
210 CHECK: [[Zext:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
211 CHECK: [[Ctlz:%[0-9]+]]:_(s16) = G_CTLZ [[Zext]]
212 CHECK: [[Cst8:%[0-9]+]]:_(s16) = G_CONSTANT i16 8
213 CHECK: [[Sub:%[0-9]+]]:_(s16) = G_SUB [[Ctlz]]:_, [[Cst8]]:_
214 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC [[Sub]]
218 ASSERT_TRUE(CheckMachineFunction(*MF
, CheckStr
));
221 // CTLZ_ZERO_UNDEF widening.
222 TEST_F(LegalizerHelperTest
, WidenBitCountingCTLZZeroUndef
) {
226 // Declare your legalization info
228 A
, { getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF
).legalFor({s16
}); });
231 LLT s8
{LLT::scalar(8)};
232 LLT s16
{LLT::scalar(16)};
233 auto MIBTrunc
= B
.buildTrunc(s8
, Copies
[0]);
234 auto MIBCTLZ_ZU
= B
.buildInstr(TargetOpcode::G_CTLZ_ZERO_UNDEF
, s8
, MIBTrunc
);
235 AInfo
Info(MF
->getSubtarget());
236 LegalizerHelper
Helper(*MF
, Info
);
237 ASSERT_TRUE(Helper
.widenScalar(*MIBCTLZ_ZU
, 0, s16
) ==
238 LegalizerHelper::LegalizeResult::Legalized
);
241 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
242 CHECK: [[Zext:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
243 CHECK: [[CtlzZu:%[0-9]+]]:_(s16) = G_CTLZ_ZERO_UNDEF [[Zext]]
244 CHECK: [[Cst8:%[0-9]+]]:_(s16) = G_CONSTANT i16 8
245 CHECK: [[Sub:%[0-9]+]]:_(s16) = G_SUB [[CtlzZu]]:_, [[Cst8]]:_
246 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC [[Sub]]
250 ASSERT_TRUE(CheckMachineFunction(*MF
, CheckStr
));
254 TEST_F(LegalizerHelperTest
, WidenBitCountingCTPOP
) {
258 // Declare your legalization info
260 A
, { getActionDefinitionsBuilder(G_CTPOP
).legalFor({s16
}); });
263 LLT s8
{LLT::scalar(8)};
264 LLT s16
{LLT::scalar(16)};
265 auto MIBTrunc
= B
.buildTrunc(s8
, Copies
[0]);
266 auto MIBCTPOP
= B
.buildInstr(TargetOpcode::G_CTPOP
, s8
, MIBTrunc
);
267 AInfo
Info(MF
->getSubtarget());
268 LegalizerHelper
Helper(*MF
, Info
);
269 ASSERT_TRUE(Helper
.widenScalar(*MIBCTPOP
, 0, s16
) ==
270 LegalizerHelper::LegalizeResult::Legalized
);
273 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
274 CHECK: [[Zext:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
275 CHECK: [[Ctpop:%[0-9]+]]:_(s16) = G_CTPOP [[Zext]]
276 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC [[Ctpop]]
280 ASSERT_TRUE(CheckMachineFunction(*MF
, CheckStr
));
283 // CTTZ_ZERO_UNDEF widening.
284 TEST_F(LegalizerHelperTest
, WidenBitCountingCTTZ_ZERO_UNDEF
) {
288 // Declare your legalization info
290 A
, { getActionDefinitionsBuilder(G_CTTZ_ZERO_UNDEF
).legalFor({s16
}); });
293 LLT s8
{LLT::scalar(8)};
294 LLT s16
{LLT::scalar(16)};
295 auto MIBTrunc
= B
.buildTrunc(s8
, Copies
[0]);
296 auto MIBCTTZ_ZERO_UNDEF
=
297 B
.buildInstr(TargetOpcode::G_CTTZ_ZERO_UNDEF
, s8
, MIBTrunc
);
298 AInfo
Info(MF
->getSubtarget());
299 LegalizerHelper
Helper(*MF
, Info
);
300 ASSERT_TRUE(Helper
.widenScalar(*MIBCTTZ_ZERO_UNDEF
, 0, s16
) ==
301 LegalizerHelper::LegalizeResult::Legalized
);
304 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
305 CHECK: [[Zext:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
306 CHECK: [[CttzZu:%[0-9]+]]:_(s16) = G_CTTZ_ZERO_UNDEF [[Zext]]
307 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC [[CttzZu]]
311 ASSERT_TRUE(CheckMachineFunction(*MF
, CheckStr
));
315 TEST_F(LegalizerHelperTest
, WidenBitCountingCTTZ
) {
319 // Declare your legalization info
320 DefineLegalizerInfo(A
,
321 { getActionDefinitionsBuilder(G_CTTZ
).legalFor({s16
}); });
324 LLT s8
{LLT::scalar(8)};
325 LLT s16
{LLT::scalar(16)};
326 auto MIBTrunc
= B
.buildTrunc(s8
, Copies
[0]);
327 auto MIBCTTZ
= B
.buildInstr(TargetOpcode::G_CTTZ
, s8
, MIBTrunc
);
328 AInfo
Info(MF
->getSubtarget());
329 LegalizerHelper
Helper(*MF
, Info
);
330 ASSERT_TRUE(Helper
.widenScalar(*MIBCTTZ
, 0, s16
) ==
331 LegalizerHelper::LegalizeResult::Legalized
);
334 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
335 CHECK: [[Zext:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
336 CHECK: [[Cst:%[0-9]+]]:_(s16) = G_CONSTANT i16 256
337 CHECK: [[Or:%[0-9]+]]:_(s16) = G_OR [[Zext]]:_, [[Cst]]
338 CHECK: [[Cttz:%[0-9]+]]:_(s16) = G_CTTZ [[Or]]
339 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC [[Cttz]]
343 ASSERT_TRUE(CheckMachineFunction(*MF
, CheckStr
));
346 TEST_F(LegalizerHelperTest
, WidenUADDO
) {
350 // Declare your legalization info
351 DefineLegalizerInfo(A
,
352 { getActionDefinitionsBuilder(G_ADD
).legalFor({s16
}); });
355 LLT s8
{LLT::scalar(8)};
356 LLT s16
{LLT::scalar(16)};
357 auto MIBTrunc
= B
.buildTrunc(s8
, Copies
[0]);
358 unsigned CarryReg
= MRI
->createGenericVirtualRegister(LLT::scalar(1));
359 auto MIBUAddO
= B
.buildInstr(TargetOpcode::G_UADDO
, s8
)
361 .addUse(MIBTrunc
->getOperand(0).getReg())
362 .addUse(MIBTrunc
->getOperand(0).getReg());
363 AInfo
Info(MF
->getSubtarget());
364 LegalizerHelper
Helper(*MF
, Info
);
365 ASSERT_TRUE(Helper
.widenScalar(*MIBUAddO
, 0, s16
) ==
366 LegalizerHelper::LegalizeResult::Legalized
);
369 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
370 CHECK: [[LHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
371 CHECK: [[RHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
372 CHECK: [[ADD:%[0-9]+]]:_(s16) = G_ADD [[LHS]]:_, [[RHS]]:_
373 CHECK: [[CST:%[0-9]+]]:_(s16) = G_CONSTANT i16 255
374 CHECK: [[AND:%[0-9]+]]:_(s16) = G_AND [[ADD]]:_, [[CST]]:_
375 CHECK: G_ICMP intpred(ne), [[ADD]]:_(s16), [[AND]]:_
376 CHECK: G_TRUNC [[ADD]]
380 ASSERT_TRUE(CheckMachineFunction(*MF
, CheckStr
));
384 TEST_F(LegalizerHelperTest
, WidenUSUBO
) {
388 // Declare your legalization info
389 DefineLegalizerInfo(A
,
390 { getActionDefinitionsBuilder(G_SUB
).legalFor({s16
}); });
393 LLT s8
{LLT::scalar(8)};
394 LLT s16
{LLT::scalar(16)};
395 auto MIBTrunc
= B
.buildTrunc(s8
, Copies
[0]);
396 unsigned CarryReg
= MRI
->createGenericVirtualRegister(LLT::scalar(1));
397 auto MIBUSUBO
= B
.buildInstr(TargetOpcode::G_USUBO
, s8
)
399 .addUse(MIBTrunc
->getOperand(0).getReg())
400 .addUse(MIBTrunc
->getOperand(0).getReg());
401 AInfo
Info(MF
->getSubtarget());
402 LegalizerHelper
Helper(*MF
, Info
);
403 ASSERT_TRUE(Helper
.widenScalar(*MIBUSUBO
, 0, s16
) ==
404 LegalizerHelper::LegalizeResult::Legalized
);
407 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
408 CHECK: [[LHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
409 CHECK: [[RHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
410 CHECK: [[SUB:%[0-9]+]]:_(s16) = G_SUB [[LHS]]:_, [[RHS]]:_
411 CHECK: [[CST:%[0-9]+]]:_(s16) = G_CONSTANT i16 255
412 CHECK: [[AND:%[0-9]+]]:_(s16) = G_AND [[SUB]]:_, [[CST]]:_
413 CHECK: G_ICMP intpred(ne), [[SUB]]:_(s16), [[AND]]:_
414 CHECK: G_TRUNC [[SUB]]
418 ASSERT_TRUE(CheckMachineFunction(*MF
, CheckStr
));