1 //===- PatternMatchTest.cpp -----------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "GISelMITest.h"
10 #include "llvm/CodeGen/GlobalISel/ConstantFoldingMIRBuilder.h"
11 #include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
12 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
13 #include "llvm/CodeGen/GlobalISel/Utils.h"
14 #include "llvm/CodeGen/MIRParser/MIRParser.h"
15 #include "llvm/CodeGen/MachineFunction.h"
16 #include "llvm/CodeGen/MachineModuleInfo.h"
17 #include "llvm/CodeGen/TargetFrameLowering.h"
18 #include "llvm/CodeGen/TargetInstrInfo.h"
19 #include "llvm/CodeGen/TargetLowering.h"
20 #include "llvm/CodeGen/TargetSubtargetInfo.h"
21 #include "llvm/Support/SourceMgr.h"
22 #include "llvm/Support/TargetRegistry.h"
23 #include "llvm/Support/TargetSelect.h"
24 #include "llvm/Target/TargetMachine.h"
25 #include "llvm/Target/TargetOptions.h"
26 #include "gtest/gtest.h"
27
28 using namespace llvm;
29 using namespace MIPatternMatch;
30
31 namespace {
32
TEST_F(AArch64GISelMITest,MatchIntConstant)33 TEST_F(AArch64GISelMITest, MatchIntConstant) {
34 setUp();
35 if (!TM)
36 return;
37 auto MIBCst = B.buildConstant(LLT::scalar(64), 42);
38 int64_t Cst;
39 bool match = mi_match(MIBCst.getReg(0), *MRI, m_ICst(Cst));
40 EXPECT_TRUE(match);
41 EXPECT_EQ(Cst, 42);
42 }
43
TEST_F(AArch64GISelMITest,MatchBinaryOp)44 TEST_F(AArch64GISelMITest, MatchBinaryOp) {
45 setUp();
46 if (!TM)
47 return;
48 LLT s32 = LLT::scalar(32);
49 LLT s64 = LLT::scalar(64);
50 auto MIBAdd = B.buildAdd(s64, Copies[0], Copies[1]);
51 // Test case for no bind.
52 bool match =
53 mi_match(MIBAdd.getReg(0), *MRI, m_GAdd(m_Reg(), m_Reg()));
54 EXPECT_TRUE(match);
55 Register Src0, Src1, Src2;
56 match = mi_match(MIBAdd.getReg(0), *MRI,
57 m_GAdd(m_Reg(Src0), m_Reg(Src1)));
58 EXPECT_TRUE(match);
59 EXPECT_EQ(Src0, Copies[0]);
60 EXPECT_EQ(Src1, Copies[1]);
61
62 // Build MUL(ADD %0, %1), %2
63 auto MIBMul = B.buildMul(s64, MIBAdd, Copies[2]);
64
65 // Try to match MUL.
66 match = mi_match(MIBMul.getReg(0), *MRI,
67 m_GMul(m_Reg(Src0), m_Reg(Src1)));
68 EXPECT_TRUE(match);
69 EXPECT_EQ(Src0, MIBAdd.getReg(0));
70 EXPECT_EQ(Src1, Copies[2]);
71
72 // Try to match MUL(ADD)
73 match = mi_match(MIBMul.getReg(0), *MRI,
74 m_GMul(m_GAdd(m_Reg(Src0), m_Reg(Src1)), m_Reg(Src2)));
75 EXPECT_TRUE(match);
76 EXPECT_EQ(Src0, Copies[0]);
77 EXPECT_EQ(Src1, Copies[1]);
78 EXPECT_EQ(Src2, Copies[2]);
79
80 // Test Commutativity.
81 auto MIBMul2 = B.buildMul(s64, Copies[0], B.buildConstant(s64, 42));
82 // Try to match MUL(Cst, Reg) on src of MUL(Reg, Cst) to validate
83 // commutativity.
84 int64_t Cst;
85 match = mi_match(MIBMul2.getReg(0), *MRI,
86 m_GMul(m_ICst(Cst), m_Reg(Src0)));
87 EXPECT_TRUE(match);
88 EXPECT_EQ(Cst, 42);
89 EXPECT_EQ(Src0, Copies[0]);
90
91 // Make sure commutative doesn't work with something like SUB.
92 auto MIBSub = B.buildSub(s64, Copies[0], B.buildConstant(s64, 42));
93 match = mi_match(MIBSub.getReg(0), *MRI,
94 m_GSub(m_ICst(Cst), m_Reg(Src0)));
95 EXPECT_FALSE(match);
96
97 auto MIBFMul = B.buildInstr(TargetOpcode::G_FMUL, {s64},
98 {Copies[0], B.buildConstant(s64, 42)});
99 // Match and test commutativity for FMUL.
100 match = mi_match(MIBFMul.getReg(0), *MRI,
101 m_GFMul(m_ICst(Cst), m_Reg(Src0)));
102 EXPECT_TRUE(match);
103 EXPECT_EQ(Cst, 42);
104 EXPECT_EQ(Src0, Copies[0]);
105
106 // FSUB
107 auto MIBFSub = B.buildInstr(TargetOpcode::G_FSUB, {s64},
108 {Copies[0], B.buildConstant(s64, 42)});
109 match = mi_match(MIBFSub.getReg(0), *MRI,
110 m_GFSub(m_Reg(Src0), m_Reg()));
111 EXPECT_TRUE(match);
112 EXPECT_EQ(Src0, Copies[0]);
113
114 // Build AND %0, %1
115 auto MIBAnd = B.buildAnd(s64, Copies[0], Copies[1]);
116 // Try to match AND.
117 match = mi_match(MIBAnd.getReg(0), *MRI,
118 m_GAnd(m_Reg(Src0), m_Reg(Src1)));
119 EXPECT_TRUE(match);
120 EXPECT_EQ(Src0, Copies[0]);
121 EXPECT_EQ(Src1, Copies[1]);
122
123 // Build OR %0, %1
124 auto MIBOr = B.buildOr(s64, Copies[0], Copies[1]);
125 // Try to match OR.
126 match = mi_match(MIBOr.getReg(0), *MRI,
127 m_GOr(m_Reg(Src0), m_Reg(Src1)));
128 EXPECT_TRUE(match);
129 EXPECT_EQ(Src0, Copies[0]);
130 EXPECT_EQ(Src1, Copies[1]);
131
132 // Match lshr, and make sure a different shift amount type works.
133 auto TruncCopy1 = B.buildTrunc(s32, Copies[1]);
134 auto LShr = B.buildLShr(s64, Copies[0], TruncCopy1);
135 match = mi_match(LShr.getReg(0), *MRI,
136 m_GLShr(m_Reg(Src0), m_Reg(Src1)));
137 EXPECT_TRUE(match);
138 EXPECT_EQ(Src0, Copies[0]);
139 EXPECT_EQ(Src1, TruncCopy1.getReg(0));
140
141 // Match shl, and make sure a different shift amount type works.
142 auto Shl = B.buildShl(s64, Copies[0], TruncCopy1);
143 match = mi_match(Shl.getReg(0), *MRI,
144 m_GShl(m_Reg(Src0), m_Reg(Src1)));
145 EXPECT_TRUE(match);
146 EXPECT_EQ(Src0, Copies[0]);
147 EXPECT_EQ(Src1, TruncCopy1.getReg(0));
148 }
149
TEST_F(AArch64GISelMITest,MatchICmp)150 TEST_F(AArch64GISelMITest, MatchICmp) {
151 setUp();
152 if (!TM)
153 return;
154
155 const LLT s1 = LLT::scalar(1);
156 auto CmpEq = B.buildICmp(CmpInst::ICMP_EQ, s1, Copies[0], Copies[1]);
157
158 // Check match any predicate.
159 bool match =
160 mi_match(CmpEq.getReg(0), *MRI, m_GICmp(m_Pred(), m_Reg(), m_Reg()));
161 EXPECT_TRUE(match);
162
163 // Check we get the predicate and registers.
164 CmpInst::Predicate Pred;
165 Register Reg0;
166 Register Reg1;
167 match = mi_match(CmpEq.getReg(0), *MRI,
168 m_GICmp(m_Pred(Pred), m_Reg(Reg0), m_Reg(Reg1)));
169 EXPECT_TRUE(match);
170 EXPECT_EQ(CmpInst::ICMP_EQ, Pred);
171 EXPECT_EQ(Copies[0], Reg0);
172 EXPECT_EQ(Copies[1], Reg1);
173 }
174
TEST_F(AArch64GISelMITest,MatchFCmp)175 TEST_F(AArch64GISelMITest, MatchFCmp) {
176 setUp();
177 if (!TM)
178 return;
179
180 const LLT s1 = LLT::scalar(1);
181 auto CmpEq = B.buildFCmp(CmpInst::FCMP_OEQ, s1, Copies[0], Copies[1]);
182
183 // Check match any predicate.
184 bool match =
185 mi_match(CmpEq.getReg(0), *MRI, m_GFCmp(m_Pred(), m_Reg(), m_Reg()));
186 EXPECT_TRUE(match);
187
188 // Check we get the predicate and registers.
189 CmpInst::Predicate Pred;
190 Register Reg0;
191 Register Reg1;
192 match = mi_match(CmpEq.getReg(0), *MRI,
193 m_GFCmp(m_Pred(Pred), m_Reg(Reg0), m_Reg(Reg1)));
194 EXPECT_TRUE(match);
195 EXPECT_EQ(CmpInst::FCMP_OEQ, Pred);
196 EXPECT_EQ(Copies[0], Reg0);
197 EXPECT_EQ(Copies[1], Reg1);
198 }
199
TEST_F(AArch64GISelMITest,MatchFPUnaryOp)200 TEST_F(AArch64GISelMITest, MatchFPUnaryOp) {
201 setUp();
202 if (!TM)
203 return;
204
205 // Truncate s64 to s32.
206 LLT s32 = LLT::scalar(32);
207 auto Copy0s32 = B.buildFPTrunc(s32, Copies[0]);
208
209 // Match G_FABS.
210 auto MIBFabs = B.buildInstr(TargetOpcode::G_FABS, {s32}, {Copy0s32});
211 bool match =
212 mi_match(MIBFabs.getReg(0), *MRI, m_GFabs(m_Reg()));
213 EXPECT_TRUE(match);
214
215 Register Src;
216 auto MIBFNeg = B.buildInstr(TargetOpcode::G_FNEG, {s32}, {Copy0s32});
217 match = mi_match(MIBFNeg.getReg(0), *MRI, m_GFNeg(m_Reg(Src)));
218 EXPECT_TRUE(match);
219 EXPECT_EQ(Src, Copy0s32.getReg(0));
220
221 match = mi_match(MIBFabs.getReg(0), *MRI, m_GFabs(m_Reg(Src)));
222 EXPECT_TRUE(match);
223 EXPECT_EQ(Src, Copy0s32.getReg(0));
224
225 // Build and match FConstant.
226 auto MIBFCst = B.buildFConstant(s32, .5);
227 const ConstantFP *TmpFP{};
228 match = mi_match(MIBFCst.getReg(0), *MRI, m_GFCst(TmpFP));
229 EXPECT_TRUE(match);
230 EXPECT_TRUE(TmpFP);
231 APFloat APF((float).5);
232 auto *CFP = ConstantFP::get(Context, APF);
233 EXPECT_EQ(CFP, TmpFP);
234
235 // Build double float.
236 LLT s64 = LLT::scalar(64);
237 auto MIBFCst64 = B.buildFConstant(s64, .5);
238 const ConstantFP *TmpFP64{};
239 match = mi_match(MIBFCst64.getReg(0), *MRI, m_GFCst(TmpFP64));
240 EXPECT_TRUE(match);
241 EXPECT_TRUE(TmpFP64);
242 APFloat APF64(.5);
243 auto CFP64 = ConstantFP::get(Context, APF64);
244 EXPECT_EQ(CFP64, TmpFP64);
245 EXPECT_NE(TmpFP64, TmpFP);
246
247 // Build half float.
248 LLT s16 = LLT::scalar(16);
249 auto MIBFCst16 = B.buildFConstant(s16, .5);
250 const ConstantFP *TmpFP16{};
251 match = mi_match(MIBFCst16.getReg(0), *MRI, m_GFCst(TmpFP16));
252 EXPECT_TRUE(match);
253 EXPECT_TRUE(TmpFP16);
254 bool Ignored;
255 APFloat APF16(.5);
256 APF16.convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven, &Ignored);
257 auto CFP16 = ConstantFP::get(Context, APF16);
258 EXPECT_EQ(TmpFP16, CFP16);
259 EXPECT_NE(TmpFP16, TmpFP);
260 }
261
TEST_F(AArch64GISelMITest,MatchExtendsTrunc)262 TEST_F(AArch64GISelMITest, MatchExtendsTrunc) {
263 setUp();
264 if (!TM)
265 return;
266
267 LLT s64 = LLT::scalar(64);
268 LLT s32 = LLT::scalar(32);
269
270 auto MIBTrunc = B.buildTrunc(s32, Copies[0]);
271 auto MIBAExt = B.buildAnyExt(s64, MIBTrunc);
272 auto MIBZExt = B.buildZExt(s64, MIBTrunc);
273 auto MIBSExt = B.buildSExt(s64, MIBTrunc);
274 Register Src0;
275 bool match =
276 mi_match(MIBTrunc.getReg(0), *MRI, m_GTrunc(m_Reg(Src0)));
277 EXPECT_TRUE(match);
278 EXPECT_EQ(Src0, Copies[0]);
279 match =
280 mi_match(MIBAExt.getReg(0), *MRI, m_GAnyExt(m_Reg(Src0)));
281 EXPECT_TRUE(match);
282 EXPECT_EQ(Src0, MIBTrunc.getReg(0));
283
284 match = mi_match(MIBSExt.getReg(0), *MRI, m_GSExt(m_Reg(Src0)));
285 EXPECT_TRUE(match);
286 EXPECT_EQ(Src0, MIBTrunc.getReg(0));
287
288 match = mi_match(MIBZExt.getReg(0), *MRI, m_GZExt(m_Reg(Src0)));
289 EXPECT_TRUE(match);
290 EXPECT_EQ(Src0, MIBTrunc.getReg(0));
291
292 // Match ext(trunc src)
293 match = mi_match(MIBAExt.getReg(0), *MRI,
294 m_GAnyExt(m_GTrunc(m_Reg(Src0))));
295 EXPECT_TRUE(match);
296 EXPECT_EQ(Src0, Copies[0]);
297
298 match = mi_match(MIBSExt.getReg(0), *MRI,
299 m_GSExt(m_GTrunc(m_Reg(Src0))));
300 EXPECT_TRUE(match);
301 EXPECT_EQ(Src0, Copies[0]);
302
303 match = mi_match(MIBZExt.getReg(0), *MRI,
304 m_GZExt(m_GTrunc(m_Reg(Src0))));
305 EXPECT_TRUE(match);
306 EXPECT_EQ(Src0, Copies[0]);
307 }
308
TEST_F(AArch64GISelMITest,MatchSpecificType)309 TEST_F(AArch64GISelMITest, MatchSpecificType) {
310 setUp();
311 if (!TM)
312 return;
313
314 // Try to match a 64bit add.
315 LLT s64 = LLT::scalar(64);
316 LLT s32 = LLT::scalar(32);
317 auto MIBAdd = B.buildAdd(s64, Copies[0], Copies[1]);
318 EXPECT_FALSE(mi_match(MIBAdd.getReg(0), *MRI,
319 m_GAdd(m_SpecificType(s32), m_Reg())));
320 EXPECT_TRUE(mi_match(MIBAdd.getReg(0), *MRI,
321 m_GAdd(m_SpecificType(s64), m_Reg())));
322
323 // Try to match the destination type of a bitcast.
324 LLT v2s32 = LLT::vector(2, 32);
325 auto MIBCast = B.buildCast(v2s32, Copies[0]);
326 EXPECT_TRUE(
327 mi_match(MIBCast.getReg(0), *MRI, m_GBitcast(m_Reg())));
328 EXPECT_TRUE(
329 mi_match(MIBCast.getReg(0), *MRI, m_SpecificType(v2s32)));
330 EXPECT_TRUE(
331 mi_match(MIBCast.getReg(1), *MRI, m_SpecificType(s64)));
332
333 // Build a PTRToInt and INTTOPTR and match and test them.
334 LLT PtrTy = LLT::pointer(0, 64);
335 auto MIBIntToPtr = B.buildCast(PtrTy, Copies[0]);
336 auto MIBPtrToInt = B.buildCast(s64, MIBIntToPtr);
337 Register Src0;
338
339 // match the ptrtoint(inttoptr reg)
340 bool match = mi_match(MIBPtrToInt.getReg(0), *MRI,
341 m_GPtrToInt(m_GIntToPtr(m_Reg(Src0))));
342 EXPECT_TRUE(match);
343 EXPECT_EQ(Src0, Copies[0]);
344 }
345
TEST_F(AArch64GISelMITest,MatchCombinators)346 TEST_F(AArch64GISelMITest, MatchCombinators) {
347 setUp();
348 if (!TM)
349 return;
350
351 LLT s64 = LLT::scalar(64);
352 LLT s32 = LLT::scalar(32);
353 auto MIBAdd = B.buildAdd(s64, Copies[0], Copies[1]);
354 Register Src0, Src1;
355 bool match =
356 mi_match(MIBAdd.getReg(0), *MRI,
357 m_all_of(m_SpecificType(s64), m_GAdd(m_Reg(Src0), m_Reg(Src1))));
358 EXPECT_TRUE(match);
359 EXPECT_EQ(Src0, Copies[0]);
360 EXPECT_EQ(Src1, Copies[1]);
361 // Check for s32 (which should fail).
362 match =
363 mi_match(MIBAdd.getReg(0), *MRI,
364 m_all_of(m_SpecificType(s32), m_GAdd(m_Reg(Src0), m_Reg(Src1))));
365 EXPECT_FALSE(match);
366 match =
367 mi_match(MIBAdd.getReg(0), *MRI,
368 m_any_of(m_SpecificType(s32), m_GAdd(m_Reg(Src0), m_Reg(Src1))));
369 EXPECT_TRUE(match);
370 EXPECT_EQ(Src0, Copies[0]);
371 EXPECT_EQ(Src1, Copies[1]);
372
373 // Match a case where none of the predicates hold true.
374 match = mi_match(
375 MIBAdd.getReg(0), *MRI,
376 m_any_of(m_SpecificType(LLT::scalar(16)), m_GSub(m_Reg(), m_Reg())));
377 EXPECT_FALSE(match);
378 }
379
TEST_F(AArch64GISelMITest,MatchMiscellaneous)380 TEST_F(AArch64GISelMITest, MatchMiscellaneous) {
381 setUp();
382 if (!TM)
383 return;
384
385 LLT s64 = LLT::scalar(64);
386 auto MIBAdd = B.buildAdd(s64, Copies[0], Copies[1]);
387 // Make multiple uses of this add.
388 B.buildCast(LLT::pointer(0, 32), MIBAdd);
389 B.buildCast(LLT::pointer(1, 32), MIBAdd);
390 bool match = mi_match(MIBAdd.getReg(0), *MRI, m_GAdd(m_Reg(), m_Reg()));
391 EXPECT_TRUE(match);
392 match = mi_match(MIBAdd.getReg(0), *MRI, m_OneUse(m_GAdd(m_Reg(), m_Reg())));
393 EXPECT_FALSE(match);
394 }
395 } // namespace
396
main(int argc,char ** argv)397 int main(int argc, char **argv) {
398 ::testing::InitGoogleTest(&argc, argv);
399 initLLVM();
400 return RUN_ALL_TESTS();
401 }
402