[InstCombine] Signed saturation patterns
[llvm-complete.git] / unittests / CodeGen / GlobalISel / PatternMatchTest.cpp
blobb6e3e1166a0e9d3b609599ecc48fda07532c9e5e
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 //===----------------------------------------------------------------------===//
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"
28 using namespace llvm;
29 using namespace MIPatternMatch;
31 namespace {
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->getOperand(0).getReg(), *MRI, m_ICst(Cst));
40 EXPECT_TRUE(match);
41 EXPECT_EQ(Cst, 42);
44 TEST_F(GISelMITest, MatchBinaryOp) {
45 setUp();
46 if (!TM)
47 return;
48 LLT s64 = LLT::scalar(64);
49 auto MIBAdd = B.buildAdd(s64, Copies[0], Copies[1]);
50 // Test case for no bind.
51 bool match =
52 mi_match(MIBAdd->getOperand(0).getReg(), *MRI, m_GAdd(m_Reg(), m_Reg()));
53 EXPECT_TRUE(match);
54 Register Src0, Src1, Src2;
55 match = mi_match(MIBAdd->getOperand(0).getReg(), *MRI,
56 m_GAdd(m_Reg(Src0), m_Reg(Src1)));
57 EXPECT_TRUE(match);
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]);
64 // Try to match MUL.
65 match = mi_match(MIBMul->getOperand(0).getReg(), *MRI,
66 m_GMul(m_Reg(Src0), m_Reg(Src1)));
67 EXPECT_TRUE(match);
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)));
74 EXPECT_TRUE(match);
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
82 // commutativity.
83 int64_t Cst;
84 match = mi_match(MIBMul2->getOperand(0).getReg(), *MRI,
85 m_GMul(m_ICst(Cst), m_Reg(Src0)));
86 EXPECT_TRUE(match);
87 EXPECT_EQ(Cst, 42);
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)));
94 EXPECT_FALSE(match);
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)));
101 EXPECT_TRUE(match);
102 EXPECT_EQ(Cst, 42);
103 EXPECT_EQ(Src0, Copies[0]);
105 // FSUB
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()));
110 EXPECT_TRUE(match);
111 EXPECT_EQ(Src0, Copies[0]);
113 // Build AND %0, %1
114 auto MIBAnd = B.buildAnd(s64, Copies[0], Copies[1]);
115 // Try to match AND.
116 match = mi_match(MIBAnd->getOperand(0).getReg(), *MRI,
117 m_GAnd(m_Reg(Src0), m_Reg(Src1)));
118 EXPECT_TRUE(match);
119 EXPECT_EQ(Src0, Copies[0]);
120 EXPECT_EQ(Src1, Copies[1]);
122 // Build OR %0, %1
123 auto MIBOr = B.buildOr(s64, Copies[0], Copies[1]);
124 // Try to match OR.
125 match = mi_match(MIBOr->getOperand(0).getReg(), *MRI,
126 m_GOr(m_Reg(Src0), m_Reg(Src1)));
127 EXPECT_TRUE(match);
128 EXPECT_EQ(Src0, Copies[0]);
129 EXPECT_EQ(Src1, Copies[1]);
132 TEST_F(GISelMITest, MatchFPUnaryOp) {
133 setUp();
134 if (!TM)
135 return;
137 // Truncate s64 to s32.
138 LLT s32 = LLT::scalar(32);
139 auto Copy0s32 = B.buildFPTrunc(s32, Copies[0]);
141 // Match G_FABS.
142 auto MIBFabs = B.buildInstr(TargetOpcode::G_FABS, {s32}, {Copy0s32});
143 bool match =
144 mi_match(MIBFabs->getOperand(0).getReg(), *MRI, m_GFabs(m_Reg()));
145 EXPECT_TRUE(match);
147 Register Src;
148 auto MIBFNeg = B.buildInstr(TargetOpcode::G_FNEG, {s32}, {Copy0s32});
149 match = mi_match(MIBFNeg->getOperand(0).getReg(), *MRI, m_GFNeg(m_Reg(Src)));
150 EXPECT_TRUE(match);
151 EXPECT_EQ(Src, Copy0s32->getOperand(0).getReg());
153 match = mi_match(MIBFabs->getOperand(0).getReg(), *MRI, m_GFabs(m_Reg(Src)));
154 EXPECT_TRUE(match);
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));
161 EXPECT_TRUE(match);
162 EXPECT_TRUE(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));
172 EXPECT_TRUE(match);
173 EXPECT_TRUE(TmpFP64);
174 APFloat APF64(.5);
175 auto CFP64 = ConstantFP::get(Context, APF64);
176 EXPECT_EQ(CFP64, TmpFP64);
177 EXPECT_NE(TmpFP64, TmpFP);
179 // Build half float.
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));
184 EXPECT_TRUE(match);
185 EXPECT_TRUE(TmpFP16);
186 bool Ignored;
187 APFloat APF16(.5);
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) {
195 setUp();
196 if (!TM)
197 return;
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);
206 Register Src0;
207 bool match =
208 mi_match(MIBTrunc->getOperand(0).getReg(), *MRI, m_GTrunc(m_Reg(Src0)));
209 EXPECT_TRUE(match);
210 EXPECT_EQ(Src0, Copies[0]);
211 match =
212 mi_match(MIBAExt->getOperand(0).getReg(), *MRI, m_GAnyExt(m_Reg(Src0)));
213 EXPECT_TRUE(match);
214 EXPECT_EQ(Src0, MIBTrunc->getOperand(0).getReg());
216 match = mi_match(MIBSExt->getOperand(0).getReg(), *MRI, m_GSExt(m_Reg(Src0)));
217 EXPECT_TRUE(match);
218 EXPECT_EQ(Src0, MIBTrunc->getOperand(0).getReg());
220 match = mi_match(MIBZExt->getOperand(0).getReg(), *MRI, m_GZExt(m_Reg(Src0)));
221 EXPECT_TRUE(match);
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))));
227 EXPECT_TRUE(match);
228 EXPECT_EQ(Src0, Copies[0]);
230 match = mi_match(MIBSExt->getOperand(0).getReg(), *MRI,
231 m_GSExt(m_GTrunc(m_Reg(Src0))));
232 EXPECT_TRUE(match);
233 EXPECT_EQ(Src0, Copies[0]);
235 match = mi_match(MIBZExt->getOperand(0).getReg(), *MRI,
236 m_GZExt(m_GTrunc(m_Reg(Src0))));
237 EXPECT_TRUE(match);
238 EXPECT_EQ(Src0, Copies[0]);
241 TEST_F(GISelMITest, MatchSpecificType) {
242 setUp();
243 if (!TM)
244 return;
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]);
258 EXPECT_TRUE(
259 mi_match(MIBCast->getOperand(0).getReg(), *MRI, m_GBitcast(m_Reg())));
260 EXPECT_TRUE(
261 mi_match(MIBCast->getOperand(0).getReg(), *MRI, m_SpecificType(v2s32)));
262 EXPECT_TRUE(
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);
269 Register Src0;
271 // match the ptrtoint(inttoptr reg)
272 bool match = mi_match(MIBPtrToInt->getOperand(0).getReg(), *MRI,
273 m_GPtrToInt(m_GIntToPtr(m_Reg(Src0))));
274 EXPECT_TRUE(match);
275 EXPECT_EQ(Src0, Copies[0]);
278 TEST_F(GISelMITest, MatchCombinators) {
279 setUp();
280 if (!TM)
281 return;
283 LLT s64 = LLT::scalar(64);
284 LLT s32 = LLT::scalar(32);
285 auto MIBAdd = B.buildAdd(s64, Copies[0], Copies[1]);
286 Register Src0, Src1;
287 bool match =
288 mi_match(MIBAdd->getOperand(0).getReg(), *MRI,
289 m_all_of(m_SpecificType(s64), m_GAdd(m_Reg(Src0), m_Reg(Src1))));
290 EXPECT_TRUE(match);
291 EXPECT_EQ(Src0, Copies[0]);
292 EXPECT_EQ(Src1, Copies[1]);
293 // Check for s32 (which should fail).
294 match =
295 mi_match(MIBAdd->getOperand(0).getReg(), *MRI,
296 m_all_of(m_SpecificType(s32), m_GAdd(m_Reg(Src0), m_Reg(Src1))));
297 EXPECT_FALSE(match);
298 match =
299 mi_match(MIBAdd->getOperand(0).getReg(), *MRI,
300 m_any_of(m_SpecificType(s32), m_GAdd(m_Reg(Src0), m_Reg(Src1))));
301 EXPECT_TRUE(match);
302 EXPECT_EQ(Src0, Copies[0]);
303 EXPECT_EQ(Src1, Copies[1]);
305 // Match a case where none of the predicates hold true.
306 match = mi_match(
307 MIBAdd->getOperand(0).getReg(), *MRI,
308 m_any_of(m_SpecificType(LLT::scalar(16)), m_GSub(m_Reg(), m_Reg())));
309 EXPECT_FALSE(match);
312 TEST_F(GISelMITest, MatchMiscellaneous) {
313 setUp();
314 if (!TM)
315 return;
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()));
323 EXPECT_TRUE(match);
324 match = mi_match(MIBAdd.getReg(0), *MRI, m_OneUse(m_GAdd(m_Reg(), m_Reg())));
325 EXPECT_FALSE(match);
327 } // namespace
329 int main(int argc, char **argv) {
330 ::testing::InitGoogleTest(&argc, argv);
331 initLLVM();
332 return RUN_ALL_TESTS();