blob: 40518d6aa1cea2bd51d36c1857b785a620630ee6 [file] [log] [blame]
Aditya Nandakumar500e3ea2019-01-16 00:40:37 +00001//===- LegalizerHelperTest.cpp
2//-----------------------------------------------===//
Aditya Nandakumarc0333f72018-08-21 17:30:31 +00003//
Chandler Carruth2946cd72019-01-19 08:50:56 +00004// 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
Aditya Nandakumarc0333f72018-08-21 17:30:31 +00007//
8//===----------------------------------------------------------------------===//
9
Aditya Nandakumar500e3ea2019-01-16 00:40:37 +000010#include "GISelMITest.h"
Aditya Nandakumarc0333f72018-08-21 17:30:31 +000011
12namespace {
13
Aditya Nandakumarf75d4f32018-12-05 20:14:52 +000014class DummyGISelObserver : public GISelChangeObserver {
15public:
Aditya Nandakumar500e3ea2019-01-16 00:40:37 +000016 void changingInstr(MachineInstr &MI) override {}
17 void changedInstr(MachineInstr &MI) override {}
18 void createdInstr(MachineInstr &MI) override {}
19 void erasingInstr(MachineInstr &MI) override {}
Aditya Nandakumarf75d4f32018-12-05 20:14:52 +000020};
21
Aditya Nandakumarc0333f72018-08-21 17:30:31 +000022// Test CTTZ expansion when CTTZ_ZERO_UNDEF is legal or custom,
23// in which case it becomes CTTZ_ZERO_UNDEF with select.
Aditya Nandakumar500e3ea2019-01-16 00:40:37 +000024TEST_F(GISelMITest, LowerBitCountingCTTZ0) {
Aditya Nandakumarc0333f72018-08-21 17:30:31 +000025 if (!TM)
26 return;
27
28 // Declare your legalization info
Matt Arsenaultd5684f72019-01-31 02:09:57 +000029 DefineLegalizerInfo(A, {
30 getActionDefinitionsBuilder(G_CTTZ_ZERO_UNDEF).legalFor({{s64, s64}});
31 });
Aditya Nandakumarc0333f72018-08-21 17:30:31 +000032 // Build Instr
Aditya Nandakumarcef44a22018-12-11 00:48:50 +000033 auto MIBCTTZ =
34 B.buildInstr(TargetOpcode::G_CTTZ, {LLT::scalar(64)}, {Copies[0]});
Aditya Nandakumarc0333f72018-08-21 17:30:31 +000035 AInfo Info(MF->getSubtarget());
Aditya Nandakumarf75d4f32018-12-05 20:14:52 +000036 DummyGISelObserver Observer;
Aditya Nandakumar500e3ea2019-01-16 00:40:37 +000037 LegalizerHelper Helper(*MF, Info, Observer, B);
Aditya Nandakumarc0333f72018-08-21 17:30:31 +000038 // Perform Legalization
39 ASSERT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) ==
40 LegalizerHelper::LegalizeResult::Legalized);
41
42 auto CheckStr = R"(
43 CHECK: [[CZU:%[0-9]+]]:_(s64) = G_CTTZ_ZERO_UNDEF %0
44 CHECK: [[ZERO:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
45 CHECK: [[SIXTY4:%[0-9]+]]:_(s64) = G_CONSTANT i64 64
46 CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), %0:_(s64), [[ZERO]]
47 CHECK: [[SEL:%[0-9]+]]:_(s64) = G_SELECT [[CMP]]:_(s1), [[SIXTY4]]:_, [[CZU]]
48 )";
49
50 // Check
51 ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
52}
53
54// CTTZ expansion in terms of CTLZ
Aditya Nandakumar500e3ea2019-01-16 00:40:37 +000055TEST_F(GISelMITest, LowerBitCountingCTTZ1) {
Aditya Nandakumarc0333f72018-08-21 17:30:31 +000056 if (!TM)
57 return;
58
59 // Declare your legalization info
Matt Arsenaultd5684f72019-01-31 02:09:57 +000060 DefineLegalizerInfo(A, {
61 getActionDefinitionsBuilder(G_CTLZ).legalFor({{s64, s64}});
62 });
Aditya Nandakumarc0333f72018-08-21 17:30:31 +000063 // Build Instr
Aditya Nandakumarcef44a22018-12-11 00:48:50 +000064 auto MIBCTTZ =
65 B.buildInstr(TargetOpcode::G_CTTZ, {LLT::scalar(64)}, {Copies[0]});
Aditya Nandakumarc0333f72018-08-21 17:30:31 +000066 AInfo Info(MF->getSubtarget());
Aditya Nandakumarf75d4f32018-12-05 20:14:52 +000067 DummyGISelObserver Observer;
Aditya Nandakumar500e3ea2019-01-16 00:40:37 +000068 LegalizerHelper Helper(*MF, Info, Observer, B);
Aditya Nandakumarc0333f72018-08-21 17:30:31 +000069 // Perform Legalization
70 ASSERT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) ==
71 LegalizerHelper::LegalizeResult::Legalized);
72
73 auto CheckStr = R"(
74 CHECK: [[NEG1:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1
75 CHECK: [[NOT:%[0-9]+]]:_(s64) = G_XOR %0:_, [[NEG1]]
76 CHECK: [[SUB1:%[0-9]+]]:_(s64) = G_ADD %0:_, [[NEG1]]
77 CHECK: [[AND1:%[0-9]+]]:_(s64) = G_AND [[NOT]]:_, [[SUB1]]:_
78 CHECK: [[CST64:%[0-9]+]]:_(s64) = G_CONSTANT i64 64
79 CHECK: [[CTLZ:%[0-9]+]]:_(s64) = G_CTLZ [[AND1]]:_
80 CHECK: G_SUB [[CST64]]:_, [[CTLZ]]:_
81 )";
82
83 // Check
84 ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
85}
86
87// CTTZ expansion in terms of CTPOP
Aditya Nandakumar500e3ea2019-01-16 00:40:37 +000088TEST_F(GISelMITest, LowerBitCountingCTTZ2) {
Aditya Nandakumarc0333f72018-08-21 17:30:31 +000089 if (!TM)
90 return;
91
92 // Declare your legalization info
Matt Arsenaultd5684f72019-01-31 02:09:57 +000093 DefineLegalizerInfo(A, {
94 getActionDefinitionsBuilder(G_CTPOP).legalFor({{s64, s64}});
95 });
Aditya Nandakumarc0333f72018-08-21 17:30:31 +000096 // Build
Aditya Nandakumarcef44a22018-12-11 00:48:50 +000097 auto MIBCTTZ =
98 B.buildInstr(TargetOpcode::G_CTTZ, {LLT::scalar(64)}, {Copies[0]});
Aditya Nandakumarc0333f72018-08-21 17:30:31 +000099 AInfo Info(MF->getSubtarget());
Aditya Nandakumarf75d4f32018-12-05 20:14:52 +0000100 DummyGISelObserver Observer;
Aditya Nandakumar500e3ea2019-01-16 00:40:37 +0000101 LegalizerHelper Helper(*MF, Info, Observer, B);
Aditya Nandakumarc0333f72018-08-21 17:30:31 +0000102 ASSERT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) ==
103 LegalizerHelper::LegalizeResult::Legalized);
104
105 auto CheckStr = R"(
106 CHECK: [[NEG1:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1
107 CHECK: [[NOT:%[0-9]+]]:_(s64) = G_XOR %0:_, [[NEG1]]
108 CHECK: [[SUB1:%[0-9]+]]:_(s64) = G_ADD %0:_, [[NEG1]]
109 CHECK: [[AND1:%[0-9]+]]:_(s64) = G_AND [[NOT]]:_, [[SUB1]]:_
110 CHECK: [[POP:%[0-9]+]]:_(s64) = G_CTPOP [[AND1]]
111 )";
112
113 // Check
114 ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
115}
116
117// CTTZ_ZERO_UNDEF expansion in terms of CTTZ
Aditya Nandakumar500e3ea2019-01-16 00:40:37 +0000118TEST_F(GISelMITest, LowerBitCountingCTTZ3) {
Aditya Nandakumarc0333f72018-08-21 17:30:31 +0000119 if (!TM)
120 return;
121
122 // Declare your legalization info
Matt Arsenaultd5684f72019-01-31 02:09:57 +0000123 DefineLegalizerInfo(A, {
124 getActionDefinitionsBuilder(G_CTTZ).legalFor({{s64, s64}});
125 });
Aditya Nandakumarc0333f72018-08-21 17:30:31 +0000126 // Build
Aditya Nandakumarcef44a22018-12-11 00:48:50 +0000127 auto MIBCTTZ = B.buildInstr(TargetOpcode::G_CTTZ_ZERO_UNDEF,
128 {LLT::scalar(64)}, {Copies[0]});
Aditya Nandakumarc0333f72018-08-21 17:30:31 +0000129 AInfo Info(MF->getSubtarget());
Aditya Nandakumarf75d4f32018-12-05 20:14:52 +0000130 DummyGISelObserver Observer;
Aditya Nandakumar500e3ea2019-01-16 00:40:37 +0000131 LegalizerHelper Helper(*MF, Info, Observer, B);
Aditya Nandakumarc0333f72018-08-21 17:30:31 +0000132 ASSERT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) ==
133 LegalizerHelper::LegalizeResult::Legalized);
134
135 auto CheckStr = R"(
136 CHECK: CTTZ
137 )";
138
139 // Check
140 ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
141}
142
143// CTLZ expansion in terms of CTLZ_ZERO_UNDEF
Aditya Nandakumar500e3ea2019-01-16 00:40:37 +0000144TEST_F(GISelMITest, LowerBitCountingCTLZ0) {
Aditya Nandakumarc0333f72018-08-21 17:30:31 +0000145 if (!TM)
146 return;
147
148 // Declare your legalization info
Matt Arsenaultd5684f72019-01-31 02:09:57 +0000149 DefineLegalizerInfo(A, {
150 getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF).legalFor({{s64, s64}});
151 });
Aditya Nandakumarc0333f72018-08-21 17:30:31 +0000152 // Build
Aditya Nandakumarcef44a22018-12-11 00:48:50 +0000153 auto MIBCTLZ =
154 B.buildInstr(TargetOpcode::G_CTLZ, {LLT::scalar(64)}, {Copies[0]});
Aditya Nandakumarc0333f72018-08-21 17:30:31 +0000155 AInfo Info(MF->getSubtarget());
Aditya Nandakumarf75d4f32018-12-05 20:14:52 +0000156 DummyGISelObserver Observer;
Aditya Nandakumar500e3ea2019-01-16 00:40:37 +0000157 LegalizerHelper Helper(*MF, Info, Observer, B);
Aditya Nandakumarc0333f72018-08-21 17:30:31 +0000158 ASSERT_TRUE(Helper.lower(*MIBCTLZ, 0, LLT::scalar(64)) ==
159 LegalizerHelper::LegalizeResult::Legalized);
160
161 auto CheckStr = R"(
162 CHECK: [[CZU:%[0-9]+]]:_(s64) = G_CTLZ_ZERO_UNDEF %0
163 CHECK: [[ZERO:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
164 CHECK: [[SIXTY4:%[0-9]+]]:_(s64) = G_CONSTANT i64 64
165 CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), %0:_(s64), [[ZERO]]
166 CHECK: [[SEL:%[0-9]+]]:_(s64) = G_SELECT [[CMP]]:_(s1), [[SIXTY4]]:_, [[CZU]]
167 )";
168
169 // Check
170 ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
171}
172
Diana Picus0528e2c2018-11-26 11:07:02 +0000173// CTLZ expansion in terms of CTLZ_ZERO_UNDEF if the latter is a libcall
Aditya Nandakumar500e3ea2019-01-16 00:40:37 +0000174TEST_F(GISelMITest, LowerBitCountingCTLZLibcall) {
Diana Picus0528e2c2018-11-26 11:07:02 +0000175 if (!TM)
176 return;
177
178 // Declare your legalization info
Matt Arsenaultd5684f72019-01-31 02:09:57 +0000179 DefineLegalizerInfo(A, {
180 getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF).libcallFor({{s64, s64}});
181 });
Diana Picus0528e2c2018-11-26 11:07:02 +0000182 // Build
Aditya Nandakumarcef44a22018-12-11 00:48:50 +0000183 auto MIBCTLZ =
184 B.buildInstr(TargetOpcode::G_CTLZ, {LLT::scalar(64)}, {Copies[0]});
Diana Picus0528e2c2018-11-26 11:07:02 +0000185 AInfo Info(MF->getSubtarget());
Aditya Nandakumarf75d4f32018-12-05 20:14:52 +0000186 DummyGISelObserver Observer;
Aditya Nandakumar500e3ea2019-01-16 00:40:37 +0000187 LegalizerHelper Helper(*MF, Info, Observer, B);
Diana Picus0528e2c2018-11-26 11:07:02 +0000188 ASSERT_TRUE(Helper.lower(*MIBCTLZ, 0, LLT::scalar(64)) ==
189 LegalizerHelper::LegalizeResult::Legalized);
190
191 auto CheckStr = R"(
192 CHECK: [[CZU:%[0-9]+]]:_(s64) = G_CTLZ_ZERO_UNDEF %0
193 CHECK: [[ZERO:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
194 CHECK: [[THIRTY2:%[0-9]+]]:_(s64) = G_CONSTANT i64 64
195 CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), %0:_(s64), [[ZERO]]
196 CHECK: [[SEL:%[0-9]+]]:_(s64) = G_SELECT [[CMP]]:_(s1), [[THIRTY2]]:_, [[CZU]]
197 )";
198
199 // Check
200 ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
201}
202
Aditya Nandakumarc0333f72018-08-21 17:30:31 +0000203// CTLZ expansion
Aditya Nandakumar500e3ea2019-01-16 00:40:37 +0000204TEST_F(GISelMITest, LowerBitCountingCTLZ1) {
Aditya Nandakumarc0333f72018-08-21 17:30:31 +0000205 if (!TM)
206 return;
207
208 // Declare your legalization info
Matt Arsenaultd5684f72019-01-31 02:09:57 +0000209 DefineLegalizerInfo(A, {
210 getActionDefinitionsBuilder(G_CTPOP).legalFor({{s8, s8}});
211 });
Aditya Nandakumarc0333f72018-08-21 17:30:31 +0000212 // Build
213 // Trunc it to s8.
214 LLT s8{LLT::scalar(8)};
215 auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
Aditya Nandakumarcef44a22018-12-11 00:48:50 +0000216 auto MIBCTLZ = B.buildInstr(TargetOpcode::G_CTLZ, {s8}, {MIBTrunc});
Aditya Nandakumarc0333f72018-08-21 17:30:31 +0000217 AInfo Info(MF->getSubtarget());
Aditya Nandakumarf75d4f32018-12-05 20:14:52 +0000218 DummyGISelObserver Observer;
Aditya Nandakumar500e3ea2019-01-16 00:40:37 +0000219 LegalizerHelper Helper(*MF, Info, Observer, B);
Aditya Nandakumarc0333f72018-08-21 17:30:31 +0000220 ASSERT_TRUE(Helper.lower(*MIBCTLZ, 0, s8) ==
221 LegalizerHelper::LegalizeResult::Legalized);
222
223 auto CheckStr = R"(
224 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
225 CHECK: [[Cst1:%[0-9]+]]:_(s8) = G_CONSTANT i8 1
226 CHECK: [[Sh1:%[0-9]+]]:_(s8) = G_LSHR [[Trunc]]:_, [[Cst1]]:_
227 CHECK: [[Or1:%[0-9]+]]:_(s8) = G_OR [[Trunc]]:_, [[Sh1]]:_
228 CHECK: [[Cst2:%[0-9]+]]:_(s8) = G_CONSTANT i8 2
229 CHECK: [[Sh2:%[0-9]+]]:_(s8) = G_LSHR [[Or1]]:_, [[Cst2]]:_
230 CHECK: [[Or2:%[0-9]+]]:_(s8) = G_OR [[Or1]]:_, [[Sh2]]:_
231 CHECK: [[Cst4:%[0-9]+]]:_(s8) = G_CONSTANT i8 4
232 CHECK: [[Sh4:%[0-9]+]]:_(s8) = G_LSHR [[Or2]]:_, [[Cst4]]:_
233 CHECK: [[Or4:%[0-9]+]]:_(s8) = G_OR [[Or2]]:_, [[Sh4]]:_
234 CHECK: [[CTPOP:%[0-9]+]]:_(s8) = G_CTPOP [[Or4]]:_
235 CHECK: [[Len:%[0-9]+]]:_(s8) = G_CONSTANT i8 8
236 CHECK: [[Sub:%[0-9]+]]:_(s8) = G_SUB [[Len]]:_, [[CTPOP]]:_
237 )";
238
239 // Check
240 ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
241}
Aditya Nandakumarc1061832018-08-22 17:59:18 +0000242
243// CTLZ widening.
Aditya Nandakumar500e3ea2019-01-16 00:40:37 +0000244TEST_F(GISelMITest, WidenBitCountingCTLZ) {
Aditya Nandakumarc1061832018-08-22 17:59:18 +0000245 if (!TM)
246 return;
247
248 // Declare your legalization info
Matt Arsenaultd5684f72019-01-31 02:09:57 +0000249 DefineLegalizerInfo(A, {
250 getActionDefinitionsBuilder(G_CTLZ).legalFor({{s16, s16}});
251 });
Aditya Nandakumarc1061832018-08-22 17:59:18 +0000252 // Build
253 // Trunc it to s8.
254 LLT s8{LLT::scalar(8)};
255 LLT s16{LLT::scalar(16)};
256 auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
Aditya Nandakumarcef44a22018-12-11 00:48:50 +0000257 auto MIBCTLZ = B.buildInstr(TargetOpcode::G_CTLZ, {s8}, {MIBTrunc});
Aditya Nandakumarc1061832018-08-22 17:59:18 +0000258 AInfo Info(MF->getSubtarget());
Aditya Nandakumarf75d4f32018-12-05 20:14:52 +0000259 DummyGISelObserver Observer;
Aditya Nandakumar500e3ea2019-01-16 00:40:37 +0000260 LegalizerHelper Helper(*MF, Info, Observer, B);
Matt Arsenaultd5684f72019-01-31 02:09:57 +0000261 ASSERT_TRUE(Helper.widenScalar(*MIBCTLZ, 1, s16) ==
Aditya Nandakumarc1061832018-08-22 17:59:18 +0000262 LegalizerHelper::LegalizeResult::Legalized);
263
264 auto CheckStr = R"(
265 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
266 CHECK: [[Zext:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
267 CHECK: [[Ctlz:%[0-9]+]]:_(s16) = G_CTLZ [[Zext]]
268 CHECK: [[Cst8:%[0-9]+]]:_(s16) = G_CONSTANT i16 8
269 CHECK: [[Sub:%[0-9]+]]:_(s16) = G_SUB [[Ctlz]]:_, [[Cst8]]:_
270 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC [[Sub]]
271 )";
272
273 // Check
274 ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
275}
276
277// CTLZ_ZERO_UNDEF widening.
Aditya Nandakumar500e3ea2019-01-16 00:40:37 +0000278TEST_F(GISelMITest, WidenBitCountingCTLZZeroUndef) {
Aditya Nandakumarc1061832018-08-22 17:59:18 +0000279 if (!TM)
280 return;
281
282 // Declare your legalization info
Matt Arsenaultd5684f72019-01-31 02:09:57 +0000283 DefineLegalizerInfo(A, {
284 getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF).legalFor({{s16, s16}});
285 });
Aditya Nandakumarc1061832018-08-22 17:59:18 +0000286 // Build
287 // Trunc it to s8.
288 LLT s8{LLT::scalar(8)};
289 LLT s16{LLT::scalar(16)};
290 auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
Aditya Nandakumarcef44a22018-12-11 00:48:50 +0000291 auto MIBCTLZ_ZU =
292 B.buildInstr(TargetOpcode::G_CTLZ_ZERO_UNDEF, {s8}, {MIBTrunc});
Aditya Nandakumarc1061832018-08-22 17:59:18 +0000293 AInfo Info(MF->getSubtarget());
Aditya Nandakumarf75d4f32018-12-05 20:14:52 +0000294 DummyGISelObserver Observer;
Aditya Nandakumar500e3ea2019-01-16 00:40:37 +0000295 LegalizerHelper Helper(*MF, Info, Observer, B);
Matt Arsenaultd5684f72019-01-31 02:09:57 +0000296 ASSERT_TRUE(Helper.widenScalar(*MIBCTLZ_ZU, 1, s16) ==
Aditya Nandakumarc1061832018-08-22 17:59:18 +0000297 LegalizerHelper::LegalizeResult::Legalized);
298
299 auto CheckStr = R"(
300 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
301 CHECK: [[Zext:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
302 CHECK: [[CtlzZu:%[0-9]+]]:_(s16) = G_CTLZ_ZERO_UNDEF [[Zext]]
303 CHECK: [[Cst8:%[0-9]+]]:_(s16) = G_CONSTANT i16 8
304 CHECK: [[Sub:%[0-9]+]]:_(s16) = G_SUB [[CtlzZu]]:_, [[Cst8]]:_
305 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC [[Sub]]
306 )";
307
308 // Check
309 ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
310}
311
312// CTPOP widening.
Aditya Nandakumar500e3ea2019-01-16 00:40:37 +0000313TEST_F(GISelMITest, WidenBitCountingCTPOP) {
Aditya Nandakumarc1061832018-08-22 17:59:18 +0000314 if (!TM)
315 return;
316
317 // Declare your legalization info
Matt Arsenaultd5684f72019-01-31 02:09:57 +0000318 DefineLegalizerInfo(A, {
319 getActionDefinitionsBuilder(G_CTPOP).legalFor({{s16, s16}});
320 });
Aditya Nandakumarc1061832018-08-22 17:59:18 +0000321 // Build
322 // Trunc it to s8.
323 LLT s8{LLT::scalar(8)};
324 LLT s16{LLT::scalar(16)};
325 auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
Aditya Nandakumarcef44a22018-12-11 00:48:50 +0000326 auto MIBCTPOP = B.buildInstr(TargetOpcode::G_CTPOP, {s8}, {MIBTrunc});
Aditya Nandakumarc1061832018-08-22 17:59:18 +0000327 AInfo Info(MF->getSubtarget());
Aditya Nandakumarf75d4f32018-12-05 20:14:52 +0000328 DummyGISelObserver Observer;
Aditya Nandakumar500e3ea2019-01-16 00:40:37 +0000329 LegalizerHelper Helper(*MF, Info, Observer, B);
Matt Arsenaultd5684f72019-01-31 02:09:57 +0000330 ASSERT_TRUE(Helper.widenScalar(*MIBCTPOP, 1, s16) ==
Aditya Nandakumarc1061832018-08-22 17:59:18 +0000331 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: [[Ctpop:%[0-9]+]]:_(s16) = G_CTPOP [[Zext]]
337 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC [[Ctpop]]
338 )";
339
340 // Check
341 ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
342}
343
344// CTTZ_ZERO_UNDEF widening.
Aditya Nandakumar500e3ea2019-01-16 00:40:37 +0000345TEST_F(GISelMITest, WidenBitCountingCTTZ_ZERO_UNDEF) {
Aditya Nandakumarc1061832018-08-22 17:59:18 +0000346 if (!TM)
347 return;
348
349 // Declare your legalization info
Matt Arsenaultd5684f72019-01-31 02:09:57 +0000350 DefineLegalizerInfo(A, {
351 getActionDefinitionsBuilder(G_CTTZ_ZERO_UNDEF).legalFor({{s16, s16}});
352 });
Aditya Nandakumarc1061832018-08-22 17:59:18 +0000353 // Build
354 // Trunc it to s8.
355 LLT s8{LLT::scalar(8)};
356 LLT s16{LLT::scalar(16)};
357 auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
358 auto MIBCTTZ_ZERO_UNDEF =
Aditya Nandakumarcef44a22018-12-11 00:48:50 +0000359 B.buildInstr(TargetOpcode::G_CTTZ_ZERO_UNDEF, {s8}, {MIBTrunc});
Aditya Nandakumarc1061832018-08-22 17:59:18 +0000360 AInfo Info(MF->getSubtarget());
Aditya Nandakumarf75d4f32018-12-05 20:14:52 +0000361 DummyGISelObserver Observer;
Aditya Nandakumar500e3ea2019-01-16 00:40:37 +0000362 LegalizerHelper Helper(*MF, Info, Observer, B);
Matt Arsenaultd5684f72019-01-31 02:09:57 +0000363 ASSERT_TRUE(Helper.widenScalar(*MIBCTTZ_ZERO_UNDEF, 1, s16) ==
Aditya Nandakumarc1061832018-08-22 17:59:18 +0000364 LegalizerHelper::LegalizeResult::Legalized);
365
366 auto CheckStr = R"(
367 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
368 CHECK: [[Zext:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
369 CHECK: [[CttzZu:%[0-9]+]]:_(s16) = G_CTTZ_ZERO_UNDEF [[Zext]]
370 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC [[CttzZu]]
371 )";
372
373 // Check
374 ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
375}
376
377// CTTZ widening.
Aditya Nandakumar500e3ea2019-01-16 00:40:37 +0000378TEST_F(GISelMITest, WidenBitCountingCTTZ) {
Aditya Nandakumarc1061832018-08-22 17:59:18 +0000379 if (!TM)
380 return;
381
382 // Declare your legalization info
Matt Arsenaultd5684f72019-01-31 02:09:57 +0000383 DefineLegalizerInfo(A, {
384 getActionDefinitionsBuilder(G_CTTZ).legalFor({{s16, s16}});
385 });
Aditya Nandakumarc1061832018-08-22 17:59:18 +0000386 // Build
387 // Trunc it to s8.
388 LLT s8{LLT::scalar(8)};
389 LLT s16{LLT::scalar(16)};
390 auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
Aditya Nandakumarcef44a22018-12-11 00:48:50 +0000391 auto MIBCTTZ = B.buildInstr(TargetOpcode::G_CTTZ, {s8}, {MIBTrunc});
Aditya Nandakumarc1061832018-08-22 17:59:18 +0000392 AInfo Info(MF->getSubtarget());
Aditya Nandakumarf75d4f32018-12-05 20:14:52 +0000393 DummyGISelObserver Observer;
Aditya Nandakumar500e3ea2019-01-16 00:40:37 +0000394 LegalizerHelper Helper(*MF, Info, Observer, B);
Matt Arsenaultd5684f72019-01-31 02:09:57 +0000395 ASSERT_TRUE(Helper.widenScalar(*MIBCTTZ, 1, s16) ==
Aditya Nandakumarc1061832018-08-22 17:59:18 +0000396 LegalizerHelper::LegalizeResult::Legalized);
397
398 auto CheckStr = R"(
399 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
400 CHECK: [[Zext:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
401 CHECK: [[Cst:%[0-9]+]]:_(s16) = G_CONSTANT i16 256
402 CHECK: [[Or:%[0-9]+]]:_(s16) = G_OR [[Zext]]:_, [[Cst]]
403 CHECK: [[Cttz:%[0-9]+]]:_(s16) = G_CTTZ [[Or]]
404 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC [[Cttz]]
405 )";
406
407 // Check
408 ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
409}
Aditya Nandakumar6d47a412018-08-29 03:17:08 +0000410// UADDO widening.
Aditya Nandakumar500e3ea2019-01-16 00:40:37 +0000411TEST_F(GISelMITest, WidenUADDO) {
Aditya Nandakumar6d47a412018-08-29 03:17:08 +0000412 if (!TM)
413 return;
414
415 // Declare your legalization info
Matt Arsenaultd5684f72019-01-31 02:09:57 +0000416 DefineLegalizerInfo(A, {
417 getActionDefinitionsBuilder(G_ADD).legalFor({{s16, s16}});
418 });
Aditya Nandakumar6d47a412018-08-29 03:17:08 +0000419 // Build
420 // Trunc it to s8.
421 LLT s8{LLT::scalar(8)};
422 LLT s16{LLT::scalar(16)};
423 auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
424 unsigned CarryReg = MRI->createGenericVirtualRegister(LLT::scalar(1));
Aditya Nandakumarcef44a22018-12-11 00:48:50 +0000425 auto MIBUAddO =
426 B.buildInstr(TargetOpcode::G_UADDO, {s8, CarryReg}, {MIBTrunc, MIBTrunc});
Aditya Nandakumar6d47a412018-08-29 03:17:08 +0000427 AInfo Info(MF->getSubtarget());
Aditya Nandakumarf75d4f32018-12-05 20:14:52 +0000428 DummyGISelObserver Observer;
Aditya Nandakumar500e3ea2019-01-16 00:40:37 +0000429 LegalizerHelper Helper(*MF, Info, Observer, B);
Aditya Nandakumar6d47a412018-08-29 03:17:08 +0000430 ASSERT_TRUE(Helper.widenScalar(*MIBUAddO, 0, s16) ==
431 LegalizerHelper::LegalizeResult::Legalized);
432
433 auto CheckStr = R"(
434 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
435 CHECK: [[LHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
436 CHECK: [[RHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
437 CHECK: [[ADD:%[0-9]+]]:_(s16) = G_ADD [[LHS]]:_, [[RHS]]:_
438 CHECK: [[CST:%[0-9]+]]:_(s16) = G_CONSTANT i16 255
439 CHECK: [[AND:%[0-9]+]]:_(s16) = G_AND [[ADD]]:_, [[CST]]:_
440 CHECK: G_ICMP intpred(ne), [[ADD]]:_(s16), [[AND]]:_
441 CHECK: G_TRUNC [[ADD]]
442 )";
443
444 // Check
445 ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
446}
447
448// USUBO widening.
Aditya Nandakumar500e3ea2019-01-16 00:40:37 +0000449TEST_F(GISelMITest, WidenUSUBO) {
Aditya Nandakumar6d47a412018-08-29 03:17:08 +0000450 if (!TM)
451 return;
452
453 // Declare your legalization info
Matt Arsenaultd5684f72019-01-31 02:09:57 +0000454 DefineLegalizerInfo(A, {
455 getActionDefinitionsBuilder(G_SUB).legalFor({{s16, s16}});
456 });
Aditya Nandakumar6d47a412018-08-29 03:17:08 +0000457 // Build
458 // Trunc it to s8.
459 LLT s8{LLT::scalar(8)};
460 LLT s16{LLT::scalar(16)};
461 auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
462 unsigned CarryReg = MRI->createGenericVirtualRegister(LLT::scalar(1));
Aditya Nandakumarcef44a22018-12-11 00:48:50 +0000463 auto MIBUSUBO =
464 B.buildInstr(TargetOpcode::G_USUBO, {s8, CarryReg}, {MIBTrunc, MIBTrunc});
Aditya Nandakumar6d47a412018-08-29 03:17:08 +0000465 AInfo Info(MF->getSubtarget());
Aditya Nandakumarf75d4f32018-12-05 20:14:52 +0000466 DummyGISelObserver Observer;
Aditya Nandakumar500e3ea2019-01-16 00:40:37 +0000467 LegalizerHelper Helper(*MF, Info, Observer, B);
Aditya Nandakumar6d47a412018-08-29 03:17:08 +0000468 ASSERT_TRUE(Helper.widenScalar(*MIBUSUBO, 0, s16) ==
469 LegalizerHelper::LegalizeResult::Legalized);
470
471 auto CheckStr = R"(
472 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
473 CHECK: [[LHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
474 CHECK: [[RHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
475 CHECK: [[SUB:%[0-9]+]]:_(s16) = G_SUB [[LHS]]:_, [[RHS]]:_
476 CHECK: [[CST:%[0-9]+]]:_(s16) = G_CONSTANT i16 255
477 CHECK: [[AND:%[0-9]+]]:_(s16) = G_AND [[SUB]]:_, [[CST]]:_
478 CHECK: G_ICMP intpred(ne), [[SUB]]:_(s16), [[AND]]:_
479 CHECK: G_TRUNC [[SUB]]
480 )";
481
482 // Check
483 ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
484}
Aditya Nandakumarc0333f72018-08-21 17:30:31 +0000485} // namespace