blob: 1f3a690ad0155a7d8380f7132ba9d084a2cda439 [file] [log] [blame]
Aditya Nandakumar2036f442018-01-25 02:53:06 +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
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +000010#include "llvm/CodeGen/GlobalISel/ConstantFoldingMIRBuilder.h"
Aditya Nandakumar2036f442018-01-25 02:53:06 +000011#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
28using namespace llvm;
29using namespace MIPatternMatch;
30
31namespace {
32
33void initLLVM() {
34 InitializeAllTargets();
35 InitializeAllTargetMCs();
36 InitializeAllAsmPrinters();
37 InitializeAllAsmParsers();
38
39 PassRegistry *Registry = PassRegistry::getPassRegistry();
40 initializeCore(*Registry);
41 initializeCodeGen(*Registry);
42}
43
44/// Create a TargetMachine. As we lack a dedicated always available target for
45/// unittests, we go for "AArch64".
Matthias Braun3d849f62018-11-05 23:49:13 +000046std::unique_ptr<LLVMTargetMachine> createTargetMachine() {
Aditya Nandakumar2036f442018-01-25 02:53:06 +000047 Triple TargetTriple("aarch64--");
48 std::string Error;
49 const Target *T = TargetRegistry::lookupTarget("", TargetTriple, Error);
50 if (!T)
51 return nullptr;
52
53 TargetOptions Options;
Matthias Braun3d849f62018-11-05 23:49:13 +000054 return std::unique_ptr<LLVMTargetMachine>(static_cast<LLVMTargetMachine*>(
55 T->createTargetMachine("AArch64", "", "", Options, None, None,
56 CodeGenOpt::Aggressive)));
Aditya Nandakumar2036f442018-01-25 02:53:06 +000057}
58
59std::unique_ptr<Module> parseMIR(LLVMContext &Context,
60 std::unique_ptr<MIRParser> &MIR,
61 const TargetMachine &TM, StringRef MIRCode,
62 const char *FuncName, MachineModuleInfo &MMI) {
63 SMDiagnostic Diagnostic;
64 std::unique_ptr<MemoryBuffer> MBuffer = MemoryBuffer::getMemBuffer(MIRCode);
65 MIR = createMIRParser(std::move(MBuffer), Context);
66 if (!MIR)
67 return nullptr;
68
69 std::unique_ptr<Module> M = MIR->parseIRModule();
70 if (!M)
71 return nullptr;
72
73 M->setDataLayout(TM.createDataLayout());
74
75 if (MIR->parseMachineFunctions(*M, MMI))
76 return nullptr;
77
78 return M;
79}
80
81std::pair<std::unique_ptr<Module>, std::unique_ptr<MachineModuleInfo>>
Matthias Braun3d849f62018-11-05 23:49:13 +000082createDummyModule(LLVMContext &Context, const LLVMTargetMachine &TM,
Aditya Nandakumar2036f442018-01-25 02:53:06 +000083 StringRef MIRFunc) {
84 SmallString<512> S;
85 StringRef MIRString = (Twine(R"MIR(
86---
87...
88name: func
89registers:
90 - { id: 0, class: _ }
91 - { id: 1, class: _ }
92 - { id: 2, class: _ }
93 - { id: 3, class: _ }
94body: |
95 bb.1:
Puyan Lotfi43e94b12018-01-31 22:04:26 +000096 %0(s64) = COPY $x0
97 %1(s64) = COPY $x1
98 %2(s64) = COPY $x2
Aditya Nandakumar2036f442018-01-25 02:53:06 +000099)MIR") + Twine(MIRFunc) + Twine("...\n"))
100 .toNullTerminatedStringRef(S);
101 std::unique_ptr<MIRParser> MIR;
102 auto MMI = make_unique<MachineModuleInfo>(&TM);
103 std::unique_ptr<Module> M =
104 parseMIR(Context, MIR, TM, MIRString, "func", *MMI);
105 return make_pair(std::move(M), std::move(MMI));
106}
107
108static MachineFunction *getMFFromMMI(const Module *M,
109 const MachineModuleInfo *MMI) {
110 Function *F = M->getFunction("func");
111 auto *MF = MMI->getMachineFunction(*F);
112 return MF;
113}
114
115static void collectCopies(SmallVectorImpl<unsigned> &Copies,
116 MachineFunction *MF) {
117 for (auto &MBB : *MF)
118 for (MachineInstr &MI : MBB) {
119 if (MI.getOpcode() == TargetOpcode::COPY)
120 Copies.push_back(MI.getOperand(0).getReg());
121 }
122}
123
124TEST(PatternMatchInstr, MatchIntConstant) {
125 LLVMContext Context;
Matthias Braun3d849f62018-11-05 23:49:13 +0000126 std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
Aditya Nandakumar2036f442018-01-25 02:53:06 +0000127 if (!TM)
128 return;
129 auto ModuleMMIPair = createDummyModule(Context, *TM, "");
130 MachineFunction *MF =
131 getMFFromMMI(ModuleMMIPair.first.get(), ModuleMMIPair.second.get());
132 SmallVector<unsigned, 4> Copies;
133 collectCopies(Copies, MF);
134 MachineBasicBlock *EntryMBB = &*MF->begin();
135 MachineIRBuilder B(*MF);
136 MachineRegisterInfo &MRI = MF->getRegInfo();
137 B.setInsertPt(*EntryMBB, EntryMBB->end());
138 auto MIBCst = B.buildConstant(LLT::scalar(64), 42);
Aditya Nandakumarb808e3a2018-03-13 23:21:13 +0000139 int64_t Cst;
Aditya Nandakumar2036f442018-01-25 02:53:06 +0000140 bool match = mi_match(MIBCst->getOperand(0).getReg(), MRI, m_ICst(Cst));
141 ASSERT_TRUE(match);
Aditya Nandakumarb808e3a2018-03-13 23:21:13 +0000142 ASSERT_EQ(Cst, 42);
Aditya Nandakumar2036f442018-01-25 02:53:06 +0000143}
144
145TEST(PatternMatchInstr, MatchBinaryOp) {
146 LLVMContext Context;
Matthias Braun3d849f62018-11-05 23:49:13 +0000147 std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
Aditya Nandakumar2036f442018-01-25 02:53:06 +0000148 if (!TM)
149 return;
150 auto ModuleMMIPair = createDummyModule(Context, *TM, "");
151 MachineFunction *MF =
152 getMFFromMMI(ModuleMMIPair.first.get(), ModuleMMIPair.second.get());
153 SmallVector<unsigned, 4> Copies;
154 collectCopies(Copies, MF);
155 MachineBasicBlock *EntryMBB = &*MF->begin();
156 MachineIRBuilder B(*MF);
157 MachineRegisterInfo &MRI = MF->getRegInfo();
158 B.setInsertPt(*EntryMBB, EntryMBB->end());
159 LLT s64 = LLT::scalar(64);
160 auto MIBAdd = B.buildAdd(s64, Copies[0], Copies[1]);
161 // Test case for no bind.
162 bool match =
163 mi_match(MIBAdd->getOperand(0).getReg(), MRI, m_GAdd(m_Reg(), m_Reg()));
164 ASSERT_TRUE(match);
165 unsigned Src0, Src1, Src2;
166 match = mi_match(MIBAdd->getOperand(0).getReg(), MRI,
167 m_GAdd(m_Reg(Src0), m_Reg(Src1)));
168 ASSERT_TRUE(match);
169 ASSERT_EQ(Src0, Copies[0]);
170 ASSERT_EQ(Src1, Copies[1]);
171
172 // Build MUL(ADD %0, %1), %2
173 auto MIBMul = B.buildMul(s64, MIBAdd, Copies[2]);
174
175 // Try to match MUL.
176 match = mi_match(MIBMul->getOperand(0).getReg(), MRI,
177 m_GMul(m_Reg(Src0), m_Reg(Src1)));
178 ASSERT_TRUE(match);
179 ASSERT_EQ(Src0, MIBAdd->getOperand(0).getReg());
180 ASSERT_EQ(Src1, Copies[2]);
181
182 // Try to match MUL(ADD)
183 match = mi_match(MIBMul->getOperand(0).getReg(), MRI,
184 m_GMul(m_GAdd(m_Reg(Src0), m_Reg(Src1)), m_Reg(Src2)));
185 ASSERT_TRUE(match);
186 ASSERT_EQ(Src0, Copies[0]);
187 ASSERT_EQ(Src1, Copies[1]);
188 ASSERT_EQ(Src2, Copies[2]);
189
190 // Test Commutativity.
191 auto MIBMul2 = B.buildMul(s64, Copies[0], B.buildConstant(s64, 42));
192 // Try to match MUL(Cst, Reg) on src of MUL(Reg, Cst) to validate
193 // commutativity.
Aditya Nandakumarb808e3a2018-03-13 23:21:13 +0000194 int64_t Cst;
Aditya Nandakumar2036f442018-01-25 02:53:06 +0000195 match = mi_match(MIBMul2->getOperand(0).getReg(), MRI,
196 m_GMul(m_ICst(Cst), m_Reg(Src0)));
197 ASSERT_TRUE(match);
Aditya Nandakumarb808e3a2018-03-13 23:21:13 +0000198 ASSERT_EQ(Cst, 42);
Aditya Nandakumar2036f442018-01-25 02:53:06 +0000199 ASSERT_EQ(Src0, Copies[0]);
200
201 // Make sure commutative doesn't work with something like SUB.
202 auto MIBSub = B.buildSub(s64, Copies[0], B.buildConstant(s64, 42));
203 match = mi_match(MIBSub->getOperand(0).getReg(), MRI,
204 m_GSub(m_ICst(Cst), m_Reg(Src0)));
205 ASSERT_FALSE(match);
Aditya Nandakumar6250b182018-02-13 20:09:13 +0000206
207 auto MIBFMul = B.buildInstr(TargetOpcode::G_FMUL, s64, Copies[0],
208 B.buildConstant(s64, 42));
209 // Match and test commutativity for FMUL.
210 match = mi_match(MIBFMul->getOperand(0).getReg(), MRI,
211 m_GFMul(m_ICst(Cst), m_Reg(Src0)));
212 ASSERT_TRUE(match);
Aditya Nandakumarb808e3a2018-03-13 23:21:13 +0000213 ASSERT_EQ(Cst, 42);
Aditya Nandakumar6250b182018-02-13 20:09:13 +0000214 ASSERT_EQ(Src0, Copies[0]);
Volkan Keles02bb1742018-02-14 19:58:36 +0000215
Aditya Nandakumar2980b012018-05-31 19:30:01 +0000216 // FSUB
217 auto MIBFSub = B.buildInstr(TargetOpcode::G_FSUB, s64, Copies[0],
218 B.buildConstant(s64, 42));
219 match = mi_match(MIBFSub->getOperand(0).getReg(), MRI,
220 m_GFSub(m_Reg(Src0), m_Reg()));
221 ASSERT_TRUE(match);
222 ASSERT_EQ(Src0, Copies[0]);
223
Volkan Keles02bb1742018-02-14 19:58:36 +0000224 // Build AND %0, %1
225 auto MIBAnd = B.buildAnd(s64, Copies[0], Copies[1]);
226 // Try to match AND.
227 match = mi_match(MIBAnd->getOperand(0).getReg(), MRI,
228 m_GAnd(m_Reg(Src0), m_Reg(Src1)));
229 ASSERT_TRUE(match);
230 ASSERT_EQ(Src0, Copies[0]);
231 ASSERT_EQ(Src1, Copies[1]);
232
233 // Build OR %0, %1
234 auto MIBOr = B.buildOr(s64, Copies[0], Copies[1]);
235 // Try to match OR.
236 match = mi_match(MIBOr->getOperand(0).getReg(), MRI,
237 m_GOr(m_Reg(Src0), m_Reg(Src1)));
238 ASSERT_TRUE(match);
239 ASSERT_EQ(Src0, Copies[0]);
240 ASSERT_EQ(Src1, Copies[1]);
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000241
242 // Try to use the FoldableInstructionsBuilder to build binary ops.
243 ConstantFoldingMIRBuilder CFB(B.getState());
244 LLT s32 = LLT::scalar(32);
245 auto MIBCAdd =
246 CFB.buildAdd(s32, CFB.buildConstant(s32, 0), CFB.buildConstant(s32, 1));
247 // This should be a constant now.
248 match = mi_match(MIBCAdd->getOperand(0).getReg(), MRI, m_ICst(Cst));
249 ASSERT_TRUE(match);
250 ASSERT_EQ(Cst, 1);
251 auto MIBCAdd1 =
252 CFB.buildInstr(TargetOpcode::G_ADD, s32, CFB.buildConstant(s32, 0),
253 CFB.buildConstant(s32, 1));
254 // This should be a constant now.
255 match = mi_match(MIBCAdd1->getOperand(0).getReg(), MRI, m_ICst(Cst));
256 ASSERT_TRUE(match);
257 ASSERT_EQ(Cst, 1);
258
259 // Try one of the other constructors of MachineIRBuilder to make sure it's
260 // compatible.
261 ConstantFoldingMIRBuilder CFB1(*MF);
262 CFB1.setInsertPt(*EntryMBB, EntryMBB->end());
263 auto MIBCSub =
264 CFB1.buildInstr(TargetOpcode::G_SUB, s32, CFB1.buildConstant(s32, 1),
265 CFB1.buildConstant(s32, 1));
266 // This should be a constant now.
267 match = mi_match(MIBCSub->getOperand(0).getReg(), MRI, m_ICst(Cst));
268 ASSERT_TRUE(match);
269 ASSERT_EQ(Cst, 0);
Aditya Nandakumar2036f442018-01-25 02:53:06 +0000270}
271
Volkan Keles2bc42e92018-03-05 22:31:55 +0000272TEST(PatternMatchInstr, MatchFPUnaryOp) {
273 LLVMContext Context;
Matthias Braun3d849f62018-11-05 23:49:13 +0000274 std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
Volkan Keles2bc42e92018-03-05 22:31:55 +0000275 if (!TM)
276 return;
277 auto ModuleMMIPair = createDummyModule(Context, *TM, "");
278 MachineFunction *MF =
279 getMFFromMMI(ModuleMMIPair.first.get(), ModuleMMIPair.second.get());
280 SmallVector<unsigned, 4> Copies;
281 collectCopies(Copies, MF);
282 MachineBasicBlock *EntryMBB = &*MF->begin();
283 MachineIRBuilder B(*MF);
284 MachineRegisterInfo &MRI = MF->getRegInfo();
285 B.setInsertPt(*EntryMBB, EntryMBB->end());
286
287 // Truncate s64 to s32.
288 LLT s32 = LLT::scalar(32);
289 auto Copy0s32 = B.buildFPTrunc(s32, Copies[0]);
290
291 // Match G_FABS.
292 auto MIBFabs = B.buildInstr(TargetOpcode::G_FABS, s32, Copy0s32);
293 bool match = mi_match(MIBFabs->getOperand(0).getReg(), MRI, m_GFabs(m_Reg()));
294 ASSERT_TRUE(match);
Aditya Nandakumar2980b012018-05-31 19:30:01 +0000295
Volkan Keles2bc42e92018-03-05 22:31:55 +0000296 unsigned Src;
Aditya Nandakumar2980b012018-05-31 19:30:01 +0000297 auto MIBFNeg = B.buildInstr(TargetOpcode::G_FNEG, s32, Copy0s32);
298 match = mi_match(MIBFNeg->getOperand(0).getReg(), MRI, m_GFNeg(m_Reg(Src)));
299 ASSERT_TRUE(match);
300 ASSERT_EQ(Src, Copy0s32->getOperand(0).getReg());
301
Volkan Keles2bc42e92018-03-05 22:31:55 +0000302 match = mi_match(MIBFabs->getOperand(0).getReg(), MRI, m_GFabs(m_Reg(Src)));
303 ASSERT_TRUE(match);
304 ASSERT_EQ(Src, Copy0s32->getOperand(0).getReg());
Aditya Nandakumar91fc4e02018-03-09 17:31:51 +0000305
306 // Build and match FConstant.
307 auto MIBFCst = B.buildFConstant(s32, .5);
308 const ConstantFP *TmpFP{};
309 match = mi_match(MIBFCst->getOperand(0).getReg(), MRI, m_GFCst(TmpFP));
310 ASSERT_TRUE(match);
311 ASSERT_TRUE(TmpFP);
312 APFloat APF((float).5);
313 auto *CFP = ConstantFP::get(Context, APF);
314 ASSERT_EQ(CFP, TmpFP);
315
316 // Build double float.
317 LLT s64 = LLT::scalar(64);
318 auto MIBFCst64 = B.buildFConstant(s64, .5);
319 const ConstantFP *TmpFP64{};
320 match = mi_match(MIBFCst64->getOperand(0).getReg(), MRI, m_GFCst(TmpFP64));
321 ASSERT_TRUE(match);
322 ASSERT_TRUE(TmpFP64);
323 APFloat APF64(.5);
324 auto CFP64 = ConstantFP::get(Context, APF64);
325 ASSERT_EQ(CFP64, TmpFP64);
326 ASSERT_NE(TmpFP64, TmpFP);
327
328 // Build half float.
329 LLT s16 = LLT::scalar(16);
330 auto MIBFCst16 = B.buildFConstant(s16, .5);
331 const ConstantFP *TmpFP16{};
332 match = mi_match(MIBFCst16->getOperand(0).getReg(), MRI, m_GFCst(TmpFP16));
333 ASSERT_TRUE(match);
334 ASSERT_TRUE(TmpFP16);
335 bool Ignored;
336 APFloat APF16(.5);
337 APF16.convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven, &Ignored);
338 auto CFP16 = ConstantFP::get(Context, APF16);
339 ASSERT_EQ(TmpFP16, CFP16);
340 ASSERT_NE(TmpFP16, TmpFP);
Volkan Keles2bc42e92018-03-05 22:31:55 +0000341}
342
Aditya Nandakumar2036f442018-01-25 02:53:06 +0000343TEST(PatternMatchInstr, MatchExtendsTrunc) {
344 LLVMContext Context;
Matthias Braun3d849f62018-11-05 23:49:13 +0000345 std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
Aditya Nandakumar2036f442018-01-25 02:53:06 +0000346 if (!TM)
347 return;
348 auto ModuleMMIPair = createDummyModule(Context, *TM, "");
349 MachineFunction *MF =
350 getMFFromMMI(ModuleMMIPair.first.get(), ModuleMMIPair.second.get());
351 SmallVector<unsigned, 4> Copies;
352 collectCopies(Copies, MF);
353 MachineBasicBlock *EntryMBB = &*MF->begin();
354 MachineIRBuilder B(*MF);
355 MachineRegisterInfo &MRI = MF->getRegInfo();
356 B.setInsertPt(*EntryMBB, EntryMBB->end());
357 LLT s64 = LLT::scalar(64);
358 LLT s32 = LLT::scalar(32);
359
360 auto MIBTrunc = B.buildTrunc(s32, Copies[0]);
361 auto MIBAExt = B.buildAnyExt(s64, MIBTrunc);
362 auto MIBZExt = B.buildZExt(s64, MIBTrunc);
363 auto MIBSExt = B.buildSExt(s64, MIBTrunc);
364 unsigned Src0;
365 bool match =
366 mi_match(MIBTrunc->getOperand(0).getReg(), MRI, m_GTrunc(m_Reg(Src0)));
367 ASSERT_TRUE(match);
368 ASSERT_EQ(Src0, Copies[0]);
369 match =
370 mi_match(MIBAExt->getOperand(0).getReg(), MRI, m_GAnyExt(m_Reg(Src0)));
371 ASSERT_TRUE(match);
372 ASSERT_EQ(Src0, MIBTrunc->getOperand(0).getReg());
373
374 match = mi_match(MIBSExt->getOperand(0).getReg(), MRI, m_GSExt(m_Reg(Src0)));
375 ASSERT_TRUE(match);
376 ASSERT_EQ(Src0, MIBTrunc->getOperand(0).getReg());
377
378 match = mi_match(MIBZExt->getOperand(0).getReg(), MRI, m_GZExt(m_Reg(Src0)));
379 ASSERT_TRUE(match);
380 ASSERT_EQ(Src0, MIBTrunc->getOperand(0).getReg());
381
382 // Match ext(trunc src)
383 match = mi_match(MIBAExt->getOperand(0).getReg(), MRI,
384 m_GAnyExt(m_GTrunc(m_Reg(Src0))));
385 ASSERT_TRUE(match);
386 ASSERT_EQ(Src0, Copies[0]);
387
388 match = mi_match(MIBSExt->getOperand(0).getReg(), MRI,
389 m_GSExt(m_GTrunc(m_Reg(Src0))));
390 ASSERT_TRUE(match);
391 ASSERT_EQ(Src0, Copies[0]);
392
393 match = mi_match(MIBZExt->getOperand(0).getReg(), MRI,
394 m_GZExt(m_GTrunc(m_Reg(Src0))));
395 ASSERT_TRUE(match);
396 ASSERT_EQ(Src0, Copies[0]);
397}
398
399TEST(PatternMatchInstr, MatchSpecificType) {
400 LLVMContext Context;
Matthias Braun3d849f62018-11-05 23:49:13 +0000401 std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
Aditya Nandakumar2036f442018-01-25 02:53:06 +0000402 if (!TM)
403 return;
404 auto ModuleMMIPair = createDummyModule(Context, *TM, "");
405 MachineFunction *MF =
406 getMFFromMMI(ModuleMMIPair.first.get(), ModuleMMIPair.second.get());
407 SmallVector<unsigned, 4> Copies;
408 collectCopies(Copies, MF);
409 MachineBasicBlock *EntryMBB = &*MF->begin();
410 MachineIRBuilder B(*MF);
411 MachineRegisterInfo &MRI = MF->getRegInfo();
412 B.setInsertPt(*EntryMBB, EntryMBB->end());
Volkan Keles02bb1742018-02-14 19:58:36 +0000413
414 // Try to match a 64bit add.
Aditya Nandakumar2036f442018-01-25 02:53:06 +0000415 LLT s64 = LLT::scalar(64);
416 LLT s32 = LLT::scalar(32);
417 auto MIBAdd = B.buildAdd(s64, Copies[0], Copies[1]);
Aditya Nandakumar2036f442018-01-25 02:53:06 +0000418 ASSERT_FALSE(mi_match(MIBAdd->getOperand(0).getReg(), MRI,
419 m_GAdd(m_SpecificType(s32), m_Reg())));
420 ASSERT_TRUE(mi_match(MIBAdd->getOperand(0).getReg(), MRI,
421 m_GAdd(m_SpecificType(s64), m_Reg())));
Volkan Keles02bb1742018-02-14 19:58:36 +0000422
423 // Try to match the destination type of a bitcast.
424 LLT v2s32 = LLT::vector(2, 32);
425 auto MIBCast = B.buildCast(v2s32, Copies[0]);
426 ASSERT_TRUE(
Aditya Nandakumarbab2d3e2018-02-19 23:11:53 +0000427 mi_match(MIBCast->getOperand(0).getReg(), MRI, m_GBitcast(m_Reg())));
428 ASSERT_TRUE(
Volkan Keles02bb1742018-02-14 19:58:36 +0000429 mi_match(MIBCast->getOperand(0).getReg(), MRI, m_SpecificType(v2s32)));
430 ASSERT_TRUE(
431 mi_match(MIBCast->getOperand(1).getReg(), MRI, m_SpecificType(s64)));
Aditya Nandakumarbab2d3e2018-02-19 23:11:53 +0000432
433 // Build a PTRToInt and INTTOPTR and match and test them.
434 LLT PtrTy = LLT::pointer(0, 64);
435 auto MIBIntToPtr = B.buildCast(PtrTy, Copies[0]);
436 auto MIBPtrToInt = B.buildCast(s64, MIBIntToPtr);
437 unsigned Src0;
438
439 // match the ptrtoint(inttoptr reg)
440 bool match = mi_match(MIBPtrToInt->getOperand(0).getReg(), MRI,
441 m_GPtrToInt(m_GIntToPtr(m_Reg(Src0))));
442 ASSERT_TRUE(match);
443 ASSERT_EQ(Src0, Copies[0]);
Aditya Nandakumar2036f442018-01-25 02:53:06 +0000444}
445
446TEST(PatternMatchInstr, MatchCombinators) {
447 LLVMContext Context;
Matthias Braun3d849f62018-11-05 23:49:13 +0000448 std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
Aditya Nandakumar2036f442018-01-25 02:53:06 +0000449 if (!TM)
450 return;
451 auto ModuleMMIPair = createDummyModule(Context, *TM, "");
452 MachineFunction *MF =
453 getMFFromMMI(ModuleMMIPair.first.get(), ModuleMMIPair.second.get());
454 SmallVector<unsigned, 4> Copies;
455 collectCopies(Copies, MF);
456 MachineBasicBlock *EntryMBB = &*MF->begin();
457 MachineIRBuilder B(*MF);
458 MachineRegisterInfo &MRI = MF->getRegInfo();
459 B.setInsertPt(*EntryMBB, EntryMBB->end());
460 LLT s64 = LLT::scalar(64);
461 LLT s32 = LLT::scalar(32);
462 auto MIBAdd = B.buildAdd(s64, Copies[0], Copies[1]);
463 unsigned Src0, Src1;
464 bool match =
465 mi_match(MIBAdd->getOperand(0).getReg(), MRI,
466 m_all_of(m_SpecificType(s64), m_GAdd(m_Reg(Src0), m_Reg(Src1))));
467 ASSERT_TRUE(match);
468 ASSERT_EQ(Src0, Copies[0]);
469 ASSERT_EQ(Src1, Copies[1]);
470 // Check for s32 (which should fail).
471 match =
472 mi_match(MIBAdd->getOperand(0).getReg(), MRI,
473 m_all_of(m_SpecificType(s32), m_GAdd(m_Reg(Src0), m_Reg(Src1))));
474 ASSERT_FALSE(match);
475 match =
476 mi_match(MIBAdd->getOperand(0).getReg(), MRI,
477 m_any_of(m_SpecificType(s32), m_GAdd(m_Reg(Src0), m_Reg(Src1))));
478 ASSERT_TRUE(match);
479 ASSERT_EQ(Src0, Copies[0]);
480 ASSERT_EQ(Src1, Copies[1]);
Aditya Nandakumarcf85f312018-02-23 01:01:59 +0000481
482 // Match a case where none of the predicates hold true.
483 match = mi_match(
484 MIBAdd->getOperand(0).getReg(), MRI,
485 m_any_of(m_SpecificType(LLT::scalar(16)), m_GSub(m_Reg(), m_Reg())));
486 ASSERT_FALSE(match);
Aditya Nandakumar2036f442018-01-25 02:53:06 +0000487}
488} // namespace
489
490int main(int argc, char **argv) {
491 ::testing::InitGoogleTest(&argc, argv);
492 initLLVM();
493 return RUN_ALL_TESTS();
494}