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 
33 TEST_F(GISelMITest, 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 
44 TEST_F(GISelMITest, 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 
142 TEST_F(GISelMITest, MatchICmp) {
143   setUp();
144   if (!TM)
145     return;
146 
147   const LLT s1 = LLT::scalar(1);
148   auto CmpEq = B.buildICmp(CmpInst::ICMP_EQ, s1, Copies[0], Copies[1]);
149 
150   // Check match any predicate.
151   bool match =
152       mi_match(CmpEq.getReg(0), *MRI, m_GICmp(m_Pred(), m_Reg(), m_Reg()));
153   EXPECT_TRUE(match);
154 
155   // Check we get the predicate and registers.
156   CmpInst::Predicate Pred;
157   Register Reg0;
158   Register Reg1;
159   match = mi_match(CmpEq.getReg(0), *MRI,
160                    m_GICmp(m_Pred(Pred), m_Reg(Reg0), m_Reg(Reg1)));
161   EXPECT_TRUE(match);
162   EXPECT_EQ(CmpInst::ICMP_EQ, Pred);
163   EXPECT_EQ(Copies[0], Reg0);
164   EXPECT_EQ(Copies[1], Reg1);
165 }
166 
167 TEST_F(GISelMITest, MatchFCmp) {
168   setUp();
169   if (!TM)
170     return;
171 
172   const LLT s1 = LLT::scalar(1);
173   auto CmpEq = B.buildFCmp(CmpInst::FCMP_OEQ, s1, Copies[0], Copies[1]);
174 
175   // Check match any predicate.
176   bool match =
177       mi_match(CmpEq.getReg(0), *MRI, m_GFCmp(m_Pred(), m_Reg(), m_Reg()));
178   EXPECT_TRUE(match);
179 
180   // Check we get the predicate and registers.
181   CmpInst::Predicate Pred;
182   Register Reg0;
183   Register Reg1;
184   match = mi_match(CmpEq.getReg(0), *MRI,
185                    m_GFCmp(m_Pred(Pred), m_Reg(Reg0), m_Reg(Reg1)));
186   EXPECT_TRUE(match);
187   EXPECT_EQ(CmpInst::FCMP_OEQ, Pred);
188   EXPECT_EQ(Copies[0], Reg0);
189   EXPECT_EQ(Copies[1], Reg1);
190 }
191 
192 TEST_F(GISelMITest, MatchFPUnaryOp) {
193   setUp();
194   if (!TM)
195     return;
196 
197   // Truncate s64 to s32.
198   LLT s32 = LLT::scalar(32);
199   auto Copy0s32 = B.buildFPTrunc(s32, Copies[0]);
200 
201   // Match G_FABS.
202   auto MIBFabs = B.buildInstr(TargetOpcode::G_FABS, {s32}, {Copy0s32});
203   bool match =
204       mi_match(MIBFabs.getReg(0), *MRI, m_GFabs(m_Reg()));
205   EXPECT_TRUE(match);
206 
207   Register Src;
208   auto MIBFNeg = B.buildInstr(TargetOpcode::G_FNEG, {s32}, {Copy0s32});
209   match = mi_match(MIBFNeg.getReg(0), *MRI, m_GFNeg(m_Reg(Src)));
210   EXPECT_TRUE(match);
211   EXPECT_EQ(Src, Copy0s32.getReg(0));
212 
213   match = mi_match(MIBFabs.getReg(0), *MRI, m_GFabs(m_Reg(Src)));
214   EXPECT_TRUE(match);
215   EXPECT_EQ(Src, Copy0s32.getReg(0));
216 
217   // Build and match FConstant.
218   auto MIBFCst = B.buildFConstant(s32, .5);
219   const ConstantFP *TmpFP{};
220   match = mi_match(MIBFCst.getReg(0), *MRI, m_GFCst(TmpFP));
221   EXPECT_TRUE(match);
222   EXPECT_TRUE(TmpFP);
223   APFloat APF((float).5);
224   auto *CFP = ConstantFP::get(Context, APF);
225   EXPECT_EQ(CFP, TmpFP);
226 
227   // Build double float.
228   LLT s64 = LLT::scalar(64);
229   auto MIBFCst64 = B.buildFConstant(s64, .5);
230   const ConstantFP *TmpFP64{};
231   match = mi_match(MIBFCst64.getReg(0), *MRI, m_GFCst(TmpFP64));
232   EXPECT_TRUE(match);
233   EXPECT_TRUE(TmpFP64);
234   APFloat APF64(.5);
235   auto CFP64 = ConstantFP::get(Context, APF64);
236   EXPECT_EQ(CFP64, TmpFP64);
237   EXPECT_NE(TmpFP64, TmpFP);
238 
239   // Build half float.
240   LLT s16 = LLT::scalar(16);
241   auto MIBFCst16 = B.buildFConstant(s16, .5);
242   const ConstantFP *TmpFP16{};
243   match = mi_match(MIBFCst16.getReg(0), *MRI, m_GFCst(TmpFP16));
244   EXPECT_TRUE(match);
245   EXPECT_TRUE(TmpFP16);
246   bool Ignored;
247   APFloat APF16(.5);
248   APF16.convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven, &Ignored);
249   auto CFP16 = ConstantFP::get(Context, APF16);
250   EXPECT_EQ(TmpFP16, CFP16);
251   EXPECT_NE(TmpFP16, TmpFP);
252 }
253 
254 TEST_F(GISelMITest, MatchExtendsTrunc) {
255   setUp();
256   if (!TM)
257     return;
258 
259   LLT s64 = LLT::scalar(64);
260   LLT s32 = LLT::scalar(32);
261 
262   auto MIBTrunc = B.buildTrunc(s32, Copies[0]);
263   auto MIBAExt = B.buildAnyExt(s64, MIBTrunc);
264   auto MIBZExt = B.buildZExt(s64, MIBTrunc);
265   auto MIBSExt = B.buildSExt(s64, MIBTrunc);
266   Register Src0;
267   bool match =
268       mi_match(MIBTrunc.getReg(0), *MRI, m_GTrunc(m_Reg(Src0)));
269   EXPECT_TRUE(match);
270   EXPECT_EQ(Src0, Copies[0]);
271   match =
272       mi_match(MIBAExt.getReg(0), *MRI, m_GAnyExt(m_Reg(Src0)));
273   EXPECT_TRUE(match);
274   EXPECT_EQ(Src0, MIBTrunc.getReg(0));
275 
276   match = mi_match(MIBSExt.getReg(0), *MRI, m_GSExt(m_Reg(Src0)));
277   EXPECT_TRUE(match);
278   EXPECT_EQ(Src0, MIBTrunc.getReg(0));
279 
280   match = mi_match(MIBZExt.getReg(0), *MRI, m_GZExt(m_Reg(Src0)));
281   EXPECT_TRUE(match);
282   EXPECT_EQ(Src0, MIBTrunc.getReg(0));
283 
284   // Match ext(trunc src)
285   match = mi_match(MIBAExt.getReg(0), *MRI,
286                    m_GAnyExt(m_GTrunc(m_Reg(Src0))));
287   EXPECT_TRUE(match);
288   EXPECT_EQ(Src0, Copies[0]);
289 
290   match = mi_match(MIBSExt.getReg(0), *MRI,
291                    m_GSExt(m_GTrunc(m_Reg(Src0))));
292   EXPECT_TRUE(match);
293   EXPECT_EQ(Src0, Copies[0]);
294 
295   match = mi_match(MIBZExt.getReg(0), *MRI,
296                    m_GZExt(m_GTrunc(m_Reg(Src0))));
297   EXPECT_TRUE(match);
298   EXPECT_EQ(Src0, Copies[0]);
299 }
300 
301 TEST_F(GISelMITest, MatchSpecificType) {
302   setUp();
303   if (!TM)
304     return;
305 
306   // Try to match a 64bit add.
307   LLT s64 = LLT::scalar(64);
308   LLT s32 = LLT::scalar(32);
309   auto MIBAdd = B.buildAdd(s64, Copies[0], Copies[1]);
310   EXPECT_FALSE(mi_match(MIBAdd.getReg(0), *MRI,
311                         m_GAdd(m_SpecificType(s32), m_Reg())));
312   EXPECT_TRUE(mi_match(MIBAdd.getReg(0), *MRI,
313                        m_GAdd(m_SpecificType(s64), m_Reg())));
314 
315   // Try to match the destination type of a bitcast.
316   LLT v2s32 = LLT::vector(2, 32);
317   auto MIBCast = B.buildCast(v2s32, Copies[0]);
318   EXPECT_TRUE(
319       mi_match(MIBCast.getReg(0), *MRI, m_GBitcast(m_Reg())));
320   EXPECT_TRUE(
321       mi_match(MIBCast.getReg(0), *MRI, m_SpecificType(v2s32)));
322   EXPECT_TRUE(
323       mi_match(MIBCast.getReg(1), *MRI, m_SpecificType(s64)));
324 
325   // Build a PTRToInt and INTTOPTR and match and test them.
326   LLT PtrTy = LLT::pointer(0, 64);
327   auto MIBIntToPtr = B.buildCast(PtrTy, Copies[0]);
328   auto MIBPtrToInt = B.buildCast(s64, MIBIntToPtr);
329   Register Src0;
330 
331   // match the ptrtoint(inttoptr reg)
332   bool match = mi_match(MIBPtrToInt.getReg(0), *MRI,
333                         m_GPtrToInt(m_GIntToPtr(m_Reg(Src0))));
334   EXPECT_TRUE(match);
335   EXPECT_EQ(Src0, Copies[0]);
336 }
337 
338 TEST_F(GISelMITest, MatchCombinators) {
339   setUp();
340   if (!TM)
341     return;
342 
343   LLT s64 = LLT::scalar(64);
344   LLT s32 = LLT::scalar(32);
345   auto MIBAdd = B.buildAdd(s64, Copies[0], Copies[1]);
346   Register Src0, Src1;
347   bool match =
348       mi_match(MIBAdd.getReg(0), *MRI,
349                m_all_of(m_SpecificType(s64), m_GAdd(m_Reg(Src0), m_Reg(Src1))));
350   EXPECT_TRUE(match);
351   EXPECT_EQ(Src0, Copies[0]);
352   EXPECT_EQ(Src1, Copies[1]);
353   // Check for s32 (which should fail).
354   match =
355       mi_match(MIBAdd.getReg(0), *MRI,
356                m_all_of(m_SpecificType(s32), m_GAdd(m_Reg(Src0), m_Reg(Src1))));
357   EXPECT_FALSE(match);
358   match =
359       mi_match(MIBAdd.getReg(0), *MRI,
360                m_any_of(m_SpecificType(s32), m_GAdd(m_Reg(Src0), m_Reg(Src1))));
361   EXPECT_TRUE(match);
362   EXPECT_EQ(Src0, Copies[0]);
363   EXPECT_EQ(Src1, Copies[1]);
364 
365   // Match a case where none of the predicates hold true.
366   match = mi_match(
367       MIBAdd.getReg(0), *MRI,
368       m_any_of(m_SpecificType(LLT::scalar(16)), m_GSub(m_Reg(), m_Reg())));
369   EXPECT_FALSE(match);
370 }
371 
372 TEST_F(GISelMITest, MatchMiscellaneous) {
373   setUp();
374   if (!TM)
375     return;
376 
377   LLT s64 = LLT::scalar(64);
378   auto MIBAdd = B.buildAdd(s64, Copies[0], Copies[1]);
379   // Make multiple uses of this add.
380   B.buildCast(LLT::pointer(0, 32), MIBAdd);
381   B.buildCast(LLT::pointer(1, 32), MIBAdd);
382   bool match = mi_match(MIBAdd.getReg(0), *MRI, m_GAdd(m_Reg(), m_Reg()));
383   EXPECT_TRUE(match);
384   match = mi_match(MIBAdd.getReg(0), *MRI, m_OneUse(m_GAdd(m_Reg(), m_Reg())));
385   EXPECT_FALSE(match);
386 }
387 } // namespace
388 
389 int main(int argc, char **argv) {
390   ::testing::InitGoogleTest(&argc, argv);
391   initLLVM();
392   return RUN_ALL_TESTS();
393 }
394