blob: 65d0d73166a24e9563841782fab69c93a77290fd [file] [log] [blame]
Aditya Nandakumarc0333f72018-08-21 17:30:31 +00001//===- PatternMatchTest.cpp -----------------------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "LegalizerHelperTest.h"
11
12namespace {
13
14// Test CTTZ expansion when CTTZ_ZERO_UNDEF is legal or custom,
15// in which case it becomes CTTZ_ZERO_UNDEF with select.
16TEST_F(LegalizerHelperTest, LowerBitCountingCTTZ0) {
17 if (!TM)
18 return;
19
20 // Declare your legalization info
21 DefineLegalizerInfo(
22 A, { getActionDefinitionsBuilder(G_CTTZ_ZERO_UNDEF).legalFor({s64}); });
23 // Build Instr
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);
30
31 auto CheckStr = R"(
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]]
37 )";
38
39 // Check
40 ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
41}
42
43// CTTZ expansion in terms of CTLZ
44TEST_F(LegalizerHelperTest, LowerBitCountingCTTZ1) {
45 if (!TM)
46 return;
47
48 // Declare your legalization info
49 DefineLegalizerInfo(A,
50 { getActionDefinitionsBuilder(G_CTLZ).legalFor({s64}); });
51 // Build Instr
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);
58
59 auto CheckStr = R"(
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]]:_
67 )";
68
69 // Check
70 ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
71}
72
73// CTTZ expansion in terms of CTPOP
74TEST_F(LegalizerHelperTest, LowerBitCountingCTTZ2) {
75 if (!TM)
76 return;
77
78 // Declare your legalization info
79 DefineLegalizerInfo(
80 A, { getActionDefinitionsBuilder(G_CTPOP).legalFor({s64}); });
81 // Build
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);
87
88 auto CheckStr = R"(
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]]
94 )";
95
96 // Check
97 ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
98}
99
100// CTTZ_ZERO_UNDEF expansion in terms of CTTZ
101TEST_F(LegalizerHelperTest, LowerBitCountingCTTZ3) {
102 if (!TM)
103 return;
104
105 // Declare your legalization info
106 DefineLegalizerInfo(A,
107 { getActionDefinitionsBuilder(G_CTTZ).legalFor({s64}); });
108 // Build
109 auto MIBCTTZ =
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);
115
116 auto CheckStr = R"(
117 CHECK: CTTZ
118 )";
119
120 // Check
121 ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
122}
123
124// CTLZ expansion in terms of CTLZ_ZERO_UNDEF
125TEST_F(LegalizerHelperTest, LowerBitCountingCTLZ0) {
126 if (!TM)
127 return;
128
129 // Declare your legalization info
130 DefineLegalizerInfo(
131 A, { getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF).legalFor({s64}); });
132 // Build
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);
138
139 auto CheckStr = R"(
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]]
145 )";
146
147 // Check
148 ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
149}
150
151// CTLZ expansion
152TEST_F(LegalizerHelperTest, LowerBitCountingCTLZ1) {
153 if (!TM)
154 return;
155
156 // Declare your legalization info
157 DefineLegalizerInfo(A,
158 { getActionDefinitionsBuilder(G_CTPOP).legalFor({s8}); });
159 // Build
160 // Trunc it to 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);
168
169 auto CheckStr = R"(
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]]:_
183 )";
184
185 // Check
186 ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
187}
Aditya Nandakumarc1061832018-08-22 17:59:18 +0000188
189// CTLZ widening.
190TEST_F(LegalizerHelperTest, WidenBitCountingCTLZ) {
191 if (!TM)
192 return;
193
194 // Declare your legalization info
195 DefineLegalizerInfo(A,
196 { getActionDefinitionsBuilder(G_CTLZ).legalFor({s16}); });
197 // Build
198 // Trunc it to s8.
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);
207
208 auto CheckStr = R"(
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]]
215 )";
216
217 // Check
218 ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
219}
220
221// CTLZ_ZERO_UNDEF widening.
222TEST_F(LegalizerHelperTest, WidenBitCountingCTLZZeroUndef) {
223 if (!TM)
224 return;
225
226 // Declare your legalization info
227 DefineLegalizerInfo(
228 A, { getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF).legalFor({s16}); });
229 // Build
230 // Trunc it to s8.
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);
239
240 auto CheckStr = R"(
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]]
247 )";
248
249 // Check
250 ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
251}
252
253// CTPOP widening.
254TEST_F(LegalizerHelperTest, WidenBitCountingCTPOP) {
255 if (!TM)
256 return;
257
258 // Declare your legalization info
259 DefineLegalizerInfo(
260 A, { getActionDefinitionsBuilder(G_CTPOP).legalFor({s16}); });
261 // Build
262 // Trunc it to s8.
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);
271
272 auto CheckStr = R"(
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]]
277 )";
278
279 // Check
280 ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
281}
282
283// CTTZ_ZERO_UNDEF widening.
284TEST_F(LegalizerHelperTest, WidenBitCountingCTTZ_ZERO_UNDEF) {
285 if (!TM)
286 return;
287
288 // Declare your legalization info
289 DefineLegalizerInfo(
290 A, { getActionDefinitionsBuilder(G_CTTZ_ZERO_UNDEF).legalFor({s16}); });
291 // Build
292 // Trunc it to s8.
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);
302
303 auto CheckStr = R"(
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]]
308 )";
309
310 // Check
311 ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
312}
313
314// CTTZ widening.
315TEST_F(LegalizerHelperTest, WidenBitCountingCTTZ) {
316 if (!TM)
317 return;
318
319 // Declare your legalization info
320 DefineLegalizerInfo(A,
321 { getActionDefinitionsBuilder(G_CTTZ).legalFor({s16}); });
322 // Build
323 // Trunc it to s8.
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);
332
333 auto CheckStr = R"(
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]]
340 )";
341
342 // Check
343 ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
344}
Aditya Nandakumarc0333f72018-08-21 17:30:31 +0000345} // namespace