1 //===- PatternMatchTest.cpp -----------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
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"
29 using namespace MIPatternMatch
;
33 TEST_F(GISelMITest
, MatchIntConstant
) {
37 auto MIBCst
= B
.buildConstant(LLT::scalar(64), 42);
39 bool match
= mi_match(MIBCst
->getOperand(0).getReg(), *MRI
, m_ICst(Cst
));
44 TEST_F(GISelMITest
, MatchBinaryOp
) {
48 LLT s64
= LLT::scalar(64);
49 auto MIBAdd
= B
.buildAdd(s64
, Copies
[0], Copies
[1]);
50 // Test case for no bind.
52 mi_match(MIBAdd
->getOperand(0).getReg(), *MRI
, m_GAdd(m_Reg(), m_Reg()));
54 Register Src0
, Src1
, Src2
;
55 match
= mi_match(MIBAdd
->getOperand(0).getReg(), *MRI
,
56 m_GAdd(m_Reg(Src0
), m_Reg(Src1
)));
58 EXPECT_EQ(Src0
, Copies
[0]);
59 EXPECT_EQ(Src1
, Copies
[1]);
61 // Build MUL(ADD %0, %1), %2
62 auto MIBMul
= B
.buildMul(s64
, MIBAdd
, Copies
[2]);
65 match
= mi_match(MIBMul
->getOperand(0).getReg(), *MRI
,
66 m_GMul(m_Reg(Src0
), m_Reg(Src1
)));
68 EXPECT_EQ(Src0
, MIBAdd
->getOperand(0).getReg());
69 EXPECT_EQ(Src1
, Copies
[2]);
71 // Try to match MUL(ADD)
72 match
= mi_match(MIBMul
->getOperand(0).getReg(), *MRI
,
73 m_GMul(m_GAdd(m_Reg(Src0
), m_Reg(Src1
)), m_Reg(Src2
)));
75 EXPECT_EQ(Src0
, Copies
[0]);
76 EXPECT_EQ(Src1
, Copies
[1]);
77 EXPECT_EQ(Src2
, Copies
[2]);
79 // Test Commutativity.
80 auto MIBMul2
= B
.buildMul(s64
, Copies
[0], B
.buildConstant(s64
, 42));
81 // Try to match MUL(Cst, Reg) on src of MUL(Reg, Cst) to validate
84 match
= mi_match(MIBMul2
->getOperand(0).getReg(), *MRI
,
85 m_GMul(m_ICst(Cst
), m_Reg(Src0
)));
88 EXPECT_EQ(Src0
, Copies
[0]);
90 // Make sure commutative doesn't work with something like SUB.
91 auto MIBSub
= B
.buildSub(s64
, Copies
[0], B
.buildConstant(s64
, 42));
92 match
= mi_match(MIBSub
->getOperand(0).getReg(), *MRI
,
93 m_GSub(m_ICst(Cst
), m_Reg(Src0
)));
96 auto MIBFMul
= B
.buildInstr(TargetOpcode::G_FMUL
, {s64
},
97 {Copies
[0], B
.buildConstant(s64
, 42)});
98 // Match and test commutativity for FMUL.
99 match
= mi_match(MIBFMul
->getOperand(0).getReg(), *MRI
,
100 m_GFMul(m_ICst(Cst
), m_Reg(Src0
)));
103 EXPECT_EQ(Src0
, Copies
[0]);
106 auto MIBFSub
= B
.buildInstr(TargetOpcode::G_FSUB
, {s64
},
107 {Copies
[0], B
.buildConstant(s64
, 42)});
108 match
= mi_match(MIBFSub
->getOperand(0).getReg(), *MRI
,
109 m_GFSub(m_Reg(Src0
), m_Reg()));
111 EXPECT_EQ(Src0
, Copies
[0]);
114 auto MIBAnd
= B
.buildAnd(s64
, Copies
[0], Copies
[1]);
116 match
= mi_match(MIBAnd
->getOperand(0).getReg(), *MRI
,
117 m_GAnd(m_Reg(Src0
), m_Reg(Src1
)));
119 EXPECT_EQ(Src0
, Copies
[0]);
120 EXPECT_EQ(Src1
, Copies
[1]);
123 auto MIBOr
= B
.buildOr(s64
, Copies
[0], Copies
[1]);
125 match
= mi_match(MIBOr
->getOperand(0).getReg(), *MRI
,
126 m_GOr(m_Reg(Src0
), m_Reg(Src1
)));
128 EXPECT_EQ(Src0
, Copies
[0]);
129 EXPECT_EQ(Src1
, Copies
[1]);
132 TEST_F(GISelMITest
, MatchFPUnaryOp
) {
137 // Truncate s64 to s32.
138 LLT s32
= LLT::scalar(32);
139 auto Copy0s32
= B
.buildFPTrunc(s32
, Copies
[0]);
142 auto MIBFabs
= B
.buildInstr(TargetOpcode::G_FABS
, {s32
}, {Copy0s32
});
144 mi_match(MIBFabs
->getOperand(0).getReg(), *MRI
, m_GFabs(m_Reg()));
148 auto MIBFNeg
= B
.buildInstr(TargetOpcode::G_FNEG
, {s32
}, {Copy0s32
});
149 match
= mi_match(MIBFNeg
->getOperand(0).getReg(), *MRI
, m_GFNeg(m_Reg(Src
)));
151 EXPECT_EQ(Src
, Copy0s32
->getOperand(0).getReg());
153 match
= mi_match(MIBFabs
->getOperand(0).getReg(), *MRI
, m_GFabs(m_Reg(Src
)));
155 EXPECT_EQ(Src
, Copy0s32
->getOperand(0).getReg());
157 // Build and match FConstant.
158 auto MIBFCst
= B
.buildFConstant(s32
, .5);
159 const ConstantFP
*TmpFP
{};
160 match
= mi_match(MIBFCst
->getOperand(0).getReg(), *MRI
, m_GFCst(TmpFP
));
163 APFloat
APF((float).5);
164 auto *CFP
= ConstantFP::get(Context
, APF
);
165 EXPECT_EQ(CFP
, TmpFP
);
167 // Build double float.
168 LLT s64
= LLT::scalar(64);
169 auto MIBFCst64
= B
.buildFConstant(s64
, .5);
170 const ConstantFP
*TmpFP64
{};
171 match
= mi_match(MIBFCst64
->getOperand(0).getReg(), *MRI
, m_GFCst(TmpFP64
));
173 EXPECT_TRUE(TmpFP64
);
175 auto CFP64
= ConstantFP::get(Context
, APF64
);
176 EXPECT_EQ(CFP64
, TmpFP64
);
177 EXPECT_NE(TmpFP64
, TmpFP
);
180 LLT s16
= LLT::scalar(16);
181 auto MIBFCst16
= B
.buildFConstant(s16
, .5);
182 const ConstantFP
*TmpFP16
{};
183 match
= mi_match(MIBFCst16
->getOperand(0).getReg(), *MRI
, m_GFCst(TmpFP16
));
185 EXPECT_TRUE(TmpFP16
);
188 APF16
.convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven
, &Ignored
);
189 auto CFP16
= ConstantFP::get(Context
, APF16
);
190 EXPECT_EQ(TmpFP16
, CFP16
);
191 EXPECT_NE(TmpFP16
, TmpFP
);
194 TEST_F(GISelMITest
, MatchExtendsTrunc
) {
199 LLT s64
= LLT::scalar(64);
200 LLT s32
= LLT::scalar(32);
202 auto MIBTrunc
= B
.buildTrunc(s32
, Copies
[0]);
203 auto MIBAExt
= B
.buildAnyExt(s64
, MIBTrunc
);
204 auto MIBZExt
= B
.buildZExt(s64
, MIBTrunc
);
205 auto MIBSExt
= B
.buildSExt(s64
, MIBTrunc
);
208 mi_match(MIBTrunc
->getOperand(0).getReg(), *MRI
, m_GTrunc(m_Reg(Src0
)));
210 EXPECT_EQ(Src0
, Copies
[0]);
212 mi_match(MIBAExt
->getOperand(0).getReg(), *MRI
, m_GAnyExt(m_Reg(Src0
)));
214 EXPECT_EQ(Src0
, MIBTrunc
->getOperand(0).getReg());
216 match
= mi_match(MIBSExt
->getOperand(0).getReg(), *MRI
, m_GSExt(m_Reg(Src0
)));
218 EXPECT_EQ(Src0
, MIBTrunc
->getOperand(0).getReg());
220 match
= mi_match(MIBZExt
->getOperand(0).getReg(), *MRI
, m_GZExt(m_Reg(Src0
)));
222 EXPECT_EQ(Src0
, MIBTrunc
->getOperand(0).getReg());
224 // Match ext(trunc src)
225 match
= mi_match(MIBAExt
->getOperand(0).getReg(), *MRI
,
226 m_GAnyExt(m_GTrunc(m_Reg(Src0
))));
228 EXPECT_EQ(Src0
, Copies
[0]);
230 match
= mi_match(MIBSExt
->getOperand(0).getReg(), *MRI
,
231 m_GSExt(m_GTrunc(m_Reg(Src0
))));
233 EXPECT_EQ(Src0
, Copies
[0]);
235 match
= mi_match(MIBZExt
->getOperand(0).getReg(), *MRI
,
236 m_GZExt(m_GTrunc(m_Reg(Src0
))));
238 EXPECT_EQ(Src0
, Copies
[0]);
241 TEST_F(GISelMITest
, MatchSpecificType
) {
246 // Try to match a 64bit add.
247 LLT s64
= LLT::scalar(64);
248 LLT s32
= LLT::scalar(32);
249 auto MIBAdd
= B
.buildAdd(s64
, Copies
[0], Copies
[1]);
250 EXPECT_FALSE(mi_match(MIBAdd
->getOperand(0).getReg(), *MRI
,
251 m_GAdd(m_SpecificType(s32
), m_Reg())));
252 EXPECT_TRUE(mi_match(MIBAdd
->getOperand(0).getReg(), *MRI
,
253 m_GAdd(m_SpecificType(s64
), m_Reg())));
255 // Try to match the destination type of a bitcast.
256 LLT v2s32
= LLT::vector(2, 32);
257 auto MIBCast
= B
.buildCast(v2s32
, Copies
[0]);
259 mi_match(MIBCast
->getOperand(0).getReg(), *MRI
, m_GBitcast(m_Reg())));
261 mi_match(MIBCast
->getOperand(0).getReg(), *MRI
, m_SpecificType(v2s32
)));
263 mi_match(MIBCast
->getOperand(1).getReg(), *MRI
, m_SpecificType(s64
)));
265 // Build a PTRToInt and INTTOPTR and match and test them.
266 LLT PtrTy
= LLT::pointer(0, 64);
267 auto MIBIntToPtr
= B
.buildCast(PtrTy
, Copies
[0]);
268 auto MIBPtrToInt
= B
.buildCast(s64
, MIBIntToPtr
);
271 // match the ptrtoint(inttoptr reg)
272 bool match
= mi_match(MIBPtrToInt
->getOperand(0).getReg(), *MRI
,
273 m_GPtrToInt(m_GIntToPtr(m_Reg(Src0
))));
275 EXPECT_EQ(Src0
, Copies
[0]);
278 TEST_F(GISelMITest
, MatchCombinators
) {
283 LLT s64
= LLT::scalar(64);
284 LLT s32
= LLT::scalar(32);
285 auto MIBAdd
= B
.buildAdd(s64
, Copies
[0], Copies
[1]);
288 mi_match(MIBAdd
->getOperand(0).getReg(), *MRI
,
289 m_all_of(m_SpecificType(s64
), m_GAdd(m_Reg(Src0
), m_Reg(Src1
))));
291 EXPECT_EQ(Src0
, Copies
[0]);
292 EXPECT_EQ(Src1
, Copies
[1]);
293 // Check for s32 (which should fail).
295 mi_match(MIBAdd
->getOperand(0).getReg(), *MRI
,
296 m_all_of(m_SpecificType(s32
), m_GAdd(m_Reg(Src0
), m_Reg(Src1
))));
299 mi_match(MIBAdd
->getOperand(0).getReg(), *MRI
,
300 m_any_of(m_SpecificType(s32
), m_GAdd(m_Reg(Src0
), m_Reg(Src1
))));
302 EXPECT_EQ(Src0
, Copies
[0]);
303 EXPECT_EQ(Src1
, Copies
[1]);
305 // Match a case where none of the predicates hold true.
307 MIBAdd
->getOperand(0).getReg(), *MRI
,
308 m_any_of(m_SpecificType(LLT::scalar(16)), m_GSub(m_Reg(), m_Reg())));
312 TEST_F(GISelMITest
, MatchMiscellaneous
) {
317 LLT s64
= LLT::scalar(64);
318 auto MIBAdd
= B
.buildAdd(s64
, Copies
[0], Copies
[1]);
319 // Make multiple uses of this add.
320 B
.buildCast(LLT::pointer(0, 32), MIBAdd
);
321 B
.buildCast(LLT::pointer(1, 32), MIBAdd
);
322 bool match
= mi_match(MIBAdd
.getReg(0), *MRI
, m_GAdd(m_Reg(), m_Reg()));
324 match
= mi_match(MIBAdd
.getReg(0), *MRI
, m_OneUse(m_GAdd(m_Reg(), m_Reg())));
329 int main(int argc
, char **argv
) {
330 ::testing::InitGoogleTest(&argc
, argv
);
332 return RUN_ALL_TESTS();