1 | //===---- llvm/unittest/IR/PatternMatch.cpp - PatternMatch unit tests ----===// |
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 "llvm/IR/PatternMatch.h" |
10 | #include "llvm/ADT/APSInt.h" |
11 | #include "llvm/ADT/STLExtras.h" |
12 | #include "llvm/Analysis/ValueTracking.h" |
13 | #include "llvm/IR/BasicBlock.h" |
14 | #include "llvm/IR/Constants.h" |
15 | #include "llvm/IR/DataLayout.h" |
16 | #include "llvm/IR/DerivedTypes.h" |
17 | #include "llvm/IR/Function.h" |
18 | #include "llvm/IR/IRBuilder.h" |
19 | #include "llvm/IR/Instructions.h" |
20 | #include "llvm/IR/LLVMContext.h" |
21 | #include "llvm/IR/MDBuilder.h" |
22 | #include "llvm/IR/Module.h" |
23 | #include "llvm/IR/NoFolder.h" |
24 | #include "llvm/IR/Operator.h" |
25 | #include "llvm/IR/Type.h" |
26 | #include "gtest/gtest.h" |
27 | |
28 | using namespace llvm; |
29 | using namespace llvm::PatternMatch; |
30 | |
31 | namespace { |
32 | |
33 | struct PatternMatchTest : ::testing::Test { |
34 | LLVMContext Ctx; |
35 | std::unique_ptr<Module> M; |
36 | Function *F; |
37 | BasicBlock *BB; |
38 | IRBuilder<NoFolder> IRB; |
39 | |
40 | PatternMatchTest() |
41 | : M(new Module("PatternMatchTestModule" , Ctx)), |
42 | F(Function::Create( |
43 | Ty: FunctionType::get(Result: Type::getVoidTy(C&: Ctx), /* IsVarArg */ isVarArg: false), |
44 | Linkage: Function::ExternalLinkage, N: "f" , M: M.get())), |
45 | BB(BasicBlock::Create(Context&: Ctx, Name: "entry" , Parent: F)), IRB(BB) {} |
46 | }; |
47 | |
48 | TEST_F(PatternMatchTest, OneUse) { |
49 | // Build up a little tree of values: |
50 | // |
51 | // One = (1 + 2) + 42 |
52 | // Two = One + 42 |
53 | // Leaf = (Two + 8) + (Two + 13) |
54 | Value *One = IRB.CreateAdd(LHS: IRB.CreateAdd(LHS: IRB.getInt32(C: 1), RHS: IRB.getInt32(C: 2)), |
55 | RHS: IRB.getInt32(C: 42)); |
56 | Value *Two = IRB.CreateAdd(LHS: One, RHS: IRB.getInt32(C: 42)); |
57 | Value *Leaf = IRB.CreateAdd(LHS: IRB.CreateAdd(LHS: Two, RHS: IRB.getInt32(C: 8)), |
58 | RHS: IRB.CreateAdd(LHS: Two, RHS: IRB.getInt32(C: 13))); |
59 | Value *V; |
60 | |
61 | EXPECT_TRUE(m_OneUse(m_Value(V)).match(One)); |
62 | EXPECT_EQ(One, V); |
63 | |
64 | EXPECT_FALSE(m_OneUse(m_Value()).match(Two)); |
65 | EXPECT_FALSE(m_OneUse(m_Value()).match(Leaf)); |
66 | } |
67 | |
68 | TEST_F(PatternMatchTest, SpecificIntEQ) { |
69 | Type *IntTy = IRB.getInt32Ty(); |
70 | unsigned BitWidth = IntTy->getScalarSizeInBits(); |
71 | |
72 | Value *Zero = ConstantInt::get(Ty: IntTy, V: 0); |
73 | Value *One = ConstantInt::get(Ty: IntTy, V: 1); |
74 | Value *NegOne = ConstantInt::get(Ty: IntTy, V: -1); |
75 | |
76 | EXPECT_TRUE( |
77 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_EQ, APInt(BitWidth, 0)) |
78 | .match(Zero)); |
79 | EXPECT_FALSE( |
80 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_EQ, APInt(BitWidth, 0)) |
81 | .match(One)); |
82 | EXPECT_FALSE( |
83 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_EQ, APInt(BitWidth, 0)) |
84 | .match(NegOne)); |
85 | |
86 | EXPECT_FALSE( |
87 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_EQ, APInt(BitWidth, 1)) |
88 | .match(Zero)); |
89 | EXPECT_TRUE( |
90 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_EQ, APInt(BitWidth, 1)) |
91 | .match(One)); |
92 | EXPECT_FALSE( |
93 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_EQ, APInt(BitWidth, 1)) |
94 | .match(NegOne)); |
95 | |
96 | EXPECT_FALSE( |
97 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_EQ, APInt(BitWidth, -1)) |
98 | .match(Zero)); |
99 | EXPECT_FALSE( |
100 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_EQ, APInt(BitWidth, -1)) |
101 | .match(One)); |
102 | EXPECT_TRUE( |
103 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_EQ, APInt(BitWidth, -1)) |
104 | .match(NegOne)); |
105 | } |
106 | |
107 | TEST_F(PatternMatchTest, SpecificIntNE) { |
108 | Type *IntTy = IRB.getInt32Ty(); |
109 | unsigned BitWidth = IntTy->getScalarSizeInBits(); |
110 | |
111 | Value *Zero = ConstantInt::get(Ty: IntTy, V: 0); |
112 | Value *One = ConstantInt::get(Ty: IntTy, V: 1); |
113 | Value *NegOne = ConstantInt::get(Ty: IntTy, V: -1); |
114 | |
115 | EXPECT_FALSE( |
116 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_NE, APInt(BitWidth, 0)) |
117 | .match(Zero)); |
118 | EXPECT_TRUE( |
119 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_NE, APInt(BitWidth, 0)) |
120 | .match(One)); |
121 | EXPECT_TRUE( |
122 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_NE, APInt(BitWidth, 0)) |
123 | .match(NegOne)); |
124 | |
125 | EXPECT_TRUE( |
126 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_NE, APInt(BitWidth, 1)) |
127 | .match(Zero)); |
128 | EXPECT_FALSE( |
129 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_NE, APInt(BitWidth, 1)) |
130 | .match(One)); |
131 | EXPECT_TRUE( |
132 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_NE, APInt(BitWidth, 1)) |
133 | .match(NegOne)); |
134 | |
135 | EXPECT_TRUE( |
136 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_NE, APInt(BitWidth, -1)) |
137 | .match(Zero)); |
138 | EXPECT_TRUE( |
139 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_NE, APInt(BitWidth, -1)) |
140 | .match(One)); |
141 | EXPECT_FALSE( |
142 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_NE, APInt(BitWidth, -1)) |
143 | .match(NegOne)); |
144 | } |
145 | |
146 | TEST_F(PatternMatchTest, SpecificIntUGT) { |
147 | Type *IntTy = IRB.getInt32Ty(); |
148 | unsigned BitWidth = IntTy->getScalarSizeInBits(); |
149 | |
150 | Value *Zero = ConstantInt::get(Ty: IntTy, V: 0); |
151 | Value *One = ConstantInt::get(Ty: IntTy, V: 1); |
152 | Value *NegOne = ConstantInt::get(Ty: IntTy, V: -1); |
153 | |
154 | EXPECT_FALSE( |
155 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGT, APInt(BitWidth, 0)) |
156 | .match(Zero)); |
157 | EXPECT_TRUE( |
158 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGT, APInt(BitWidth, 0)) |
159 | .match(One)); |
160 | EXPECT_TRUE( |
161 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGT, APInt(BitWidth, 0)) |
162 | .match(NegOne)); |
163 | |
164 | EXPECT_FALSE( |
165 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGT, APInt(BitWidth, 1)) |
166 | .match(Zero)); |
167 | EXPECT_FALSE( |
168 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGT, APInt(BitWidth, 1)) |
169 | .match(One)); |
170 | EXPECT_TRUE( |
171 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGT, APInt(BitWidth, 1)) |
172 | .match(NegOne)); |
173 | |
174 | EXPECT_FALSE( |
175 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGT, APInt(BitWidth, -1)) |
176 | .match(Zero)); |
177 | EXPECT_FALSE( |
178 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGT, APInt(BitWidth, -1)) |
179 | .match(One)); |
180 | EXPECT_FALSE( |
181 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGT, APInt(BitWidth, -1)) |
182 | .match(NegOne)); |
183 | } |
184 | |
185 | TEST_F(PatternMatchTest, SignbitZeroChecks) { |
186 | Type *IntTy = IRB.getInt32Ty(); |
187 | |
188 | Value *Zero = ConstantInt::get(Ty: IntTy, V: 0); |
189 | Value *One = ConstantInt::get(Ty: IntTy, V: 1); |
190 | Value *NegOne = ConstantInt::get(Ty: IntTy, V: -1); |
191 | |
192 | EXPECT_TRUE(m_Negative().match(NegOne)); |
193 | EXPECT_FALSE(m_NonNegative().match(NegOne)); |
194 | EXPECT_FALSE(m_StrictlyPositive().match(NegOne)); |
195 | EXPECT_TRUE(m_NonPositive().match(NegOne)); |
196 | |
197 | EXPECT_FALSE(m_Negative().match(Zero)); |
198 | EXPECT_TRUE(m_NonNegative().match(Zero)); |
199 | EXPECT_FALSE(m_StrictlyPositive().match(Zero)); |
200 | EXPECT_TRUE(m_NonPositive().match(Zero)); |
201 | |
202 | EXPECT_FALSE(m_Negative().match(One)); |
203 | EXPECT_TRUE(m_NonNegative().match(One)); |
204 | EXPECT_TRUE(m_StrictlyPositive().match(One)); |
205 | EXPECT_FALSE(m_NonPositive().match(One)); |
206 | } |
207 | |
208 | TEST_F(PatternMatchTest, SpecificIntUGE) { |
209 | Type *IntTy = IRB.getInt32Ty(); |
210 | unsigned BitWidth = IntTy->getScalarSizeInBits(); |
211 | |
212 | Value *Zero = ConstantInt::get(Ty: IntTy, V: 0); |
213 | Value *One = ConstantInt::get(Ty: IntTy, V: 1); |
214 | Value *NegOne = ConstantInt::get(Ty: IntTy, V: -1); |
215 | |
216 | EXPECT_TRUE( |
217 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGE, APInt(BitWidth, 0)) |
218 | .match(Zero)); |
219 | EXPECT_TRUE( |
220 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGE, APInt(BitWidth, 0)) |
221 | .match(One)); |
222 | EXPECT_TRUE( |
223 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGE, APInt(BitWidth, 0)) |
224 | .match(NegOne)); |
225 | |
226 | EXPECT_FALSE( |
227 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGE, APInt(BitWidth, 1)) |
228 | .match(Zero)); |
229 | EXPECT_TRUE( |
230 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGE, APInt(BitWidth, 1)) |
231 | .match(One)); |
232 | EXPECT_TRUE( |
233 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGE, APInt(BitWidth, 1)) |
234 | .match(NegOne)); |
235 | |
236 | EXPECT_FALSE( |
237 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGE, APInt(BitWidth, -1)) |
238 | .match(Zero)); |
239 | EXPECT_FALSE( |
240 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGE, APInt(BitWidth, -1)) |
241 | .match(One)); |
242 | EXPECT_TRUE( |
243 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGE, APInt(BitWidth, -1)) |
244 | .match(NegOne)); |
245 | } |
246 | |
247 | TEST_F(PatternMatchTest, SpecificIntULT) { |
248 | Type *IntTy = IRB.getInt32Ty(); |
249 | unsigned BitWidth = IntTy->getScalarSizeInBits(); |
250 | |
251 | Value *Zero = ConstantInt::get(Ty: IntTy, V: 0); |
252 | Value *One = ConstantInt::get(Ty: IntTy, V: 1); |
253 | Value *NegOne = ConstantInt::get(Ty: IntTy, V: -1); |
254 | |
255 | EXPECT_FALSE( |
256 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULT, APInt(BitWidth, 0)) |
257 | .match(Zero)); |
258 | EXPECT_FALSE( |
259 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULT, APInt(BitWidth, 0)) |
260 | .match(One)); |
261 | EXPECT_FALSE( |
262 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULT, APInt(BitWidth, 0)) |
263 | .match(NegOne)); |
264 | |
265 | EXPECT_TRUE( |
266 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULT, APInt(BitWidth, 1)) |
267 | .match(Zero)); |
268 | EXPECT_FALSE( |
269 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULT, APInt(BitWidth, 1)) |
270 | .match(One)); |
271 | EXPECT_FALSE( |
272 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULT, APInt(BitWidth, 1)) |
273 | .match(NegOne)); |
274 | |
275 | EXPECT_TRUE( |
276 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULT, APInt(BitWidth, -1)) |
277 | .match(Zero)); |
278 | EXPECT_TRUE( |
279 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULT, APInt(BitWidth, -1)) |
280 | .match(One)); |
281 | EXPECT_FALSE( |
282 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULT, APInt(BitWidth, -1)) |
283 | .match(NegOne)); |
284 | } |
285 | |
286 | TEST_F(PatternMatchTest, SpecificIntULE) { |
287 | Type *IntTy = IRB.getInt32Ty(); |
288 | unsigned BitWidth = IntTy->getScalarSizeInBits(); |
289 | |
290 | Value *Zero = ConstantInt::get(Ty: IntTy, V: 0); |
291 | Value *One = ConstantInt::get(Ty: IntTy, V: 1); |
292 | Value *NegOne = ConstantInt::get(Ty: IntTy, V: -1); |
293 | |
294 | EXPECT_TRUE( |
295 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULE, APInt(BitWidth, 0)) |
296 | .match(Zero)); |
297 | EXPECT_FALSE( |
298 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULE, APInt(BitWidth, 0)) |
299 | .match(One)); |
300 | EXPECT_FALSE( |
301 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULE, APInt(BitWidth, 0)) |
302 | .match(NegOne)); |
303 | |
304 | EXPECT_TRUE( |
305 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULE, APInt(BitWidth, 1)) |
306 | .match(Zero)); |
307 | EXPECT_TRUE( |
308 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULE, APInt(BitWidth, 1)) |
309 | .match(One)); |
310 | EXPECT_FALSE( |
311 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULE, APInt(BitWidth, 1)) |
312 | .match(NegOne)); |
313 | |
314 | EXPECT_TRUE( |
315 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULE, APInt(BitWidth, -1)) |
316 | .match(Zero)); |
317 | EXPECT_TRUE( |
318 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULE, APInt(BitWidth, -1)) |
319 | .match(One)); |
320 | EXPECT_TRUE( |
321 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULE, APInt(BitWidth, -1)) |
322 | .match(NegOne)); |
323 | } |
324 | |
325 | TEST_F(PatternMatchTest, SpecificIntSGT) { |
326 | Type *IntTy = IRB.getInt32Ty(); |
327 | unsigned BitWidth = IntTy->getScalarSizeInBits(); |
328 | |
329 | Value *Zero = ConstantInt::get(Ty: IntTy, V: 0); |
330 | Value *One = ConstantInt::get(Ty: IntTy, V: 1); |
331 | Value *NegOne = ConstantInt::get(Ty: IntTy, V: -1); |
332 | |
333 | EXPECT_FALSE( |
334 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGT, APInt(BitWidth, 0)) |
335 | .match(Zero)); |
336 | EXPECT_TRUE( |
337 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGT, APInt(BitWidth, 0)) |
338 | .match(One)); |
339 | EXPECT_FALSE( |
340 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGT, APInt(BitWidth, 0)) |
341 | .match(NegOne)); |
342 | |
343 | EXPECT_FALSE( |
344 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGT, APInt(BitWidth, 1)) |
345 | .match(Zero)); |
346 | EXPECT_FALSE( |
347 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGT, APInt(BitWidth, 1)) |
348 | .match(One)); |
349 | EXPECT_FALSE( |
350 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGT, APInt(BitWidth, 1)) |
351 | .match(NegOne)); |
352 | |
353 | EXPECT_TRUE( |
354 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGT, APInt(BitWidth, -1)) |
355 | .match(Zero)); |
356 | EXPECT_TRUE( |
357 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGT, APInt(BitWidth, -1)) |
358 | .match(One)); |
359 | EXPECT_FALSE( |
360 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGT, APInt(BitWidth, -1)) |
361 | .match(NegOne)); |
362 | } |
363 | |
364 | TEST_F(PatternMatchTest, SpecificIntSGE) { |
365 | Type *IntTy = IRB.getInt32Ty(); |
366 | unsigned BitWidth = IntTy->getScalarSizeInBits(); |
367 | |
368 | Value *Zero = ConstantInt::get(Ty: IntTy, V: 0); |
369 | Value *One = ConstantInt::get(Ty: IntTy, V: 1); |
370 | Value *NegOne = ConstantInt::get(Ty: IntTy, V: -1); |
371 | |
372 | EXPECT_TRUE( |
373 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGE, APInt(BitWidth, 0)) |
374 | .match(Zero)); |
375 | EXPECT_TRUE( |
376 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGE, APInt(BitWidth, 0)) |
377 | .match(One)); |
378 | EXPECT_FALSE( |
379 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGE, APInt(BitWidth, 0)) |
380 | .match(NegOne)); |
381 | |
382 | EXPECT_FALSE( |
383 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGE, APInt(BitWidth, 1)) |
384 | .match(Zero)); |
385 | EXPECT_TRUE( |
386 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGE, APInt(BitWidth, 1)) |
387 | .match(One)); |
388 | EXPECT_FALSE( |
389 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGE, APInt(BitWidth, 1)) |
390 | .match(NegOne)); |
391 | |
392 | EXPECT_TRUE( |
393 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGE, APInt(BitWidth, -1)) |
394 | .match(Zero)); |
395 | EXPECT_TRUE( |
396 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGE, APInt(BitWidth, -1)) |
397 | .match(One)); |
398 | EXPECT_TRUE( |
399 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGE, APInt(BitWidth, -1)) |
400 | .match(NegOne)); |
401 | } |
402 | |
403 | TEST_F(PatternMatchTest, SpecificIntSLT) { |
404 | Type *IntTy = IRB.getInt32Ty(); |
405 | unsigned BitWidth = IntTy->getScalarSizeInBits(); |
406 | |
407 | Value *Zero = ConstantInt::get(Ty: IntTy, V: 0); |
408 | Value *One = ConstantInt::get(Ty: IntTy, V: 1); |
409 | Value *NegOne = ConstantInt::get(Ty: IntTy, V: -1); |
410 | |
411 | EXPECT_FALSE( |
412 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLT, APInt(BitWidth, 0)) |
413 | .match(Zero)); |
414 | EXPECT_FALSE( |
415 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLT, APInt(BitWidth, 0)) |
416 | .match(One)); |
417 | EXPECT_TRUE( |
418 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLT, APInt(BitWidth, 0)) |
419 | .match(NegOne)); |
420 | |
421 | EXPECT_TRUE( |
422 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLT, APInt(BitWidth, 1)) |
423 | .match(Zero)); |
424 | EXPECT_FALSE( |
425 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLT, APInt(BitWidth, 1)) |
426 | .match(One)); |
427 | EXPECT_TRUE( |
428 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLT, APInt(BitWidth, 1)) |
429 | .match(NegOne)); |
430 | |
431 | EXPECT_FALSE( |
432 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLT, APInt(BitWidth, -1)) |
433 | .match(Zero)); |
434 | EXPECT_FALSE( |
435 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLT, APInt(BitWidth, -1)) |
436 | .match(One)); |
437 | EXPECT_FALSE( |
438 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLT, APInt(BitWidth, -1)) |
439 | .match(NegOne)); |
440 | } |
441 | |
442 | TEST_F(PatternMatchTest, SpecificIntSLE) { |
443 | Type *IntTy = IRB.getInt32Ty(); |
444 | unsigned BitWidth = IntTy->getScalarSizeInBits(); |
445 | |
446 | Value *Zero = ConstantInt::get(Ty: IntTy, V: 0); |
447 | Value *One = ConstantInt::get(Ty: IntTy, V: 1); |
448 | Value *NegOne = ConstantInt::get(Ty: IntTy, V: -1); |
449 | |
450 | EXPECT_TRUE( |
451 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLE, APInt(BitWidth, 0)) |
452 | .match(Zero)); |
453 | EXPECT_FALSE( |
454 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLE, APInt(BitWidth, 0)) |
455 | .match(One)); |
456 | EXPECT_TRUE( |
457 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLE, APInt(BitWidth, 0)) |
458 | .match(NegOne)); |
459 | |
460 | EXPECT_TRUE( |
461 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLE, APInt(BitWidth, 1)) |
462 | .match(Zero)); |
463 | EXPECT_TRUE( |
464 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLE, APInt(BitWidth, 1)) |
465 | .match(One)); |
466 | EXPECT_TRUE( |
467 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLE, APInt(BitWidth, 1)) |
468 | .match(NegOne)); |
469 | |
470 | EXPECT_FALSE( |
471 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLE, APInt(BitWidth, -1)) |
472 | .match(Zero)); |
473 | EXPECT_FALSE( |
474 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLE, APInt(BitWidth, -1)) |
475 | .match(One)); |
476 | EXPECT_TRUE( |
477 | m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLE, APInt(BitWidth, -1)) |
478 | .match(NegOne)); |
479 | } |
480 | |
481 | TEST_F(PatternMatchTest, Unless) { |
482 | Value *X = IRB.CreateAdd(LHS: IRB.getInt32(C: 1), RHS: IRB.getInt32(C: 0)); |
483 | |
484 | EXPECT_TRUE(m_Add(m_One(), m_Zero()).match(X)); |
485 | EXPECT_FALSE(m_Add(m_Zero(), m_One()).match(X)); |
486 | |
487 | EXPECT_FALSE(m_Unless(m_Add(m_One(), m_Zero())).match(X)); |
488 | EXPECT_TRUE(m_Unless(m_Add(m_Zero(), m_One())).match(X)); |
489 | |
490 | EXPECT_TRUE(m_c_Add(m_One(), m_Zero()).match(X)); |
491 | EXPECT_TRUE(m_c_Add(m_Zero(), m_One()).match(X)); |
492 | |
493 | EXPECT_FALSE(m_Unless(m_c_Add(m_One(), m_Zero())).match(X)); |
494 | EXPECT_FALSE(m_Unless(m_c_Add(m_Zero(), m_One())).match(X)); |
495 | } |
496 | |
497 | TEST_F(PatternMatchTest, BitWise) { |
498 | Value *Or = IRB.CreateOr(LHS: IRB.getInt32(C: 1), RHS: IRB.getInt32(C: 0)); |
499 | Value *Xor = IRB.CreateXor(LHS: IRB.getInt32(C: 1), RHS: IRB.getInt32(C: 0)); |
500 | Value *And = IRB.CreateXor(LHS: IRB.getInt32(C: 1), RHS: IRB.getInt32(C: 0)); |
501 | Constant *T = IRB.getInt1(V: true); |
502 | Constant *F = IRB.getInt1(V: false); |
503 | Value *Alloca = IRB.CreateAlloca(Ty: IRB.getInt1Ty()); |
504 | Value *X = IRB.CreateLoad(Ty: IRB.getInt1Ty(), Ptr: Alloca); |
505 | Value *Y = IRB.CreateLoad(Ty: IRB.getInt1Ty(), Ptr: Alloca); |
506 | Value *LAnd = IRB.CreateSelect(C: X, True: Y, False: F); |
507 | Value *LOr = IRB.CreateSelect(C: X, True: T, False: Y); |
508 | Value *Add = IRB.CreateAdd(LHS: IRB.getInt32(C: 1), RHS: IRB.getInt32(C: 0)); |
509 | |
510 | EXPECT_TRUE(m_BitwiseLogic(m_One(), m_Zero()).match(Or)); |
511 | EXPECT_TRUE(m_BitwiseLogic(m_One(), m_Zero()).match(Xor)); |
512 | EXPECT_TRUE(m_BitwiseLogic(m_One(), m_Zero()).match(And)); |
513 | EXPECT_FALSE(m_BitwiseLogic(m_Value(), m_Value()).match(LAnd)); |
514 | EXPECT_FALSE(m_BitwiseLogic(m_Value(), m_Value()).match(LOr)); |
515 | EXPECT_FALSE(m_BitwiseLogic(m_Value(), m_Value()).match(Add)); |
516 | |
517 | EXPECT_FALSE(m_BitwiseLogic(m_Zero(), m_One()).match(Or)); |
518 | EXPECT_FALSE(m_BitwiseLogic(m_Zero(), m_One()).match(Xor)); |
519 | EXPECT_FALSE(m_BitwiseLogic(m_Zero(), m_One()).match(And)); |
520 | |
521 | EXPECT_TRUE(m_c_BitwiseLogic(m_One(), m_Zero()).match(Or)); |
522 | EXPECT_TRUE(m_c_BitwiseLogic(m_One(), m_Zero()).match(Xor)); |
523 | EXPECT_TRUE(m_c_BitwiseLogic(m_One(), m_Zero()).match(And)); |
524 | EXPECT_FALSE(m_c_BitwiseLogic(m_Value(), m_Value()).match(LAnd)); |
525 | EXPECT_FALSE(m_c_BitwiseLogic(m_Value(), m_Value()).match(LOr)); |
526 | EXPECT_FALSE(m_c_BitwiseLogic(m_Value(), m_Value()).match(Add)); |
527 | |
528 | EXPECT_TRUE(m_c_BitwiseLogic(m_Zero(), m_One()).match(Or)); |
529 | EXPECT_TRUE(m_c_BitwiseLogic(m_Zero(), m_One()).match(Xor)); |
530 | EXPECT_TRUE(m_c_BitwiseLogic(m_Zero(), m_One()).match(And)); |
531 | |
532 | EXPECT_FALSE(m_c_BitwiseLogic(m_One(), m_One()).match(Or)); |
533 | EXPECT_FALSE(m_c_BitwiseLogic(m_Zero(), m_Zero()).match(Xor)); |
534 | } |
535 | |
536 | TEST_F(PatternMatchTest, ZExtSExtSelf) { |
537 | LLVMContext &Ctx = IRB.getContext(); |
538 | |
539 | Value *One32 = IRB.getInt32(C: 1); |
540 | Value *One64Z = IRB.CreateZExt(V: One32, DestTy: IntegerType::getInt64Ty(C&: Ctx)); |
541 | Value *One64S = IRB.CreateSExt(V: One32, DestTy: IntegerType::getInt64Ty(C&: Ctx)); |
542 | |
543 | EXPECT_TRUE(m_One().match(One32)); |
544 | EXPECT_FALSE(m_One().match(One64Z)); |
545 | EXPECT_FALSE(m_One().match(One64S)); |
546 | |
547 | EXPECT_FALSE(m_ZExt(m_One()).match(One32)); |
548 | EXPECT_TRUE(m_ZExt(m_One()).match(One64Z)); |
549 | EXPECT_FALSE(m_ZExt(m_One()).match(One64S)); |
550 | |
551 | EXPECT_FALSE(m_SExt(m_One()).match(One32)); |
552 | EXPECT_FALSE(m_SExt(m_One()).match(One64Z)); |
553 | EXPECT_TRUE(m_SExt(m_One()).match(One64S)); |
554 | |
555 | EXPECT_TRUE(m_ZExtOrSelf(m_One()).match(One32)); |
556 | EXPECT_TRUE(m_ZExtOrSelf(m_One()).match(One64Z)); |
557 | EXPECT_FALSE(m_ZExtOrSelf(m_One()).match(One64S)); |
558 | |
559 | EXPECT_TRUE(m_SExtOrSelf(m_One()).match(One32)); |
560 | EXPECT_FALSE(m_SExtOrSelf(m_One()).match(One64Z)); |
561 | EXPECT_TRUE(m_SExtOrSelf(m_One()).match(One64S)); |
562 | |
563 | EXPECT_FALSE(m_ZExtOrSExt(m_One()).match(One32)); |
564 | EXPECT_TRUE(m_ZExtOrSExt(m_One()).match(One64Z)); |
565 | EXPECT_TRUE(m_ZExtOrSExt(m_One()).match(One64S)); |
566 | |
567 | EXPECT_TRUE(m_ZExtOrSExtOrSelf(m_One()).match(One32)); |
568 | EXPECT_TRUE(m_ZExtOrSExtOrSelf(m_One()).match(One64Z)); |
569 | EXPECT_TRUE(m_ZExtOrSExtOrSelf(m_One()).match(One64S)); |
570 | } |
571 | |
572 | TEST_F(PatternMatchTest, BitCast) { |
573 | Value *OneDouble = ConstantFP::get(Ty: IRB.getDoubleTy(), V: APFloat(1.0)); |
574 | Value *ScalableDouble = ConstantFP::get( |
575 | Ty: VectorType::get(ElementType: IRB.getDoubleTy(), NumElements: 2, /*Scalable=*/true), V: APFloat(1.0)); |
576 | // scalar -> scalar |
577 | Value *DoubleToI64 = IRB.CreateBitCast(V: OneDouble, DestTy: IRB.getInt64Ty()); |
578 | // scalar -> vector |
579 | Value *DoubleToV2I32 = IRB.CreateBitCast( |
580 | V: OneDouble, DestTy: VectorType::get(ElementType: IRB.getInt32Ty(), NumElements: 2, /*Scalable=*/false)); |
581 | // vector -> scalar |
582 | Value *V2I32ToDouble = IRB.CreateBitCast(V: DoubleToV2I32, DestTy: IRB.getDoubleTy()); |
583 | // vector -> vector (same count) |
584 | Value *V2I32ToV2Float = IRB.CreateBitCast( |
585 | V: DoubleToV2I32, DestTy: VectorType::get(ElementType: IRB.getFloatTy(), NumElements: 2, /*Scalable=*/false)); |
586 | // vector -> vector (different count) |
587 | Value *V2I32TOV4I16 = IRB.CreateBitCast( |
588 | V: DoubleToV2I32, DestTy: VectorType::get(ElementType: IRB.getInt16Ty(), NumElements: 4, /*Scalable=*/false)); |
589 | // scalable vector -> scalable vector (same count) |
590 | Value *NXV2DoubleToNXV2I64 = IRB.CreateBitCast( |
591 | V: ScalableDouble, DestTy: VectorType::get(ElementType: IRB.getInt64Ty(), NumElements: 2, /*Scalable=*/true)); |
592 | // scalable vector -> scalable vector (different count) |
593 | Value *NXV2I64ToNXV4I32 = IRB.CreateBitCast( |
594 | V: NXV2DoubleToNXV2I64, |
595 | DestTy: VectorType::get(ElementType: IRB.getInt32Ty(), NumElements: 4, /*Scalable=*/true)); |
596 | |
597 | EXPECT_TRUE(m_BitCast(m_Value()).match(DoubleToI64)); |
598 | EXPECT_TRUE(m_BitCast(m_Value()).match(DoubleToV2I32)); |
599 | EXPECT_TRUE(m_BitCast(m_Value()).match(V2I32ToDouble)); |
600 | EXPECT_TRUE(m_BitCast(m_Value()).match(V2I32ToV2Float)); |
601 | EXPECT_TRUE(m_BitCast(m_Value()).match(V2I32TOV4I16)); |
602 | EXPECT_TRUE(m_BitCast(m_Value()).match(NXV2DoubleToNXV2I64)); |
603 | EXPECT_TRUE(m_BitCast(m_Value()).match(NXV2I64ToNXV4I32)); |
604 | |
605 | EXPECT_TRUE(m_ElementWiseBitCast(m_Value()).match(DoubleToI64)); |
606 | EXPECT_FALSE(m_ElementWiseBitCast(m_Value()).match(DoubleToV2I32)); |
607 | EXPECT_FALSE(m_ElementWiseBitCast(m_Value()).match(V2I32ToDouble)); |
608 | EXPECT_TRUE(m_ElementWiseBitCast(m_Value()).match(V2I32ToV2Float)); |
609 | EXPECT_FALSE(m_ElementWiseBitCast(m_Value()).match(V2I32TOV4I16)); |
610 | EXPECT_TRUE(m_ElementWiseBitCast(m_Value()).match(NXV2DoubleToNXV2I64)); |
611 | EXPECT_FALSE(m_ElementWiseBitCast(m_Value()).match(NXV2I64ToNXV4I32)); |
612 | } |
613 | |
614 | TEST_F(PatternMatchTest, Power2) { |
615 | Value *C128 = IRB.getInt32(C: 128); |
616 | Value *CNeg128 = ConstantExpr::getNeg(C: cast<Constant>(Val: C128)); |
617 | |
618 | EXPECT_TRUE(m_Power2().match(C128)); |
619 | EXPECT_FALSE(m_Power2().match(CNeg128)); |
620 | |
621 | EXPECT_TRUE(m_Power2OrZero().match(C128)); |
622 | EXPECT_FALSE(m_Power2OrZero().match(CNeg128)); |
623 | |
624 | EXPECT_FALSE(m_NegatedPower2().match(C128)); |
625 | EXPECT_TRUE(m_NegatedPower2().match(CNeg128)); |
626 | |
627 | EXPECT_FALSE(m_NegatedPower2OrZero().match(C128)); |
628 | EXPECT_TRUE(m_NegatedPower2OrZero().match(CNeg128)); |
629 | |
630 | Value *CIntMin = IRB.getInt64(C: APSInt::getSignedMinValue(numBits: 64).getSExtValue()); |
631 | Value *CNegIntMin = ConstantExpr::getNeg(C: cast<Constant>(Val: CIntMin)); |
632 | |
633 | EXPECT_TRUE(m_Power2().match(CIntMin)); |
634 | EXPECT_TRUE(m_Power2().match(CNegIntMin)); |
635 | |
636 | EXPECT_TRUE(m_Power2OrZero().match(CIntMin)); |
637 | EXPECT_TRUE(m_Power2OrZero().match(CNegIntMin)); |
638 | |
639 | EXPECT_TRUE(m_NegatedPower2().match(CIntMin)); |
640 | EXPECT_TRUE(m_NegatedPower2().match(CNegIntMin)); |
641 | |
642 | EXPECT_TRUE(m_NegatedPower2OrZero().match(CIntMin)); |
643 | EXPECT_TRUE(m_NegatedPower2OrZero().match(CNegIntMin)); |
644 | |
645 | Value *CZero = IRB.getInt64(C: 0); |
646 | |
647 | EXPECT_FALSE(m_Power2().match(CZero)); |
648 | |
649 | EXPECT_TRUE(m_Power2OrZero().match(CZero)); |
650 | |
651 | EXPECT_FALSE(m_NegatedPower2().match(CZero)); |
652 | |
653 | EXPECT_TRUE(m_NegatedPower2OrZero().match(CZero)); |
654 | } |
655 | |
656 | TEST_F(PatternMatchTest, Not) { |
657 | Value *C1 = IRB.getInt32(C: 1); |
658 | Value *C2 = IRB.getInt32(C: 2); |
659 | Value *C3 = IRB.getInt32(C: 3); |
660 | Instruction *Not = BinaryOperator::CreateXor(V1: C1, V2: C2); |
661 | |
662 | // When `m_Not` does not match the `not` itself, |
663 | // it should not try to apply the inner matcher. |
664 | Value *Val = C3; |
665 | EXPECT_FALSE(m_Not(m_Value(Val)).match(Not)); |
666 | EXPECT_EQ(Val, C3); |
667 | Not->deleteValue(); |
668 | } |
669 | |
670 | TEST_F(PatternMatchTest, CommutativeDeferredValue) { |
671 | Value *X = IRB.getInt32(C: 1); |
672 | Value *Y = IRB.getInt32(C: 2); |
673 | |
674 | { |
675 | Value *tX = X; |
676 | EXPECT_TRUE(match(X, m_Deferred(tX))); |
677 | EXPECT_FALSE(match(Y, m_Deferred(tX))); |
678 | } |
679 | { |
680 | const Value *tX = X; |
681 | EXPECT_TRUE(match(X, m_Deferred(tX))); |
682 | EXPECT_FALSE(match(Y, m_Deferred(tX))); |
683 | } |
684 | { |
685 | Value *const tX = X; |
686 | EXPECT_TRUE(match(X, m_Deferred(tX))); |
687 | EXPECT_FALSE(match(Y, m_Deferred(tX))); |
688 | } |
689 | { |
690 | const Value *const tX = X; |
691 | EXPECT_TRUE(match(X, m_Deferred(tX))); |
692 | EXPECT_FALSE(match(Y, m_Deferred(tX))); |
693 | } |
694 | |
695 | { |
696 | Value *tX = nullptr; |
697 | EXPECT_TRUE(match(IRB.CreateAnd(X, X), m_And(m_Value(tX), m_Deferred(tX)))); |
698 | EXPECT_EQ(tX, X); |
699 | } |
700 | { |
701 | Value *tX = nullptr; |
702 | EXPECT_FALSE( |
703 | match(IRB.CreateAnd(X, Y), m_c_And(m_Value(tX), m_Deferred(tX)))); |
704 | } |
705 | |
706 | auto checkMatch = [X, Y](Value *Pattern) { |
707 | Value *tX = nullptr, *tY = nullptr; |
708 | EXPECT_TRUE(match( |
709 | Pattern, m_c_And(m_Value(tX), m_c_And(m_Deferred(tX), m_Value(tY))))); |
710 | EXPECT_EQ(tX, X); |
711 | EXPECT_EQ(tY, Y); |
712 | }; |
713 | |
714 | checkMatch(IRB.CreateAnd(LHS: X, RHS: IRB.CreateAnd(LHS: X, RHS: Y))); |
715 | checkMatch(IRB.CreateAnd(LHS: X, RHS: IRB.CreateAnd(LHS: Y, RHS: X))); |
716 | checkMatch(IRB.CreateAnd(LHS: IRB.CreateAnd(LHS: X, RHS: Y), RHS: X)); |
717 | checkMatch(IRB.CreateAnd(LHS: IRB.CreateAnd(LHS: Y, RHS: X), RHS: X)); |
718 | } |
719 | |
720 | TEST_F(PatternMatchTest, FloatingPointOrderedMin) { |
721 | Type *FltTy = IRB.getFloatTy(); |
722 | Value *L = ConstantFP::get(Ty: FltTy, V: 1.0); |
723 | Value *R = ConstantFP::get(Ty: FltTy, V: 2.0); |
724 | Value *MatchL, *MatchR; |
725 | |
726 | // Test OLT. |
727 | EXPECT_TRUE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR)) |
728 | .match(IRB.CreateSelect(IRB.CreateFCmpOLT(L, R), L, R))); |
729 | EXPECT_EQ(L, MatchL); |
730 | EXPECT_EQ(R, MatchR); |
731 | |
732 | // Test OLE. |
733 | EXPECT_TRUE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR)) |
734 | .match(IRB.CreateSelect(IRB.CreateFCmpOLE(L, R), L, R))); |
735 | EXPECT_EQ(L, MatchL); |
736 | EXPECT_EQ(R, MatchR); |
737 | |
738 | // Test no match on OGE. |
739 | EXPECT_FALSE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR)) |
740 | .match(IRB.CreateSelect(IRB.CreateFCmpOGE(L, R), L, R))); |
741 | |
742 | // Test no match on OGT. |
743 | EXPECT_FALSE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR)) |
744 | .match(IRB.CreateSelect(IRB.CreateFCmpOGT(L, R), L, R))); |
745 | |
746 | // Test inverted selects. Note, that this "inverts" the ordering, e.g.: |
747 | // %cmp = fcmp oge L, R |
748 | // %min = select %cmp R, L |
749 | // Given L == NaN |
750 | // the above is expanded to %cmp == false ==> %min = L |
751 | // which is true for UnordFMin, not OrdFMin, so test that: |
752 | |
753 | // [OU]GE with inverted select. |
754 | EXPECT_FALSE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR)) |
755 | .match(IRB.CreateSelect(IRB.CreateFCmpOGE(L, R), R, L))); |
756 | EXPECT_TRUE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR)) |
757 | .match(IRB.CreateSelect(IRB.CreateFCmpUGE(L, R), R, L))); |
758 | EXPECT_EQ(L, MatchL); |
759 | EXPECT_EQ(R, MatchR); |
760 | |
761 | // [OU]GT with inverted select. |
762 | EXPECT_FALSE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR)) |
763 | .match(IRB.CreateSelect(IRB.CreateFCmpOGT(L, R), R, L))); |
764 | EXPECT_TRUE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR)) |
765 | .match(IRB.CreateSelect(IRB.CreateFCmpUGT(L, R), R, L))); |
766 | EXPECT_EQ(L, MatchL); |
767 | EXPECT_EQ(R, MatchR); |
768 | } |
769 | |
770 | TEST_F(PatternMatchTest, FloatingPointOrderedMax) { |
771 | Type *FltTy = IRB.getFloatTy(); |
772 | Value *L = ConstantFP::get(Ty: FltTy, V: 1.0); |
773 | Value *R = ConstantFP::get(Ty: FltTy, V: 2.0); |
774 | Value *MatchL, *MatchR; |
775 | |
776 | // Test OGT. |
777 | EXPECT_TRUE(m_OrdFMax(m_Value(MatchL), m_Value(MatchR)) |
778 | .match(IRB.CreateSelect(IRB.CreateFCmpOGT(L, R), L, R))); |
779 | EXPECT_EQ(L, MatchL); |
780 | EXPECT_EQ(R, MatchR); |
781 | |
782 | // Test OGE. |
783 | EXPECT_TRUE(m_OrdFMax(m_Value(MatchL), m_Value(MatchR)) |
784 | .match(IRB.CreateSelect(IRB.CreateFCmpOGE(L, R), L, R))); |
785 | EXPECT_EQ(L, MatchL); |
786 | EXPECT_EQ(R, MatchR); |
787 | |
788 | // Test no match on OLE. |
789 | EXPECT_FALSE(m_OrdFMax(m_Value(MatchL), m_Value(MatchR)) |
790 | .match(IRB.CreateSelect(IRB.CreateFCmpOLE(L, R), L, R))); |
791 | |
792 | // Test no match on OLT. |
793 | EXPECT_FALSE(m_OrdFMax(m_Value(MatchL), m_Value(MatchR)) |
794 | .match(IRB.CreateSelect(IRB.CreateFCmpOLT(L, R), L, R))); |
795 | |
796 | |
797 | // Test inverted selects. Note, that this "inverts" the ordering, e.g.: |
798 | // %cmp = fcmp ole L, R |
799 | // %max = select %cmp, R, L |
800 | // Given L == NaN, |
801 | // the above is expanded to %cmp == false ==> %max == L |
802 | // which is true for UnordFMax, not OrdFMax, so test that: |
803 | |
804 | // [OU]LE with inverted select. |
805 | EXPECT_FALSE(m_OrdFMax(m_Value(MatchL), m_Value(MatchR)) |
806 | .match(IRB.CreateSelect(IRB.CreateFCmpOLE(L, R), R, L))); |
807 | EXPECT_TRUE(m_OrdFMax(m_Value(MatchL), m_Value(MatchR)) |
808 | .match(IRB.CreateSelect(IRB.CreateFCmpULE(L, R), R, L))); |
809 | EXPECT_EQ(L, MatchL); |
810 | EXPECT_EQ(R, MatchR); |
811 | |
812 | // [OUT]LT with inverted select. |
813 | EXPECT_FALSE(m_OrdFMax(m_Value(MatchL), m_Value(MatchR)) |
814 | .match(IRB.CreateSelect(IRB.CreateFCmpOLT(L, R), R, L))); |
815 | EXPECT_TRUE(m_OrdFMax(m_Value(MatchL), m_Value(MatchR)) |
816 | .match(IRB.CreateSelect(IRB.CreateFCmpULT(L, R), R, L))); |
817 | EXPECT_EQ(L, MatchL); |
818 | EXPECT_EQ(R, MatchR); |
819 | } |
820 | |
821 | TEST_F(PatternMatchTest, FloatingPointUnorderedMin) { |
822 | Type *FltTy = IRB.getFloatTy(); |
823 | Value *L = ConstantFP::get(Ty: FltTy, V: 1.0); |
824 | Value *R = ConstantFP::get(Ty: FltTy, V: 2.0); |
825 | Value *MatchL, *MatchR; |
826 | |
827 | // Test ULT. |
828 | EXPECT_TRUE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR)) |
829 | .match(IRB.CreateSelect(IRB.CreateFCmpULT(L, R), L, R))); |
830 | EXPECT_EQ(L, MatchL); |
831 | EXPECT_EQ(R, MatchR); |
832 | |
833 | // Test ULE. |
834 | EXPECT_TRUE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR)) |
835 | .match(IRB.CreateSelect(IRB.CreateFCmpULE(L, R), L, R))); |
836 | EXPECT_EQ(L, MatchL); |
837 | EXPECT_EQ(R, MatchR); |
838 | |
839 | // Test no match on UGE. |
840 | EXPECT_FALSE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR)) |
841 | .match(IRB.CreateSelect(IRB.CreateFCmpUGE(L, R), L, R))); |
842 | |
843 | // Test no match on UGT. |
844 | EXPECT_FALSE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR)) |
845 | .match(IRB.CreateSelect(IRB.CreateFCmpUGT(L, R), L, R))); |
846 | |
847 | // Test inverted selects. Note, that this "inverts" the ordering, e.g.: |
848 | // %cmp = fcmp uge L, R |
849 | // %min = select %cmp R, L |
850 | // Given L == NaN |
851 | // the above is expanded to %cmp == true ==> %min = R |
852 | // which is true for OrdFMin, not UnordFMin, so test that: |
853 | |
854 | // [UO]GE with inverted select. |
855 | EXPECT_FALSE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR)) |
856 | .match(IRB.CreateSelect(IRB.CreateFCmpUGE(L, R), R, L))); |
857 | EXPECT_TRUE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR)) |
858 | .match(IRB.CreateSelect(IRB.CreateFCmpOGE(L, R), R, L))); |
859 | EXPECT_EQ(L, MatchL); |
860 | EXPECT_EQ(R, MatchR); |
861 | |
862 | // [UO]GT with inverted select. |
863 | EXPECT_FALSE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR)) |
864 | .match(IRB.CreateSelect(IRB.CreateFCmpUGT(L, R), R, L))); |
865 | EXPECT_TRUE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR)) |
866 | .match(IRB.CreateSelect(IRB.CreateFCmpOGT(L, R), R, L))); |
867 | EXPECT_EQ(L, MatchL); |
868 | EXPECT_EQ(R, MatchR); |
869 | } |
870 | |
871 | TEST_F(PatternMatchTest, FloatingPointUnorderedMax) { |
872 | Type *FltTy = IRB.getFloatTy(); |
873 | Value *L = ConstantFP::get(Ty: FltTy, V: 1.0); |
874 | Value *R = ConstantFP::get(Ty: FltTy, V: 2.0); |
875 | Value *MatchL, *MatchR; |
876 | |
877 | // Test UGT. |
878 | EXPECT_TRUE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR)) |
879 | .match(IRB.CreateSelect(IRB.CreateFCmpUGT(L, R), L, R))); |
880 | EXPECT_EQ(L, MatchL); |
881 | EXPECT_EQ(R, MatchR); |
882 | |
883 | // Test UGE. |
884 | EXPECT_TRUE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR)) |
885 | .match(IRB.CreateSelect(IRB.CreateFCmpUGE(L, R), L, R))); |
886 | EXPECT_EQ(L, MatchL); |
887 | EXPECT_EQ(R, MatchR); |
888 | |
889 | // Test no match on ULE. |
890 | EXPECT_FALSE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR)) |
891 | .match(IRB.CreateSelect(IRB.CreateFCmpULE(L, R), L, R))); |
892 | |
893 | // Test no match on ULT. |
894 | EXPECT_FALSE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR)) |
895 | .match(IRB.CreateSelect(IRB.CreateFCmpULT(L, R), L, R))); |
896 | |
897 | // Test inverted selects. Note, that this "inverts" the ordering, e.g.: |
898 | // %cmp = fcmp ule L, R |
899 | // %max = select %cmp R, L |
900 | // Given L == NaN |
901 | // the above is expanded to %cmp == true ==> %max = R |
902 | // which is true for OrdFMax, not UnordFMax, so test that: |
903 | |
904 | // [UO]LE with inverted select. |
905 | EXPECT_FALSE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR)) |
906 | .match(IRB.CreateSelect(IRB.CreateFCmpULE(L, R), R, L))); |
907 | EXPECT_TRUE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR)) |
908 | .match(IRB.CreateSelect(IRB.CreateFCmpOLE(L, R), R, L))); |
909 | EXPECT_EQ(L, MatchL); |
910 | EXPECT_EQ(R, MatchR); |
911 | |
912 | // [UO]LT with inverted select. |
913 | EXPECT_FALSE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR)) |
914 | .match(IRB.CreateSelect(IRB.CreateFCmpULT(L, R), R, L))); |
915 | EXPECT_TRUE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR)) |
916 | .match(IRB.CreateSelect(IRB.CreateFCmpOLT(L, R), R, L))); |
917 | EXPECT_EQ(L, MatchL); |
918 | EXPECT_EQ(R, MatchR); |
919 | } |
920 | |
921 | TEST_F(PatternMatchTest, OverflowingBinOps) { |
922 | Value *L = IRB.getInt32(C: 1); |
923 | Value *R = IRB.getInt32(C: 2); |
924 | Value *MatchL, *MatchR; |
925 | |
926 | EXPECT_TRUE( |
927 | m_NSWAdd(m_Value(MatchL), m_Value(MatchR)).match(IRB.CreateNSWAdd(L, R))); |
928 | EXPECT_EQ(L, MatchL); |
929 | EXPECT_EQ(R, MatchR); |
930 | MatchL = MatchR = nullptr; |
931 | EXPECT_TRUE( |
932 | m_NSWSub(m_Value(MatchL), m_Value(MatchR)).match(IRB.CreateNSWSub(L, R))); |
933 | EXPECT_EQ(L, MatchL); |
934 | EXPECT_EQ(R, MatchR); |
935 | MatchL = MatchR = nullptr; |
936 | EXPECT_TRUE( |
937 | m_NSWMul(m_Value(MatchL), m_Value(MatchR)).match(IRB.CreateNSWMul(L, R))); |
938 | EXPECT_EQ(L, MatchL); |
939 | EXPECT_EQ(R, MatchR); |
940 | MatchL = MatchR = nullptr; |
941 | EXPECT_TRUE(m_NSWShl(m_Value(MatchL), m_Value(MatchR)).match( |
942 | IRB.CreateShl(L, R, "" , /* NUW */ false, /* NSW */ true))); |
943 | EXPECT_EQ(L, MatchL); |
944 | EXPECT_EQ(R, MatchR); |
945 | |
946 | EXPECT_TRUE( |
947 | m_NUWAdd(m_Value(MatchL), m_Value(MatchR)).match(IRB.CreateNUWAdd(L, R))); |
948 | EXPECT_EQ(L, MatchL); |
949 | EXPECT_EQ(R, MatchR); |
950 | MatchL = MatchR = nullptr; |
951 | |
952 | EXPECT_TRUE( |
953 | m_c_NUWAdd(m_Specific(L), m_Specific(R)).match(IRB.CreateNUWAdd(L, R))); |
954 | EXPECT_TRUE( |
955 | m_c_NUWAdd(m_Specific(R), m_Specific(L)).match(IRB.CreateNUWAdd(L, R))); |
956 | EXPECT_FALSE( |
957 | m_c_NUWAdd(m_Specific(R), m_ZeroInt()).match(IRB.CreateNUWAdd(L, R))); |
958 | EXPECT_FALSE( |
959 | m_NUWAdd(m_Specific(R), m_Specific(L)).match(IRB.CreateNUWAdd(L, R))); |
960 | |
961 | EXPECT_TRUE( |
962 | m_NUWSub(m_Value(MatchL), m_Value(MatchR)).match(IRB.CreateNUWSub(L, R))); |
963 | EXPECT_EQ(L, MatchL); |
964 | EXPECT_EQ(R, MatchR); |
965 | MatchL = MatchR = nullptr; |
966 | EXPECT_TRUE( |
967 | m_NUWMul(m_Value(MatchL), m_Value(MatchR)).match(IRB.CreateNUWMul(L, R))); |
968 | EXPECT_EQ(L, MatchL); |
969 | EXPECT_EQ(R, MatchR); |
970 | MatchL = MatchR = nullptr; |
971 | EXPECT_TRUE(m_NUWShl(m_Value(MatchL), m_Value(MatchR)).match( |
972 | IRB.CreateShl(L, R, "" , /* NUW */ true, /* NSW */ false))); |
973 | EXPECT_EQ(L, MatchL); |
974 | EXPECT_EQ(R, MatchR); |
975 | |
976 | EXPECT_FALSE(m_NSWAdd(m_Value(), m_Value()).match(IRB.CreateAdd(L, R))); |
977 | EXPECT_FALSE(m_NSWAdd(m_Value(), m_Value()).match(IRB.CreateNUWAdd(L, R))); |
978 | EXPECT_FALSE(m_NSWAdd(m_Value(), m_Value()).match(IRB.CreateNSWSub(L, R))); |
979 | EXPECT_FALSE(m_NSWSub(m_Value(), m_Value()).match(IRB.CreateSub(L, R))); |
980 | EXPECT_FALSE(m_NSWSub(m_Value(), m_Value()).match(IRB.CreateNUWSub(L, R))); |
981 | EXPECT_FALSE(m_NSWSub(m_Value(), m_Value()).match(IRB.CreateNSWAdd(L, R))); |
982 | EXPECT_FALSE(m_NSWMul(m_Value(), m_Value()).match(IRB.CreateMul(L, R))); |
983 | EXPECT_FALSE(m_NSWMul(m_Value(), m_Value()).match(IRB.CreateNUWMul(L, R))); |
984 | EXPECT_FALSE(m_NSWMul(m_Value(), m_Value()).match(IRB.CreateNSWAdd(L, R))); |
985 | EXPECT_FALSE(m_NSWShl(m_Value(), m_Value()).match(IRB.CreateShl(L, R))); |
986 | EXPECT_FALSE(m_NSWShl(m_Value(), m_Value()).match( |
987 | IRB.CreateShl(L, R, "" , /* NUW */ true, /* NSW */ false))); |
988 | EXPECT_FALSE(m_NSWShl(m_Value(), m_Value()).match(IRB.CreateNSWAdd(L, R))); |
989 | |
990 | EXPECT_FALSE(m_NUWAdd(m_Value(), m_Value()).match(IRB.CreateAdd(L, R))); |
991 | EXPECT_FALSE(m_NUWAdd(m_Value(), m_Value()).match(IRB.CreateNSWAdd(L, R))); |
992 | EXPECT_FALSE(m_NUWAdd(m_Value(), m_Value()).match(IRB.CreateNUWSub(L, R))); |
993 | EXPECT_FALSE(m_NUWSub(m_Value(), m_Value()).match(IRB.CreateSub(L, R))); |
994 | EXPECT_FALSE(m_NUWSub(m_Value(), m_Value()).match(IRB.CreateNSWSub(L, R))); |
995 | EXPECT_FALSE(m_NUWSub(m_Value(), m_Value()).match(IRB.CreateNUWAdd(L, R))); |
996 | EXPECT_FALSE(m_NUWMul(m_Value(), m_Value()).match(IRB.CreateMul(L, R))); |
997 | EXPECT_FALSE(m_NUWMul(m_Value(), m_Value()).match(IRB.CreateNSWMul(L, R))); |
998 | EXPECT_FALSE(m_NUWMul(m_Value(), m_Value()).match(IRB.CreateNUWAdd(L, R))); |
999 | EXPECT_FALSE(m_NUWShl(m_Value(), m_Value()).match(IRB.CreateShl(L, R))); |
1000 | EXPECT_FALSE(m_NUWShl(m_Value(), m_Value()).match( |
1001 | IRB.CreateShl(L, R, "" , /* NUW */ false, /* NSW */ true))); |
1002 | EXPECT_FALSE(m_NUWShl(m_Value(), m_Value()).match(IRB.CreateNUWAdd(L, R))); |
1003 | } |
1004 | |
1005 | TEST_F(PatternMatchTest, LoadStoreOps) { |
1006 | // Create this load/store sequence: |
1007 | // |
1008 | // %p = alloca i32* |
1009 | // %0 = load i32*, i32** %p |
1010 | // store i32 42, i32* %0 |
1011 | |
1012 | Value *Alloca = IRB.CreateAlloca(Ty: IRB.getInt32Ty()); |
1013 | Value *LoadInst = IRB.CreateLoad(Ty: IRB.getInt32Ty(), Ptr: Alloca); |
1014 | Value *FourtyTwo = IRB.getInt32(C: 42); |
1015 | Value *StoreInst = IRB.CreateStore(Val: FourtyTwo, Ptr: Alloca); |
1016 | Value *MatchLoad, *MatchStoreVal, *MatchStorePointer; |
1017 | |
1018 | EXPECT_TRUE(m_Load(m_Value(MatchLoad)).match(LoadInst)); |
1019 | EXPECT_EQ(Alloca, MatchLoad); |
1020 | |
1021 | EXPECT_TRUE(m_Load(m_Specific(Alloca)).match(LoadInst)); |
1022 | |
1023 | EXPECT_FALSE(m_Load(m_Value(MatchLoad)).match(Alloca)); |
1024 | |
1025 | EXPECT_TRUE(m_Store(m_Value(MatchStoreVal), m_Value(MatchStorePointer)) |
1026 | .match(StoreInst)); |
1027 | EXPECT_EQ(FourtyTwo, MatchStoreVal); |
1028 | EXPECT_EQ(Alloca, MatchStorePointer); |
1029 | |
1030 | EXPECT_FALSE(m_Store(m_Value(MatchStoreVal), m_Value(MatchStorePointer)) |
1031 | .match(Alloca)); |
1032 | |
1033 | EXPECT_TRUE(m_Store(m_SpecificInt(42), m_Specific(Alloca)) |
1034 | .match(StoreInst)); |
1035 | EXPECT_FALSE(m_Store(m_SpecificInt(42), m_Specific(FourtyTwo)) |
1036 | .match(StoreInst)); |
1037 | EXPECT_FALSE(m_Store(m_SpecificInt(43), m_Specific(Alloca)) |
1038 | .match(StoreInst)); |
1039 | } |
1040 | |
1041 | TEST_F(PatternMatchTest, VectorOps) { |
1042 | // Build up small tree of vector operations |
1043 | // |
1044 | // Val = 0 + 1 |
1045 | // Val2 = Val + 3 |
1046 | // VI1 = insertelement <2 x i8> undef, i8 1, i32 0 = <1, undef> |
1047 | // VI2 = insertelement <2 x i8> %VI1, i8 %Val2, i8 %Val = <1, 4> |
1048 | // VI3 = insertelement <2 x i8> %VI1, i8 %Val2, i32 1 = <1, 4> |
1049 | // VI4 = insertelement <2 x i8> %VI1, i8 2, i8 %Val = <1, 2> |
1050 | // |
1051 | // SI1 = shufflevector <2 x i8> %VI1, <2 x i8> undef, zeroinitializer |
1052 | // SI2 = shufflevector <2 x i8> %VI3, <2 x i8> %VI4, <2 x i8> <i8 0, i8 2> |
1053 | // SI3 = shufflevector <2 x i8> %VI3, <2 x i8> undef, zeroinitializer |
1054 | // SI4 = shufflevector <2 x i8> %VI4, <2 x i8> undef, zeroinitializer |
1055 | // |
1056 | // SP1 = VectorSplat(2, i8 2) |
1057 | // SP2 = VectorSplat(2, i8 %Val) |
1058 | Type *VecTy = FixedVectorType::get(ElementType: IRB.getInt8Ty(), NumElts: 2); |
1059 | Type *i32 = IRB.getInt32Ty(); |
1060 | Type *i32VecTy = FixedVectorType::get(ElementType: i32, NumElts: 2); |
1061 | |
1062 | Value *Val = IRB.CreateAdd(LHS: IRB.getInt8(C: 0), RHS: IRB.getInt8(C: 1)); |
1063 | Value *Val2 = IRB.CreateAdd(LHS: Val, RHS: IRB.getInt8(C: 3)); |
1064 | |
1065 | SmallVector<Constant *, 2> VecElemIdxs; |
1066 | VecElemIdxs.push_back(Elt: ConstantInt::get(Ty: i32, V: 0)); |
1067 | VecElemIdxs.push_back(Elt: ConstantInt::get(Ty: i32, V: 2)); |
1068 | auto *IdxVec = ConstantVector::get(V: VecElemIdxs); |
1069 | |
1070 | Value *VI1 = IRB.CreateInsertElement(VecTy, NewElt: IRB.getInt8(C: 1), Idx: (uint64_t)0); |
1071 | Value *VI2 = IRB.CreateInsertElement(Vec: VI1, NewElt: Val2, Idx: Val); |
1072 | Value *VI3 = IRB.CreateInsertElement(Vec: VI1, NewElt: Val2, Idx: (uint64_t)1); |
1073 | Value *VI4 = IRB.CreateInsertElement(Vec: VI1, NewElt: IRB.getInt8(C: 2), Idx: Val); |
1074 | |
1075 | Value *EX1 = IRB.CreateExtractElement(Vec: VI4, Idx: Val); |
1076 | Value *EX2 = IRB.CreateExtractElement(Vec: VI4, Idx: (uint64_t)0); |
1077 | Value *EX3 = IRB.CreateExtractElement(Vec: IdxVec, Idx: (uint64_t)1); |
1078 | |
1079 | Constant *Zero = ConstantAggregateZero::get(Ty: i32VecTy); |
1080 | SmallVector<int, 16> ZeroMask; |
1081 | ShuffleVectorInst::getShuffleMask(Mask: Zero, Result&: ZeroMask); |
1082 | |
1083 | Value *SI1 = IRB.CreateShuffleVector(V: VI1, Mask: ZeroMask); |
1084 | Value *SI2 = IRB.CreateShuffleVector(V1: VI3, V2: VI4, Mask: IdxVec); |
1085 | Value *SI3 = IRB.CreateShuffleVector(V: VI3, Mask: ZeroMask); |
1086 | Value *SI4 = IRB.CreateShuffleVector(V: VI4, Mask: ZeroMask); |
1087 | |
1088 | Value *SP1 = IRB.CreateVectorSplat(NumElts: 2, V: IRB.getInt8(C: 2)); |
1089 | Value *SP2 = IRB.CreateVectorSplat(NumElts: 2, V: Val); |
1090 | |
1091 | Value *A = nullptr, *B = nullptr, *C = nullptr; |
1092 | |
1093 | // Test matching insertelement |
1094 | EXPECT_TRUE(match(VI1, m_InsertElt(m_Value(), m_Value(), m_Value()))); |
1095 | EXPECT_TRUE( |
1096 | match(VI1, m_InsertElt(m_Undef(), m_ConstantInt(), m_ConstantInt()))); |
1097 | EXPECT_TRUE( |
1098 | match(VI1, m_InsertElt(m_Undef(), m_ConstantInt(), m_Zero()))); |
1099 | EXPECT_TRUE( |
1100 | match(VI1, m_InsertElt(m_Undef(), m_SpecificInt(1), m_Zero()))); |
1101 | EXPECT_TRUE(match(VI2, m_InsertElt(m_Value(), m_Value(), m_Value()))); |
1102 | EXPECT_FALSE( |
1103 | match(VI2, m_InsertElt(m_Value(), m_Value(), m_ConstantInt()))); |
1104 | EXPECT_FALSE( |
1105 | match(VI2, m_InsertElt(m_Value(), m_ConstantInt(), m_Value()))); |
1106 | EXPECT_FALSE(match(VI2, m_InsertElt(m_Constant(), m_Value(), m_Value()))); |
1107 | EXPECT_TRUE(match(VI3, m_InsertElt(m_Value(A), m_Value(B), m_Value(C)))); |
1108 | EXPECT_TRUE(A == VI1); |
1109 | EXPECT_TRUE(B == Val2); |
1110 | EXPECT_TRUE(isa<ConstantInt>(C)); |
1111 | A = B = C = nullptr; // reset |
1112 | |
1113 | // Test matching extractelement |
1114 | EXPECT_TRUE(match(EX1, m_ExtractElt(m_Value(A), m_Value(B)))); |
1115 | EXPECT_TRUE(A == VI4); |
1116 | EXPECT_TRUE(B == Val); |
1117 | A = B = C = nullptr; // reset |
1118 | EXPECT_FALSE(match(EX1, m_ExtractElt(m_Value(), m_ConstantInt()))); |
1119 | EXPECT_TRUE(match(EX2, m_ExtractElt(m_Value(), m_ConstantInt()))); |
1120 | EXPECT_TRUE(match(EX3, m_ExtractElt(m_Constant(), m_ConstantInt()))); |
1121 | |
1122 | // Test matching shufflevector |
1123 | ArrayRef<int> Mask; |
1124 | EXPECT_TRUE(match(SI1, m_Shuffle(m_Value(), m_Undef(), m_ZeroMask()))); |
1125 | EXPECT_TRUE(match(SI2, m_Shuffle(m_Value(A), m_Value(B), m_Mask(Mask)))); |
1126 | EXPECT_TRUE(A == VI3); |
1127 | EXPECT_TRUE(B == VI4); |
1128 | A = B = C = nullptr; // reset |
1129 | |
1130 | // Test matching the vector splat pattern |
1131 | EXPECT_TRUE(match( |
1132 | SI1, |
1133 | m_Shuffle(m_InsertElt(m_Undef(), m_SpecificInt(1), m_Zero()), |
1134 | m_Undef(), m_ZeroMask()))); |
1135 | EXPECT_FALSE(match( |
1136 | SI3, m_Shuffle(m_InsertElt(m_Undef(), m_Value(), m_Zero()), |
1137 | m_Undef(), m_ZeroMask()))); |
1138 | EXPECT_FALSE(match( |
1139 | SI4, m_Shuffle(m_InsertElt(m_Undef(), m_Value(), m_Zero()), |
1140 | m_Undef(), m_ZeroMask()))); |
1141 | EXPECT_TRUE(match( |
1142 | SP1, |
1143 | m_Shuffle(m_InsertElt(m_Undef(), m_SpecificInt(2), m_Zero()), |
1144 | m_Undef(), m_ZeroMask()))); |
1145 | EXPECT_TRUE(match( |
1146 | SP2, m_Shuffle(m_InsertElt(m_Undef(), m_Value(A), m_Zero()), |
1147 | m_Undef(), m_ZeroMask()))); |
1148 | EXPECT_TRUE(A == Val); |
1149 | } |
1150 | |
1151 | TEST_F(PatternMatchTest, UndefPoisonMix) { |
1152 | Type *ScalarTy = IRB.getInt8Ty(); |
1153 | ArrayType *ArrTy = ArrayType::get(ElementType: ScalarTy, NumElements: 2); |
1154 | StructType *StTy = StructType::get(elt1: ScalarTy, elts: ScalarTy); |
1155 | StructType *StTy2 = StructType::get(elt1: ScalarTy, elts: StTy); |
1156 | StructType *StTy3 = StructType::get(elt1: StTy, elts: ScalarTy); |
1157 | Constant *Zero = ConstantInt::getNullValue(Ty: ScalarTy); |
1158 | UndefValue *U = UndefValue::get(T: ScalarTy); |
1159 | UndefValue *P = PoisonValue::get(T: ScalarTy); |
1160 | |
1161 | EXPECT_TRUE(match(ConstantVector::get({U, P}), m_Undef())); |
1162 | EXPECT_TRUE(match(ConstantVector::get({P, U}), m_Undef())); |
1163 | |
1164 | EXPECT_TRUE(match(ConstantArray::get(ArrTy, {U, P}), m_Undef())); |
1165 | EXPECT_TRUE(match(ConstantArray::get(ArrTy, {P, U}), m_Undef())); |
1166 | |
1167 | auto *UP = ConstantStruct::get(T: StTy, V: {U, P}); |
1168 | EXPECT_TRUE(match(ConstantStruct::get(StTy2, {U, UP}), m_Undef())); |
1169 | EXPECT_TRUE(match(ConstantStruct::get(StTy2, {P, UP}), m_Undef())); |
1170 | EXPECT_TRUE(match(ConstantStruct::get(StTy3, {UP, U}), m_Undef())); |
1171 | EXPECT_TRUE(match(ConstantStruct::get(StTy3, {UP, P}), m_Undef())); |
1172 | |
1173 | EXPECT_FALSE(match(ConstantStruct::get(StTy, {U, Zero}), m_Undef())); |
1174 | EXPECT_FALSE(match(ConstantStruct::get(StTy, {Zero, U}), m_Undef())); |
1175 | EXPECT_FALSE(match(ConstantStruct::get(StTy, {P, Zero}), m_Undef())); |
1176 | EXPECT_FALSE(match(ConstantStruct::get(StTy, {Zero, P}), m_Undef())); |
1177 | |
1178 | EXPECT_FALSE(match(ConstantStruct::get(StTy2, {Zero, UP}), m_Undef())); |
1179 | EXPECT_FALSE(match(ConstantStruct::get(StTy3, {UP, Zero}), m_Undef())); |
1180 | } |
1181 | |
1182 | TEST_F(PatternMatchTest, VectorUndefInt) { |
1183 | Type *ScalarTy = IRB.getInt8Ty(); |
1184 | Type *VectorTy = FixedVectorType::get(ElementType: ScalarTy, NumElts: 4); |
1185 | Constant *ScalarUndef = UndefValue::get(T: ScalarTy); |
1186 | Constant *VectorUndef = UndefValue::get(T: VectorTy); |
1187 | Constant *ScalarPoison = PoisonValue::get(T: ScalarTy); |
1188 | Constant *VectorPoison = PoisonValue::get(T: VectorTy); |
1189 | Constant *ScalarZero = Constant::getNullValue(Ty: ScalarTy); |
1190 | Constant *VectorZero = Constant::getNullValue(Ty: VectorTy); |
1191 | |
1192 | SmallVector<Constant *, 4> Elems; |
1193 | Elems.push_back(Elt: ScalarUndef); |
1194 | Elems.push_back(Elt: ScalarZero); |
1195 | Elems.push_back(Elt: ScalarUndef); |
1196 | Elems.push_back(Elt: ScalarZero); |
1197 | Constant *VectorZeroUndef = ConstantVector::get(V: Elems); |
1198 | |
1199 | SmallVector<Constant *, 4> Elems2; |
1200 | Elems2.push_back(Elt: ScalarPoison); |
1201 | Elems2.push_back(Elt: ScalarZero); |
1202 | Elems2.push_back(Elt: ScalarPoison); |
1203 | Elems2.push_back(Elt: ScalarZero); |
1204 | Constant *VectorZeroPoison = ConstantVector::get(V: Elems2); |
1205 | |
1206 | EXPECT_TRUE(match(ScalarUndef, m_Undef())); |
1207 | EXPECT_TRUE(match(ScalarPoison, m_Undef())); |
1208 | EXPECT_TRUE(match(VectorUndef, m_Undef())); |
1209 | EXPECT_TRUE(match(VectorPoison, m_Undef())); |
1210 | EXPECT_FALSE(match(ScalarZero, m_Undef())); |
1211 | EXPECT_FALSE(match(VectorZero, m_Undef())); |
1212 | EXPECT_FALSE(match(VectorZeroUndef, m_Undef())); |
1213 | EXPECT_FALSE(match(VectorZeroPoison, m_Undef())); |
1214 | |
1215 | EXPECT_FALSE(match(ScalarUndef, m_Zero())); |
1216 | EXPECT_FALSE(match(ScalarPoison, m_Zero())); |
1217 | EXPECT_FALSE(match(VectorUndef, m_Zero())); |
1218 | EXPECT_FALSE(match(VectorPoison, m_Zero())); |
1219 | EXPECT_FALSE(match(VectorZeroUndef, m_Zero())); |
1220 | EXPECT_TRUE(match(ScalarZero, m_Zero())); |
1221 | EXPECT_TRUE(match(VectorZero, m_Zero())); |
1222 | EXPECT_TRUE(match(VectorZeroPoison, m_Zero())); |
1223 | |
1224 | const APInt *C; |
1225 | // Regardless of whether poison is allowed, |
1226 | // a fully undef/poison constant does not match. |
1227 | EXPECT_FALSE(match(ScalarUndef, m_APInt(C))); |
1228 | EXPECT_FALSE(match(ScalarUndef, m_APIntForbidPoison(C))); |
1229 | EXPECT_FALSE(match(ScalarUndef, m_APIntAllowPoison(C))); |
1230 | EXPECT_FALSE(match(VectorUndef, m_APInt(C))); |
1231 | EXPECT_FALSE(match(VectorUndef, m_APIntForbidPoison(C))); |
1232 | EXPECT_FALSE(match(VectorUndef, m_APIntAllowPoison(C))); |
1233 | EXPECT_FALSE(match(ScalarPoison, m_APInt(C))); |
1234 | EXPECT_FALSE(match(ScalarPoison, m_APIntForbidPoison(C))); |
1235 | EXPECT_FALSE(match(ScalarPoison, m_APIntAllowPoison(C))); |
1236 | EXPECT_FALSE(match(VectorPoison, m_APInt(C))); |
1237 | EXPECT_FALSE(match(VectorPoison, m_APIntForbidPoison(C))); |
1238 | EXPECT_FALSE(match(VectorPoison, m_APIntAllowPoison(C))); |
1239 | |
1240 | // We can always match simple constants and simple splats. |
1241 | C = nullptr; |
1242 | EXPECT_TRUE(match(ScalarZero, m_APInt(C))); |
1243 | EXPECT_TRUE(C->isZero()); |
1244 | C = nullptr; |
1245 | EXPECT_TRUE(match(ScalarZero, m_APIntForbidPoison(C))); |
1246 | EXPECT_TRUE(C->isZero()); |
1247 | C = nullptr; |
1248 | EXPECT_TRUE(match(ScalarZero, m_APIntAllowPoison(C))); |
1249 | EXPECT_TRUE(C->isZero()); |
1250 | C = nullptr; |
1251 | EXPECT_TRUE(match(VectorZero, m_APInt(C))); |
1252 | EXPECT_TRUE(C->isZero()); |
1253 | C = nullptr; |
1254 | EXPECT_TRUE(match(VectorZero, m_APIntForbidPoison(C))); |
1255 | EXPECT_TRUE(C->isZero()); |
1256 | C = nullptr; |
1257 | EXPECT_TRUE(match(VectorZero, m_APIntAllowPoison(C))); |
1258 | EXPECT_TRUE(C->isZero()); |
1259 | |
1260 | // Splats with undef are never allowed. |
1261 | // Whether splats with poison can be matched depends on the matcher. |
1262 | EXPECT_FALSE(match(VectorZeroUndef, m_APInt(C))); |
1263 | EXPECT_FALSE(match(VectorZeroUndef, m_APIntForbidPoison(C))); |
1264 | EXPECT_FALSE(match(VectorZeroUndef, m_APIntAllowPoison(C))); |
1265 | |
1266 | EXPECT_FALSE(match(VectorZeroPoison, m_APInt(C))); |
1267 | EXPECT_FALSE(match(VectorZeroPoison, m_APIntForbidPoison(C))); |
1268 | C = nullptr; |
1269 | EXPECT_TRUE(match(VectorZeroPoison, m_APIntAllowPoison(C))); |
1270 | EXPECT_TRUE(C->isZero()); |
1271 | } |
1272 | |
1273 | TEST_F(PatternMatchTest, VectorUndefFloat) { |
1274 | Type *ScalarTy = IRB.getFloatTy(); |
1275 | Type *VectorTy = FixedVectorType::get(ElementType: ScalarTy, NumElts: 4); |
1276 | Constant *ScalarUndef = UndefValue::get(T: ScalarTy); |
1277 | Constant *VectorUndef = UndefValue::get(T: VectorTy); |
1278 | Constant *ScalarPoison = PoisonValue::get(T: ScalarTy); |
1279 | Constant *VectorPoison = PoisonValue::get(T: VectorTy); |
1280 | Constant *ScalarZero = Constant::getNullValue(Ty: ScalarTy); |
1281 | Constant *VectorZero = Constant::getNullValue(Ty: VectorTy); |
1282 | Constant *ScalarPosInf = ConstantFP::getInfinity(Ty: ScalarTy, Negative: false); |
1283 | Constant *ScalarNegInf = ConstantFP::getInfinity(Ty: ScalarTy, Negative: true); |
1284 | Constant *ScalarNaN = ConstantFP::getNaN(Ty: ScalarTy, Negative: true); |
1285 | |
1286 | Constant *VectorZeroUndef = |
1287 | ConstantVector::get(V: {ScalarUndef, ScalarZero, ScalarUndef, ScalarZero}); |
1288 | |
1289 | Constant *VectorZeroPoison = |
1290 | ConstantVector::get(V: {ScalarPoison, ScalarZero, ScalarPoison, ScalarZero}); |
1291 | |
1292 | Constant *VectorInfUndef = ConstantVector::get( |
1293 | V: {ScalarPosInf, ScalarNegInf, ScalarUndef, ScalarPosInf}); |
1294 | |
1295 | Constant *VectorInfPoison = ConstantVector::get( |
1296 | V: {ScalarPosInf, ScalarNegInf, ScalarPoison, ScalarPosInf}); |
1297 | |
1298 | Constant *VectorNaNUndef = |
1299 | ConstantVector::get(V: {ScalarUndef, ScalarNaN, ScalarNaN, ScalarNaN}); |
1300 | |
1301 | Constant *VectorNaNPoison = |
1302 | ConstantVector::get(V: {ScalarPoison, ScalarNaN, ScalarNaN, ScalarNaN}); |
1303 | |
1304 | EXPECT_TRUE(match(ScalarUndef, m_Undef())); |
1305 | EXPECT_TRUE(match(VectorUndef, m_Undef())); |
1306 | EXPECT_TRUE(match(ScalarPoison, m_Undef())); |
1307 | EXPECT_TRUE(match(VectorPoison, m_Undef())); |
1308 | EXPECT_FALSE(match(ScalarZero, m_Undef())); |
1309 | EXPECT_FALSE(match(VectorZero, m_Undef())); |
1310 | EXPECT_FALSE(match(VectorZeroUndef, m_Undef())); |
1311 | EXPECT_FALSE(match(VectorInfUndef, m_Undef())); |
1312 | EXPECT_FALSE(match(VectorNaNUndef, m_Undef())); |
1313 | EXPECT_FALSE(match(VectorZeroPoison, m_Undef())); |
1314 | EXPECT_FALSE(match(VectorInfPoison, m_Undef())); |
1315 | EXPECT_FALSE(match(VectorNaNPoison, m_Undef())); |
1316 | |
1317 | EXPECT_FALSE(match(ScalarUndef, m_AnyZeroFP())); |
1318 | EXPECT_FALSE(match(VectorUndef, m_AnyZeroFP())); |
1319 | EXPECT_FALSE(match(ScalarPoison, m_AnyZeroFP())); |
1320 | EXPECT_FALSE(match(VectorPoison, m_AnyZeroFP())); |
1321 | EXPECT_TRUE(match(ScalarZero, m_AnyZeroFP())); |
1322 | EXPECT_TRUE(match(VectorZero, m_AnyZeroFP())); |
1323 | EXPECT_FALSE(match(VectorZeroUndef, m_AnyZeroFP())); |
1324 | EXPECT_FALSE(match(VectorInfUndef, m_AnyZeroFP())); |
1325 | EXPECT_FALSE(match(VectorNaNUndef, m_AnyZeroFP())); |
1326 | EXPECT_TRUE(match(VectorZeroPoison, m_AnyZeroFP())); |
1327 | EXPECT_FALSE(match(VectorInfPoison, m_AnyZeroFP())); |
1328 | EXPECT_FALSE(match(VectorNaNPoison, m_AnyZeroFP())); |
1329 | |
1330 | EXPECT_FALSE(match(ScalarUndef, m_NaN())); |
1331 | EXPECT_FALSE(match(VectorUndef, m_NaN())); |
1332 | EXPECT_FALSE(match(VectorZeroUndef, m_NaN())); |
1333 | EXPECT_FALSE(match(ScalarPoison, m_NaN())); |
1334 | EXPECT_FALSE(match(VectorPoison, m_NaN())); |
1335 | EXPECT_FALSE(match(VectorZeroPoison, m_NaN())); |
1336 | EXPECT_FALSE(match(ScalarPosInf, m_NaN())); |
1337 | EXPECT_FALSE(match(ScalarNegInf, m_NaN())); |
1338 | EXPECT_TRUE(match(ScalarNaN, m_NaN())); |
1339 | EXPECT_FALSE(match(VectorInfUndef, m_NaN())); |
1340 | EXPECT_FALSE(match(VectorNaNUndef, m_NaN())); |
1341 | EXPECT_FALSE(match(VectorInfPoison, m_NaN())); |
1342 | EXPECT_TRUE(match(VectorNaNPoison, m_NaN())); |
1343 | |
1344 | EXPECT_FALSE(match(ScalarUndef, m_NonNaN())); |
1345 | EXPECT_FALSE(match(VectorUndef, m_NonNaN())); |
1346 | EXPECT_FALSE(match(VectorZeroUndef, m_NonNaN())); |
1347 | EXPECT_FALSE(match(ScalarPoison, m_NonNaN())); |
1348 | EXPECT_FALSE(match(VectorPoison, m_NonNaN())); |
1349 | EXPECT_TRUE(match(VectorZeroPoison, m_NonNaN())); |
1350 | EXPECT_TRUE(match(ScalarPosInf, m_NonNaN())); |
1351 | EXPECT_TRUE(match(ScalarNegInf, m_NonNaN())); |
1352 | EXPECT_FALSE(match(ScalarNaN, m_NonNaN())); |
1353 | EXPECT_FALSE(match(VectorInfUndef, m_NonNaN())); |
1354 | EXPECT_FALSE(match(VectorNaNUndef, m_NonNaN())); |
1355 | EXPECT_TRUE(match(VectorInfPoison, m_NonNaN())); |
1356 | EXPECT_FALSE(match(VectorNaNPoison, m_NonNaN())); |
1357 | |
1358 | EXPECT_FALSE(match(ScalarUndef, m_Inf())); |
1359 | EXPECT_FALSE(match(VectorUndef, m_Inf())); |
1360 | EXPECT_FALSE(match(VectorZeroUndef, m_Inf())); |
1361 | EXPECT_FALSE(match(ScalarPoison, m_Inf())); |
1362 | EXPECT_FALSE(match(VectorPoison, m_Inf())); |
1363 | EXPECT_FALSE(match(VectorZeroPoison, m_Inf())); |
1364 | EXPECT_TRUE(match(ScalarPosInf, m_Inf())); |
1365 | EXPECT_TRUE(match(ScalarNegInf, m_Inf())); |
1366 | EXPECT_FALSE(match(ScalarNaN, m_Inf())); |
1367 | EXPECT_FALSE(match(VectorInfUndef, m_Inf())); |
1368 | EXPECT_FALSE(match(VectorNaNUndef, m_Inf())); |
1369 | EXPECT_TRUE(match(VectorInfPoison, m_Inf())); |
1370 | EXPECT_FALSE(match(VectorNaNPoison, m_Inf())); |
1371 | |
1372 | EXPECT_FALSE(match(ScalarUndef, m_NonInf())); |
1373 | EXPECT_FALSE(match(VectorUndef, m_NonInf())); |
1374 | EXPECT_FALSE(match(VectorZeroUndef, m_NonInf())); |
1375 | EXPECT_FALSE(match(ScalarPoison, m_NonInf())); |
1376 | EXPECT_FALSE(match(VectorPoison, m_NonInf())); |
1377 | EXPECT_TRUE(match(VectorZeroPoison, m_NonInf())); |
1378 | EXPECT_FALSE(match(ScalarPosInf, m_NonInf())); |
1379 | EXPECT_FALSE(match(ScalarNegInf, m_NonInf())); |
1380 | EXPECT_TRUE(match(ScalarNaN, m_NonInf())); |
1381 | EXPECT_FALSE(match(VectorInfUndef, m_NonInf())); |
1382 | EXPECT_FALSE(match(VectorNaNUndef, m_NonInf())); |
1383 | EXPECT_FALSE(match(VectorInfPoison, m_NonInf())); |
1384 | EXPECT_TRUE(match(VectorNaNPoison, m_NonInf())); |
1385 | |
1386 | EXPECT_FALSE(match(ScalarUndef, m_Finite())); |
1387 | EXPECT_FALSE(match(VectorUndef, m_Finite())); |
1388 | EXPECT_FALSE(match(VectorZeroUndef, m_Finite())); |
1389 | EXPECT_FALSE(match(ScalarPoison, m_Finite())); |
1390 | EXPECT_FALSE(match(VectorPoison, m_Finite())); |
1391 | EXPECT_TRUE(match(VectorZeroPoison, m_Finite())); |
1392 | EXPECT_FALSE(match(ScalarPosInf, m_Finite())); |
1393 | EXPECT_FALSE(match(ScalarNegInf, m_Finite())); |
1394 | EXPECT_FALSE(match(ScalarNaN, m_Finite())); |
1395 | EXPECT_FALSE(match(VectorInfUndef, m_Finite())); |
1396 | EXPECT_FALSE(match(VectorNaNUndef, m_Finite())); |
1397 | EXPECT_FALSE(match(VectorInfPoison, m_Finite())); |
1398 | EXPECT_FALSE(match(VectorNaNPoison, m_Finite())); |
1399 | |
1400 | const APFloat *C; |
1401 | // Regardless of whether poison is allowed, |
1402 | // a fully undef/poison constant does not match. |
1403 | EXPECT_FALSE(match(ScalarUndef, m_APFloat(C))); |
1404 | EXPECT_FALSE(match(ScalarUndef, m_APFloatForbidPoison(C))); |
1405 | EXPECT_FALSE(match(ScalarUndef, m_APFloatAllowPoison(C))); |
1406 | EXPECT_FALSE(match(VectorUndef, m_APFloat(C))); |
1407 | EXPECT_FALSE(match(VectorUndef, m_APFloatForbidPoison(C))); |
1408 | EXPECT_FALSE(match(VectorUndef, m_APFloatAllowPoison(C))); |
1409 | EXPECT_FALSE(match(ScalarPoison, m_APFloat(C))); |
1410 | EXPECT_FALSE(match(ScalarPoison, m_APFloatForbidPoison(C))); |
1411 | EXPECT_FALSE(match(ScalarPoison, m_APFloatAllowPoison(C))); |
1412 | EXPECT_FALSE(match(VectorPoison, m_APFloat(C))); |
1413 | EXPECT_FALSE(match(VectorPoison, m_APFloatForbidPoison(C))); |
1414 | EXPECT_FALSE(match(VectorPoison, m_APFloatAllowPoison(C))); |
1415 | |
1416 | // We can always match simple constants and simple splats. |
1417 | C = nullptr; |
1418 | EXPECT_TRUE(match(ScalarZero, m_APFloat(C))); |
1419 | EXPECT_TRUE(C->isZero()); |
1420 | C = nullptr; |
1421 | EXPECT_TRUE(match(ScalarZero, m_APFloatForbidPoison(C))); |
1422 | EXPECT_TRUE(C->isZero()); |
1423 | C = nullptr; |
1424 | EXPECT_TRUE(match(ScalarZero, m_APFloatAllowPoison(C))); |
1425 | EXPECT_TRUE(C->isZero()); |
1426 | C = nullptr; |
1427 | EXPECT_TRUE(match(VectorZero, m_APFloat(C))); |
1428 | EXPECT_TRUE(C->isZero()); |
1429 | C = nullptr; |
1430 | EXPECT_TRUE(match(VectorZero, m_APFloatForbidPoison(C))); |
1431 | EXPECT_TRUE(C->isZero()); |
1432 | C = nullptr; |
1433 | EXPECT_TRUE(match(VectorZero, m_APFloatAllowPoison(C))); |
1434 | EXPECT_TRUE(C->isZero()); |
1435 | |
1436 | // Splats with undef are never allowed. |
1437 | // Whether splats with poison can be matched depends on the matcher. |
1438 | EXPECT_FALSE(match(VectorZeroUndef, m_APFloat(C))); |
1439 | EXPECT_FALSE(match(VectorZeroUndef, m_APFloatForbidPoison(C))); |
1440 | EXPECT_FALSE(match(VectorZeroUndef, m_APFloatAllowPoison(C))); |
1441 | EXPECT_FALSE(match(VectorZeroUndef, m_Finite(C))); |
1442 | |
1443 | EXPECT_FALSE(match(VectorZeroPoison, m_APFloat(C))); |
1444 | EXPECT_FALSE(match(VectorZeroPoison, m_APFloatForbidPoison(C))); |
1445 | C = nullptr; |
1446 | EXPECT_TRUE(match(VectorZeroPoison, m_APFloatAllowPoison(C))); |
1447 | EXPECT_TRUE(C->isZero()); |
1448 | C = nullptr; |
1449 | EXPECT_TRUE(match(VectorZeroPoison, m_Finite(C))); |
1450 | EXPECT_TRUE(C->isZero()); |
1451 | EXPECT_FALSE(match(VectorZeroPoison, m_APFloat(C))); |
1452 | EXPECT_FALSE(match(VectorZeroPoison, m_APFloatForbidPoison(C))); |
1453 | C = nullptr; |
1454 | EXPECT_TRUE(match(VectorZeroPoison, m_APFloatAllowPoison(C))); |
1455 | EXPECT_TRUE(C->isZero()); |
1456 | C = nullptr; |
1457 | EXPECT_TRUE(match(VectorZeroPoison, m_Finite(C))); |
1458 | EXPECT_TRUE(C->isZero()); |
1459 | } |
1460 | |
1461 | TEST_F(PatternMatchTest, FloatingPointFNeg) { |
1462 | Type *FltTy = IRB.getFloatTy(); |
1463 | Value *One = ConstantFP::get(Ty: FltTy, V: 1.0); |
1464 | Value *Z = ConstantFP::get(Ty: FltTy, V: 0.0); |
1465 | Value *NZ = ConstantFP::get(Ty: FltTy, V: -0.0); |
1466 | Value *V = IRB.CreateFNeg(V: One); |
1467 | Value *V1 = IRB.CreateFSub(L: NZ, R: One); |
1468 | Value *V2 = IRB.CreateFSub(L: Z, R: One); |
1469 | Value *V3 = IRB.CreateFAdd(L: NZ, R: One); |
1470 | Value *Match; |
1471 | |
1472 | // Test FNeg(1.0) |
1473 | EXPECT_TRUE(match(V, m_FNeg(m_Value(Match)))); |
1474 | EXPECT_EQ(One, Match); |
1475 | |
1476 | // Test FSub(-0.0, 1.0) |
1477 | EXPECT_TRUE(match(V1, m_FNeg(m_Value(Match)))); |
1478 | EXPECT_EQ(One, Match); |
1479 | |
1480 | // Test FSub(0.0, 1.0) |
1481 | EXPECT_FALSE(match(V2, m_FNeg(m_Value(Match)))); |
1482 | cast<Instruction>(Val: V2)->setHasNoSignedZeros(true); |
1483 | EXPECT_TRUE(match(V2, m_FNeg(m_Value(Match)))); |
1484 | EXPECT_EQ(One, Match); |
1485 | |
1486 | // Test FAdd(-0.0, 1.0) |
1487 | EXPECT_FALSE(match(V3, m_FNeg(m_Value(Match)))); |
1488 | } |
1489 | |
1490 | TEST_F(PatternMatchTest, CondBranchTest) { |
1491 | BasicBlock *TrueBB = BasicBlock::Create(Context&: Ctx, Name: "TrueBB" , Parent: F); |
1492 | BasicBlock *FalseBB = BasicBlock::Create(Context&: Ctx, Name: "FalseBB" , Parent: F); |
1493 | Value *Br1 = IRB.CreateCondBr(Cond: IRB.getTrue(), True: TrueBB, False: FalseBB); |
1494 | |
1495 | EXPECT_TRUE(match(Br1, m_Br(m_Value(), m_BasicBlock(), m_BasicBlock()))); |
1496 | |
1497 | BasicBlock *A, *B; |
1498 | EXPECT_TRUE(match(Br1, m_Br(m_Value(), m_BasicBlock(A), m_BasicBlock(B)))); |
1499 | EXPECT_EQ(TrueBB, A); |
1500 | EXPECT_EQ(FalseBB, B); |
1501 | |
1502 | EXPECT_FALSE( |
1503 | match(Br1, m_Br(m_Value(), m_SpecificBB(FalseBB), m_BasicBlock()))); |
1504 | EXPECT_FALSE( |
1505 | match(Br1, m_Br(m_Value(), m_BasicBlock(), m_SpecificBB(TrueBB)))); |
1506 | EXPECT_FALSE( |
1507 | match(Br1, m_Br(m_Value(), m_SpecificBB(FalseBB), m_BasicBlock(TrueBB)))); |
1508 | EXPECT_TRUE( |
1509 | match(Br1, m_Br(m_Value(), m_SpecificBB(TrueBB), m_BasicBlock(FalseBB)))); |
1510 | |
1511 | // Check we can use m_Deferred with branches. |
1512 | EXPECT_FALSE(match(Br1, m_Br(m_Value(), m_BasicBlock(A), m_Deferred(A)))); |
1513 | Value *Br2 = IRB.CreateCondBr(Cond: IRB.getTrue(), True: TrueBB, False: TrueBB); |
1514 | A = nullptr; |
1515 | EXPECT_TRUE(match(Br2, m_Br(m_Value(), m_BasicBlock(A), m_Deferred(A)))); |
1516 | } |
1517 | |
1518 | TEST_F(PatternMatchTest, WithOverflowInst) { |
1519 | Value *Add = IRB.CreateBinaryIntrinsic(Intrinsic::ID: uadd_with_overflow, |
1520 | LHS: IRB.getInt32(C: 0), RHS: IRB.getInt32(C: 0)); |
1521 | Value *Add0 = IRB.CreateExtractValue(Agg: Add, Idxs: 0); |
1522 | Value *Add1 = IRB.CreateExtractValue(Agg: Add, Idxs: 1); |
1523 | |
1524 | EXPECT_TRUE(match(Add0, m_ExtractValue<0>(m_Value()))); |
1525 | EXPECT_FALSE(match(Add0, m_ExtractValue<1>(m_Value()))); |
1526 | EXPECT_FALSE(match(Add1, m_ExtractValue<0>(m_Value()))); |
1527 | EXPECT_TRUE(match(Add1, m_ExtractValue<1>(m_Value()))); |
1528 | EXPECT_FALSE(match(Add, m_ExtractValue<1>(m_Value()))); |
1529 | EXPECT_FALSE(match(Add, m_ExtractValue<1>(m_Value()))); |
1530 | |
1531 | WithOverflowInst *WOI; |
1532 | EXPECT_FALSE(match(Add0, m_WithOverflowInst(WOI))); |
1533 | EXPECT_FALSE(match(Add1, m_WithOverflowInst(WOI))); |
1534 | EXPECT_TRUE(match(Add, m_WithOverflowInst(WOI))); |
1535 | |
1536 | EXPECT_TRUE(match(Add0, m_ExtractValue<0>(m_WithOverflowInst(WOI)))); |
1537 | EXPECT_EQ(Add, WOI); |
1538 | EXPECT_TRUE(match(Add1, m_ExtractValue<1>(m_WithOverflowInst(WOI)))); |
1539 | EXPECT_EQ(Add, WOI); |
1540 | } |
1541 | |
1542 | TEST_F(PatternMatchTest, MinMaxIntrinsics) { |
1543 | Type *Ty = IRB.getInt32Ty(); |
1544 | Value *L = ConstantInt::get(Ty, V: 1); |
1545 | Value *R = ConstantInt::get(Ty, V: 2); |
1546 | Value *MatchL, *MatchR; |
1547 | |
1548 | // Check for intrinsic ID match and capture of operands. |
1549 | EXPECT_TRUE(m_SMax(m_Value(MatchL), m_Value(MatchR)) |
1550 | .match(IRB.CreateBinaryIntrinsic(Intrinsic::smax, L, R))); |
1551 | EXPECT_EQ(L, MatchL); |
1552 | EXPECT_EQ(R, MatchR); |
1553 | |
1554 | EXPECT_TRUE(m_SMin(m_Value(MatchL), m_Value(MatchR)) |
1555 | .match(IRB.CreateBinaryIntrinsic(Intrinsic::smin, L, R))); |
1556 | EXPECT_EQ(L, MatchL); |
1557 | EXPECT_EQ(R, MatchR); |
1558 | |
1559 | EXPECT_TRUE(m_UMax(m_Value(MatchL), m_Value(MatchR)) |
1560 | .match(IRB.CreateBinaryIntrinsic(Intrinsic::umax, L, R))); |
1561 | EXPECT_EQ(L, MatchL); |
1562 | EXPECT_EQ(R, MatchR); |
1563 | |
1564 | EXPECT_TRUE(m_UMin(m_Value(MatchL), m_Value(MatchR)) |
1565 | .match(IRB.CreateBinaryIntrinsic(Intrinsic::umin, L, R))); |
1566 | EXPECT_EQ(L, MatchL); |
1567 | EXPECT_EQ(R, MatchR); |
1568 | |
1569 | // Check for intrinsic ID mismatch. |
1570 | EXPECT_FALSE(m_SMax(m_Value(MatchL), m_Value(MatchR)) |
1571 | .match(IRB.CreateBinaryIntrinsic(Intrinsic::smin, L, R))); |
1572 | EXPECT_FALSE(m_SMin(m_Value(MatchL), m_Value(MatchR)) |
1573 | .match(IRB.CreateBinaryIntrinsic(Intrinsic::umax, L, R))); |
1574 | EXPECT_FALSE(m_UMax(m_Value(MatchL), m_Value(MatchR)) |
1575 | .match(IRB.CreateBinaryIntrinsic(Intrinsic::umin, L, R))); |
1576 | EXPECT_FALSE(m_UMin(m_Value(MatchL), m_Value(MatchR)) |
1577 | .match(IRB.CreateBinaryIntrinsic(Intrinsic::smax, L, R))); |
1578 | } |
1579 | |
1580 | TEST_F(PatternMatchTest, IntrinsicMatcher) { |
1581 | Value *Name = IRB.CreateAlloca(Ty: IRB.getInt8Ty()); |
1582 | Value *Hash = IRB.getInt64(C: 0); |
1583 | Value *Num = IRB.getInt32(C: 1); |
1584 | Value *Index = IRB.getInt32(C: 2); |
1585 | Value *Step = IRB.getInt64(C: 3); |
1586 | |
1587 | Value *Ops[] = {Name, Hash, Num, Index, Step}; |
1588 | Module *M = BB->getParent()->getParent(); |
1589 | Function *TheFn = |
1590 | Intrinsic::getDeclaration(M, Intrinsic::id: instrprof_increment_step); |
1591 | |
1592 | Value *Intrinsic5 = CallInst::Create(Func: TheFn, Args: Ops, NameStr: "" , InsertAtEnd: BB); |
1593 | |
1594 | // Match without capturing. |
1595 | EXPECT_TRUE(match( |
1596 | Intrinsic5, m_Intrinsic<Intrinsic::instrprof_increment_step>( |
1597 | m_Value(), m_Value(), m_Value(), m_Value(), m_Value()))); |
1598 | EXPECT_FALSE(match( |
1599 | Intrinsic5, m_Intrinsic<Intrinsic::memmove>( |
1600 | m_Value(), m_Value(), m_Value(), m_Value(), m_Value()))); |
1601 | |
1602 | // Match with capturing. |
1603 | Value *Arg1 = nullptr; |
1604 | Value *Arg2 = nullptr; |
1605 | Value *Arg3 = nullptr; |
1606 | Value *Arg4 = nullptr; |
1607 | Value *Arg5 = nullptr; |
1608 | EXPECT_TRUE( |
1609 | match(Intrinsic5, m_Intrinsic<Intrinsic::instrprof_increment_step>( |
1610 | m_Value(Arg1), m_Value(Arg2), m_Value(Arg3), |
1611 | m_Value(Arg4), m_Value(Arg5)))); |
1612 | EXPECT_EQ(Arg1, Name); |
1613 | EXPECT_EQ(Arg2, Hash); |
1614 | EXPECT_EQ(Arg3, Num); |
1615 | EXPECT_EQ(Arg4, Index); |
1616 | EXPECT_EQ(Arg5, Step); |
1617 | |
1618 | // Match specific second argument. |
1619 | EXPECT_TRUE( |
1620 | match(Intrinsic5, |
1621 | m_Intrinsic<Intrinsic::instrprof_increment_step>( |
1622 | m_Value(), m_SpecificInt(0), m_Value(), m_Value(), m_Value()))); |
1623 | EXPECT_FALSE( |
1624 | match(Intrinsic5, m_Intrinsic<Intrinsic::instrprof_increment_step>( |
1625 | m_Value(), m_SpecificInt(10), m_Value(), m_Value(), |
1626 | m_Value()))); |
1627 | |
1628 | // Match specific third argument. |
1629 | EXPECT_TRUE( |
1630 | match(Intrinsic5, |
1631 | m_Intrinsic<Intrinsic::instrprof_increment_step>( |
1632 | m_Value(), m_Value(), m_SpecificInt(1), m_Value(), m_Value()))); |
1633 | EXPECT_FALSE( |
1634 | match(Intrinsic5, m_Intrinsic<Intrinsic::instrprof_increment_step>( |
1635 | m_Value(), m_Value(), m_SpecificInt(10), m_Value(), |
1636 | m_Value()))); |
1637 | |
1638 | // Match specific fourth argument. |
1639 | EXPECT_TRUE( |
1640 | match(Intrinsic5, |
1641 | m_Intrinsic<Intrinsic::instrprof_increment_step>( |
1642 | m_Value(), m_Value(), m_Value(), m_SpecificInt(2), m_Value()))); |
1643 | EXPECT_FALSE( |
1644 | match(Intrinsic5, m_Intrinsic<Intrinsic::instrprof_increment_step>( |
1645 | m_Value(), m_Value(), m_Value(), m_SpecificInt(10), |
1646 | m_Value()))); |
1647 | |
1648 | // Match specific fifth argument. |
1649 | EXPECT_TRUE( |
1650 | match(Intrinsic5, |
1651 | m_Intrinsic<Intrinsic::instrprof_increment_step>( |
1652 | m_Value(), m_Value(), m_Value(), m_Value(), m_SpecificInt(3)))); |
1653 | EXPECT_FALSE( |
1654 | match(Intrinsic5, m_Intrinsic<Intrinsic::instrprof_increment_step>( |
1655 | m_Value(), m_Value(), m_Value(), m_Value(), |
1656 | m_SpecificInt(10)))); |
1657 | } |
1658 | |
1659 | namespace { |
1660 | |
1661 | struct is_unsigned_zero_pred { |
1662 | bool isValue(const APInt &C) { return C.isZero(); } |
1663 | }; |
1664 | |
1665 | struct is_float_zero_pred { |
1666 | bool isValue(const APFloat &C) { return C.isZero(); } |
1667 | }; |
1668 | |
1669 | template <typename T> struct always_true_pred { |
1670 | bool isValue(const T &) { return true; } |
1671 | }; |
1672 | |
1673 | template <typename T> struct always_false_pred { |
1674 | bool isValue(const T &) { return false; } |
1675 | }; |
1676 | |
1677 | struct is_unsigned_max_pred { |
1678 | bool isValue(const APInt &C) { return C.isMaxValue(); } |
1679 | }; |
1680 | |
1681 | struct is_float_nan_pred { |
1682 | bool isValue(const APFloat &C) { return C.isNaN(); } |
1683 | }; |
1684 | |
1685 | } // namespace |
1686 | |
1687 | TEST_F(PatternMatchTest, ConstantPredicateType) { |
1688 | |
1689 | // Scalar integer |
1690 | APInt U32Max = APInt::getAllOnes(numBits: 32); |
1691 | APInt U32Zero = APInt::getZero(numBits: 32); |
1692 | APInt U32DeadBeef(32, 0xDEADBEEF); |
1693 | |
1694 | Type *U32Ty = Type::getInt32Ty(C&: Ctx); |
1695 | |
1696 | Constant *CU32Max = Constant::getIntegerValue(Ty: U32Ty, V: U32Max); |
1697 | Constant *CU32Zero = Constant::getIntegerValue(Ty: U32Ty, V: U32Zero); |
1698 | Constant *CU32DeadBeef = Constant::getIntegerValue(Ty: U32Ty, V: U32DeadBeef); |
1699 | |
1700 | EXPECT_TRUE(match(CU32Max, cst_pred_ty<is_unsigned_max_pred>())); |
1701 | EXPECT_FALSE(match(CU32Max, cst_pred_ty<is_unsigned_zero_pred>())); |
1702 | EXPECT_TRUE(match(CU32Max, cst_pred_ty<always_true_pred<APInt>>())); |
1703 | EXPECT_FALSE(match(CU32Max, cst_pred_ty<always_false_pred<APInt>>())); |
1704 | |
1705 | EXPECT_FALSE(match(CU32Zero, cst_pred_ty<is_unsigned_max_pred>())); |
1706 | EXPECT_TRUE(match(CU32Zero, cst_pred_ty<is_unsigned_zero_pred>())); |
1707 | EXPECT_TRUE(match(CU32Zero, cst_pred_ty<always_true_pred<APInt>>())); |
1708 | EXPECT_FALSE(match(CU32Zero, cst_pred_ty<always_false_pred<APInt>>())); |
1709 | |
1710 | EXPECT_FALSE(match(CU32DeadBeef, cst_pred_ty<is_unsigned_max_pred>())); |
1711 | EXPECT_FALSE(match(CU32DeadBeef, cst_pred_ty<is_unsigned_zero_pred>())); |
1712 | EXPECT_TRUE(match(CU32DeadBeef, cst_pred_ty<always_true_pred<APInt>>())); |
1713 | EXPECT_FALSE(match(CU32DeadBeef, cst_pred_ty<always_false_pred<APInt>>())); |
1714 | |
1715 | // Scalar float |
1716 | APFloat F32NaN = APFloat::getNaN(Sem: APFloat::IEEEsingle()); |
1717 | APFloat F32Zero = APFloat::getZero(Sem: APFloat::IEEEsingle()); |
1718 | APFloat F32Pi(3.14f); |
1719 | |
1720 | Type *F32Ty = Type::getFloatTy(C&: Ctx); |
1721 | |
1722 | Constant *CF32NaN = ConstantFP::get(Ty: F32Ty, V: F32NaN); |
1723 | Constant *CF32Zero = ConstantFP::get(Ty: F32Ty, V: F32Zero); |
1724 | Constant *CF32Pi = ConstantFP::get(Ty: F32Ty, V: F32Pi); |
1725 | |
1726 | EXPECT_TRUE(match(CF32NaN, cstfp_pred_ty<is_float_nan_pred>())); |
1727 | EXPECT_FALSE(match(CF32NaN, cstfp_pred_ty<is_float_zero_pred>())); |
1728 | EXPECT_TRUE(match(CF32NaN, cstfp_pred_ty<always_true_pred<APFloat>>())); |
1729 | EXPECT_FALSE(match(CF32NaN, cstfp_pred_ty<always_false_pred<APFloat>>())); |
1730 | |
1731 | EXPECT_FALSE(match(CF32Zero, cstfp_pred_ty<is_float_nan_pred>())); |
1732 | EXPECT_TRUE(match(CF32Zero, cstfp_pred_ty<is_float_zero_pred>())); |
1733 | EXPECT_TRUE(match(CF32Zero, cstfp_pred_ty<always_true_pred<APFloat>>())); |
1734 | EXPECT_FALSE(match(CF32Zero, cstfp_pred_ty<always_false_pred<APFloat>>())); |
1735 | |
1736 | EXPECT_FALSE(match(CF32Pi, cstfp_pred_ty<is_float_nan_pred>())); |
1737 | EXPECT_FALSE(match(CF32Pi, cstfp_pred_ty<is_float_zero_pred>())); |
1738 | EXPECT_TRUE(match(CF32Pi, cstfp_pred_ty<always_true_pred<APFloat>>())); |
1739 | EXPECT_FALSE(match(CF32Pi, cstfp_pred_ty<always_false_pred<APFloat>>())); |
1740 | |
1741 | auto FixedEC = ElementCount::getFixed(MinVal: 4); |
1742 | auto ScalableEC = ElementCount::getScalable(MinVal: 4); |
1743 | |
1744 | // Vector splat |
1745 | |
1746 | for (auto EC : {FixedEC, ScalableEC}) { |
1747 | // integer |
1748 | |
1749 | Constant *CSplatU32Max = ConstantVector::getSplat(EC, Elt: CU32Max); |
1750 | Constant *CSplatU32Zero = ConstantVector::getSplat(EC, Elt: CU32Zero); |
1751 | Constant *CSplatU32DeadBeef = ConstantVector::getSplat(EC, Elt: CU32DeadBeef); |
1752 | |
1753 | EXPECT_TRUE(match(CSplatU32Max, cst_pred_ty<is_unsigned_max_pred>())); |
1754 | EXPECT_FALSE(match(CSplatU32Max, cst_pred_ty<is_unsigned_zero_pred>())); |
1755 | EXPECT_TRUE(match(CSplatU32Max, cst_pred_ty<always_true_pred<APInt>>())); |
1756 | EXPECT_FALSE(match(CSplatU32Max, cst_pred_ty<always_false_pred<APInt>>())); |
1757 | |
1758 | EXPECT_FALSE(match(CSplatU32Zero, cst_pred_ty<is_unsigned_max_pred>())); |
1759 | EXPECT_TRUE(match(CSplatU32Zero, cst_pred_ty<is_unsigned_zero_pred>())); |
1760 | EXPECT_TRUE(match(CSplatU32Zero, cst_pred_ty<always_true_pred<APInt>>())); |
1761 | EXPECT_FALSE(match(CSplatU32Zero, cst_pred_ty<always_false_pred<APInt>>())); |
1762 | |
1763 | EXPECT_FALSE(match(CSplatU32DeadBeef, cst_pred_ty<is_unsigned_max_pred>())); |
1764 | EXPECT_FALSE( |
1765 | match(CSplatU32DeadBeef, cst_pred_ty<is_unsigned_zero_pred>())); |
1766 | EXPECT_TRUE( |
1767 | match(CSplatU32DeadBeef, cst_pred_ty<always_true_pred<APInt>>())); |
1768 | EXPECT_FALSE( |
1769 | match(CSplatU32DeadBeef, cst_pred_ty<always_false_pred<APInt>>())); |
1770 | |
1771 | // float |
1772 | |
1773 | Constant *CSplatF32NaN = ConstantVector::getSplat(EC, Elt: CF32NaN); |
1774 | Constant *CSplatF32Zero = ConstantVector::getSplat(EC, Elt: CF32Zero); |
1775 | Constant *CSplatF32Pi = ConstantVector::getSplat(EC, Elt: CF32Pi); |
1776 | |
1777 | EXPECT_TRUE(match(CSplatF32NaN, cstfp_pred_ty<is_float_nan_pred>())); |
1778 | EXPECT_FALSE(match(CSplatF32NaN, cstfp_pred_ty<is_float_zero_pred>())); |
1779 | EXPECT_TRUE( |
1780 | match(CSplatF32NaN, cstfp_pred_ty<always_true_pred<APFloat>>())); |
1781 | EXPECT_FALSE( |
1782 | match(CSplatF32NaN, cstfp_pred_ty<always_false_pred<APFloat>>())); |
1783 | |
1784 | EXPECT_FALSE(match(CSplatF32Zero, cstfp_pred_ty<is_float_nan_pred>())); |
1785 | EXPECT_TRUE(match(CSplatF32Zero, cstfp_pred_ty<is_float_zero_pred>())); |
1786 | EXPECT_TRUE( |
1787 | match(CSplatF32Zero, cstfp_pred_ty<always_true_pred<APFloat>>())); |
1788 | EXPECT_FALSE( |
1789 | match(CSplatF32Zero, cstfp_pred_ty<always_false_pred<APFloat>>())); |
1790 | |
1791 | EXPECT_FALSE(match(CSplatF32Pi, cstfp_pred_ty<is_float_nan_pred>())); |
1792 | EXPECT_FALSE(match(CSplatF32Pi, cstfp_pred_ty<is_float_zero_pred>())); |
1793 | EXPECT_TRUE(match(CSplatF32Pi, cstfp_pred_ty<always_true_pred<APFloat>>())); |
1794 | EXPECT_FALSE( |
1795 | match(CSplatF32Pi, cstfp_pred_ty<always_false_pred<APFloat>>())); |
1796 | } |
1797 | |
1798 | // Int arbitrary vector |
1799 | |
1800 | Constant *CMixedU32 = ConstantVector::get(V: {CU32Max, CU32Zero, CU32DeadBeef}); |
1801 | Constant *CU32Undef = UndefValue::get(T: U32Ty); |
1802 | Constant *CU32Poison = PoisonValue::get(T: U32Ty); |
1803 | Constant *CU32MaxWithUndef = |
1804 | ConstantVector::get(V: {CU32Undef, CU32Max, CU32Undef}); |
1805 | Constant *CU32MaxWithPoison = |
1806 | ConstantVector::get(V: {CU32Poison, CU32Max, CU32Poison}); |
1807 | |
1808 | EXPECT_FALSE(match(CMixedU32, cst_pred_ty<is_unsigned_max_pred>())); |
1809 | EXPECT_FALSE(match(CMixedU32, cst_pred_ty<is_unsigned_zero_pred>())); |
1810 | EXPECT_TRUE(match(CMixedU32, cst_pred_ty<always_true_pred<APInt>>())); |
1811 | EXPECT_FALSE(match(CMixedU32, cst_pred_ty<always_false_pred<APInt>>())); |
1812 | |
1813 | EXPECT_FALSE(match(CU32MaxWithUndef, cst_pred_ty<is_unsigned_max_pred>())); |
1814 | EXPECT_FALSE(match(CU32MaxWithUndef, cst_pred_ty<is_unsigned_zero_pred>())); |
1815 | EXPECT_FALSE(match(CU32MaxWithUndef, cst_pred_ty<always_true_pred<APInt>>())); |
1816 | EXPECT_FALSE( |
1817 | match(CU32MaxWithUndef, cst_pred_ty<always_false_pred<APInt>>())); |
1818 | |
1819 | EXPECT_TRUE(match(CU32MaxWithPoison, cst_pred_ty<is_unsigned_max_pred>())); |
1820 | EXPECT_FALSE(match(CU32MaxWithPoison, cst_pred_ty<is_unsigned_zero_pred>())); |
1821 | EXPECT_TRUE(match(CU32MaxWithPoison, cst_pred_ty<always_true_pred<APInt>>())); |
1822 | EXPECT_FALSE( |
1823 | match(CU32MaxWithPoison, cst_pred_ty<always_false_pred<APInt>>())); |
1824 | |
1825 | // Float arbitrary vector |
1826 | |
1827 | Constant *CMixedF32 = ConstantVector::get(V: {CF32NaN, CF32Zero, CF32Pi}); |
1828 | Constant *CF32Undef = UndefValue::get(T: F32Ty); |
1829 | Constant *CF32Poison = PoisonValue::get(T: F32Ty); |
1830 | Constant *CF32NaNWithUndef = |
1831 | ConstantVector::get(V: {CF32Undef, CF32NaN, CF32Undef}); |
1832 | Constant *CF32NaNWithPoison = |
1833 | ConstantVector::get(V: {CF32Poison, CF32NaN, CF32Poison}); |
1834 | |
1835 | EXPECT_FALSE(match(CMixedF32, cstfp_pred_ty<is_float_nan_pred>())); |
1836 | EXPECT_FALSE(match(CMixedF32, cstfp_pred_ty<is_float_zero_pred>())); |
1837 | EXPECT_TRUE(match(CMixedF32, cstfp_pred_ty<always_true_pred<APFloat>>())); |
1838 | EXPECT_FALSE(match(CMixedF32, cstfp_pred_ty<always_false_pred<APFloat>>())); |
1839 | |
1840 | EXPECT_FALSE(match(CF32NaNWithUndef, cstfp_pred_ty<is_float_nan_pred>())); |
1841 | EXPECT_FALSE(match(CF32NaNWithUndef, cstfp_pred_ty<is_float_zero_pred>())); |
1842 | EXPECT_FALSE( |
1843 | match(CF32NaNWithUndef, cstfp_pred_ty<always_true_pred<APFloat>>())); |
1844 | EXPECT_FALSE( |
1845 | match(CF32NaNWithUndef, cstfp_pred_ty<always_false_pred<APFloat>>())); |
1846 | |
1847 | EXPECT_TRUE(match(CF32NaNWithPoison, cstfp_pred_ty<is_float_nan_pred>())); |
1848 | EXPECT_FALSE(match(CF32NaNWithPoison, cstfp_pred_ty<is_float_zero_pred>())); |
1849 | EXPECT_TRUE( |
1850 | match(CF32NaNWithPoison, cstfp_pred_ty<always_true_pred<APFloat>>())); |
1851 | EXPECT_FALSE( |
1852 | match(CF32NaNWithPoison, cstfp_pred_ty<always_false_pred<APFloat>>())); |
1853 | } |
1854 | |
1855 | TEST_F(PatternMatchTest, InsertValue) { |
1856 | Type *StructTy = StructType::create(Context&: IRB.getContext(), |
1857 | Elements: {IRB.getInt32Ty(), IRB.getInt64Ty()}); |
1858 | Value *Ins0 = |
1859 | IRB.CreateInsertValue(Agg: UndefValue::get(T: StructTy), Val: IRB.getInt32(C: 20), Idxs: 0); |
1860 | Value *Ins1 = IRB.CreateInsertValue(Agg: Ins0, Val: IRB.getInt64(C: 90), Idxs: 1); |
1861 | |
1862 | EXPECT_TRUE(match(Ins0, m_InsertValue<0>(m_Value(), m_Value()))); |
1863 | EXPECT_FALSE(match(Ins0, m_InsertValue<1>(m_Value(), m_Value()))); |
1864 | EXPECT_FALSE(match(Ins1, m_InsertValue<0>(m_Value(), m_Value()))); |
1865 | EXPECT_TRUE(match(Ins1, m_InsertValue<1>(m_Value(), m_Value()))); |
1866 | |
1867 | EXPECT_TRUE(match(Ins0, m_InsertValue<0>(m_Undef(), m_SpecificInt(20)))); |
1868 | EXPECT_FALSE(match(Ins0, m_InsertValue<0>(m_Undef(), m_SpecificInt(0)))); |
1869 | |
1870 | EXPECT_TRUE( |
1871 | match(Ins1, m_InsertValue<1>(m_InsertValue<0>(m_Value(), m_Value()), |
1872 | m_SpecificInt(90)))); |
1873 | EXPECT_FALSE(match(IRB.getInt64(99), m_InsertValue<0>(m_Value(), m_Value()))); |
1874 | } |
1875 | |
1876 | TEST_F(PatternMatchTest, LogicalSelects) { |
1877 | Value *Alloca = IRB.CreateAlloca(Ty: IRB.getInt1Ty()); |
1878 | Value *X = IRB.CreateLoad(Ty: IRB.getInt1Ty(), Ptr: Alloca); |
1879 | Value *Y = IRB.CreateLoad(Ty: IRB.getInt1Ty(), Ptr: Alloca); |
1880 | Constant *T = IRB.getInt1(V: true); |
1881 | Constant *F = IRB.getInt1(V: false); |
1882 | Value *And = IRB.CreateSelect(C: X, True: Y, False: F); |
1883 | Value *Or = IRB.CreateSelect(C: X, True: T, False: Y); |
1884 | |
1885 | // Logical and: |
1886 | // Check basic no-capture logic - opcode and constant must match. |
1887 | EXPECT_TRUE(match(And, m_LogicalAnd(m_Value(), m_Value()))); |
1888 | EXPECT_TRUE(match(And, m_c_LogicalAnd(m_Value(), m_Value()))); |
1889 | EXPECT_FALSE(match(And, m_LogicalOr(m_Value(), m_Value()))); |
1890 | EXPECT_FALSE(match(And, m_c_LogicalOr(m_Value(), m_Value()))); |
1891 | |
1892 | // Check with captures. |
1893 | EXPECT_TRUE(match(And, m_LogicalAnd(m_Specific(X), m_Value()))); |
1894 | EXPECT_TRUE(match(And, m_LogicalAnd(m_Value(), m_Specific(Y)))); |
1895 | EXPECT_TRUE(match(And, m_LogicalAnd(m_Specific(X), m_Specific(Y)))); |
1896 | |
1897 | EXPECT_FALSE(match(And, m_LogicalAnd(m_Specific(Y), m_Value()))); |
1898 | EXPECT_FALSE(match(And, m_LogicalAnd(m_Value(), m_Specific(X)))); |
1899 | EXPECT_FALSE(match(And, m_LogicalAnd(m_Specific(Y), m_Specific(X)))); |
1900 | |
1901 | EXPECT_FALSE(match(And, m_LogicalAnd(m_Specific(X), m_Specific(X)))); |
1902 | EXPECT_FALSE(match(And, m_LogicalAnd(m_Specific(Y), m_Specific(Y)))); |
1903 | |
1904 | // Check captures for commutative match. |
1905 | EXPECT_TRUE(match(And, m_c_LogicalAnd(m_Specific(X), m_Value()))); |
1906 | EXPECT_TRUE(match(And, m_c_LogicalAnd(m_Value(), m_Specific(Y)))); |
1907 | EXPECT_TRUE(match(And, m_c_LogicalAnd(m_Specific(X), m_Specific(Y)))); |
1908 | |
1909 | EXPECT_TRUE(match(And, m_c_LogicalAnd(m_Specific(Y), m_Value()))); |
1910 | EXPECT_TRUE(match(And, m_c_LogicalAnd(m_Value(), m_Specific(X)))); |
1911 | EXPECT_TRUE(match(And, m_c_LogicalAnd(m_Specific(Y), m_Specific(X)))); |
1912 | |
1913 | EXPECT_FALSE(match(And, m_c_LogicalAnd(m_Specific(X), m_Specific(X)))); |
1914 | EXPECT_FALSE(match(And, m_c_LogicalAnd(m_Specific(Y), m_Specific(Y)))); |
1915 | |
1916 | // Logical or: |
1917 | // Check basic no-capture logic - opcode and constant must match. |
1918 | EXPECT_TRUE(match(Or, m_LogicalOr(m_Value(), m_Value()))); |
1919 | EXPECT_TRUE(match(Or, m_c_LogicalOr(m_Value(), m_Value()))); |
1920 | EXPECT_FALSE(match(Or, m_LogicalAnd(m_Value(), m_Value()))); |
1921 | EXPECT_FALSE(match(Or, m_c_LogicalAnd(m_Value(), m_Value()))); |
1922 | |
1923 | // Check with captures. |
1924 | EXPECT_TRUE(match(Or, m_LogicalOr(m_Specific(X), m_Value()))); |
1925 | EXPECT_TRUE(match(Or, m_LogicalOr(m_Value(), m_Specific(Y)))); |
1926 | EXPECT_TRUE(match(Or, m_LogicalOr(m_Specific(X), m_Specific(Y)))); |
1927 | |
1928 | EXPECT_FALSE(match(Or, m_LogicalOr(m_Specific(Y), m_Value()))); |
1929 | EXPECT_FALSE(match(Or, m_LogicalOr(m_Value(), m_Specific(X)))); |
1930 | EXPECT_FALSE(match(Or, m_LogicalOr(m_Specific(Y), m_Specific(X)))); |
1931 | |
1932 | EXPECT_FALSE(match(Or, m_LogicalOr(m_Specific(X), m_Specific(X)))); |
1933 | EXPECT_FALSE(match(Or, m_LogicalOr(m_Specific(Y), m_Specific(Y)))); |
1934 | |
1935 | // Check captures for commutative match. |
1936 | EXPECT_TRUE(match(Or, m_c_LogicalOr(m_Specific(X), m_Value()))); |
1937 | EXPECT_TRUE(match(Or, m_c_LogicalOr(m_Value(), m_Specific(Y)))); |
1938 | EXPECT_TRUE(match(Or, m_c_LogicalOr(m_Specific(X), m_Specific(Y)))); |
1939 | |
1940 | EXPECT_TRUE(match(Or, m_c_LogicalOr(m_Specific(Y), m_Value()))); |
1941 | EXPECT_TRUE(match(Or, m_c_LogicalOr(m_Value(), m_Specific(X)))); |
1942 | EXPECT_TRUE(match(Or, m_c_LogicalOr(m_Specific(Y), m_Specific(X)))); |
1943 | |
1944 | EXPECT_FALSE(match(Or, m_c_LogicalOr(m_Specific(X), m_Specific(X)))); |
1945 | EXPECT_FALSE(match(Or, m_c_LogicalOr(m_Specific(Y), m_Specific(Y)))); |
1946 | } |
1947 | |
1948 | TEST_F(PatternMatchTest, VectorLogicalSelects) { |
1949 | Type *i1 = IRB.getInt1Ty(); |
1950 | Type *v3i1 = FixedVectorType::get(ElementType: i1, NumElts: 3); |
1951 | |
1952 | Value *Alloca = IRB.CreateAlloca(Ty: i1); |
1953 | Value *AllocaVec = IRB.CreateAlloca(Ty: v3i1); |
1954 | Value *Scalar = IRB.CreateLoad(Ty: i1, Ptr: Alloca); |
1955 | Value *Vector = IRB.CreateLoad(Ty: v3i1, Ptr: AllocaVec); |
1956 | Constant *F = Constant::getNullValue(Ty: v3i1); |
1957 | Constant *T = Constant::getAllOnesValue(Ty: v3i1); |
1958 | |
1959 | // select <3 x i1> Vector, <3 x i1> Vector, <3 x i1> <i1 0, i1 0, i1 0> |
1960 | Value *VecAnd = IRB.CreateSelect(C: Vector, True: Vector, False: F); |
1961 | |
1962 | // select i1 Scalar, <3 x i1> Vector, <3 x i1> <i1 0, i1 0, i1 0> |
1963 | Value *MixedTypeAnd = IRB.CreateSelect(C: Scalar, True: Vector, False: F); |
1964 | |
1965 | // select <3 x i1> Vector, <3 x i1> <i1 1, i1 1, i1 1>, <3 x i1> Vector |
1966 | Value *VecOr = IRB.CreateSelect(C: Vector, True: T, False: Vector); |
1967 | |
1968 | // select i1 Scalar, <3 x i1> <i1 1, i1 1, i1 1>, <3 x i1> Vector |
1969 | Value *MixedTypeOr = IRB.CreateSelect(C: Scalar, True: T, False: Vector); |
1970 | |
1971 | // We allow matching a real vector logical select, |
1972 | // but not a scalar select of vector bools. |
1973 | EXPECT_TRUE(match(VecAnd, m_LogicalAnd(m_Value(), m_Value()))); |
1974 | EXPECT_FALSE(match(MixedTypeAnd, m_LogicalAnd(m_Value(), m_Value()))); |
1975 | EXPECT_TRUE(match(VecOr, m_LogicalOr(m_Value(), m_Value()))); |
1976 | EXPECT_FALSE(match(MixedTypeOr, m_LogicalOr(m_Value(), m_Value()))); |
1977 | } |
1978 | |
1979 | TEST_F(PatternMatchTest, VScale) { |
1980 | DataLayout DL = M->getDataLayout(); |
1981 | |
1982 | Type *VecTy = ScalableVectorType::get(ElementType: IRB.getInt8Ty(), MinNumElts: 1); |
1983 | Value *NullPtrVec = |
1984 | Constant::getNullValue(Ty: PointerType::getUnqual(C&: VecTy->getContext())); |
1985 | Value *GEP = IRB.CreateGEP(Ty: VecTy, Ptr: NullPtrVec, IdxList: IRB.getInt64(C: 1)); |
1986 | Value *PtrToInt = IRB.CreatePtrToInt(V: GEP, DestTy: DL.getIntPtrType(GEP->getType())); |
1987 | EXPECT_TRUE(match(PtrToInt, m_VScale())); |
1988 | |
1989 | Type *VecTy2 = ScalableVectorType::get(ElementType: IRB.getInt8Ty(), MinNumElts: 2); |
1990 | Value *NullPtrVec2 = |
1991 | Constant::getNullValue(Ty: PointerType::getUnqual(C&: VecTy2->getContext())); |
1992 | Value *GEP2 = IRB.CreateGEP(Ty: VecTy, Ptr: NullPtrVec2, IdxList: IRB.getInt64(C: 1)); |
1993 | Value *PtrToInt2 = |
1994 | IRB.CreatePtrToInt(V: GEP2, DestTy: DL.getIntPtrType(GEP2->getType())); |
1995 | EXPECT_TRUE(match(PtrToInt2, m_VScale())); |
1996 | } |
1997 | |
1998 | TEST_F(PatternMatchTest, NotForbidPoison) { |
1999 | Type *ScalarTy = IRB.getInt8Ty(); |
2000 | Type *VectorTy = FixedVectorType::get(ElementType: ScalarTy, NumElts: 3); |
2001 | Constant *ScalarUndef = UndefValue::get(T: ScalarTy); |
2002 | Constant *ScalarPoison = PoisonValue::get(T: ScalarTy); |
2003 | Constant *ScalarOnes = Constant::getAllOnesValue(Ty: ScalarTy); |
2004 | Constant *VectorZero = Constant::getNullValue(Ty: VectorTy); |
2005 | Constant *VectorOnes = Constant::getAllOnesValue(Ty: VectorTy); |
2006 | |
2007 | SmallVector<Constant *, 3> MixedElemsUndef; |
2008 | MixedElemsUndef.push_back(Elt: ScalarOnes); |
2009 | MixedElemsUndef.push_back(Elt: ScalarOnes); |
2010 | MixedElemsUndef.push_back(Elt: ScalarUndef); |
2011 | Constant *VectorMixedUndef = ConstantVector::get(V: MixedElemsUndef); |
2012 | |
2013 | SmallVector<Constant *, 3> MixedElemsPoison; |
2014 | MixedElemsPoison.push_back(Elt: ScalarOnes); |
2015 | MixedElemsPoison.push_back(Elt: ScalarOnes); |
2016 | MixedElemsPoison.push_back(Elt: ScalarPoison); |
2017 | Constant *VectorMixedPoison = ConstantVector::get(V: MixedElemsPoison); |
2018 | |
2019 | Value *Not = IRB.CreateXor(LHS: VectorZero, RHS: VectorOnes); |
2020 | Value *X; |
2021 | EXPECT_TRUE(match(Not, m_Not(m_Value(X)))); |
2022 | EXPECT_TRUE(match(X, m_Zero())); |
2023 | X = nullptr; |
2024 | EXPECT_TRUE(match(Not, m_NotForbidPoison(m_Value(X)))); |
2025 | EXPECT_TRUE(match(X, m_Zero())); |
2026 | |
2027 | Value *NotCommute = IRB.CreateXor(LHS: VectorOnes, RHS: VectorZero); |
2028 | Value *Y; |
2029 | EXPECT_TRUE(match(NotCommute, m_Not(m_Value(Y)))); |
2030 | EXPECT_TRUE(match(Y, m_Zero())); |
2031 | Y = nullptr; |
2032 | EXPECT_TRUE(match(NotCommute, m_NotForbidPoison(m_Value(Y)))); |
2033 | EXPECT_TRUE(match(Y, m_Zero())); |
2034 | |
2035 | Value *NotWithUndefs = IRB.CreateXor(LHS: VectorZero, RHS: VectorMixedUndef); |
2036 | EXPECT_FALSE(match(NotWithUndefs, m_Not(m_Value()))); |
2037 | EXPECT_FALSE(match(NotWithUndefs, m_NotForbidPoison(m_Value()))); |
2038 | |
2039 | Value *NotWithPoisons = IRB.CreateXor(LHS: VectorZero, RHS: VectorMixedPoison); |
2040 | EXPECT_TRUE(match(NotWithPoisons, m_Not(m_Value()))); |
2041 | EXPECT_FALSE(match(NotWithPoisons, m_NotForbidPoison(m_Value()))); |
2042 | |
2043 | Value *NotWithUndefsCommute = IRB.CreateXor(LHS: VectorMixedUndef, RHS: VectorZero); |
2044 | EXPECT_FALSE(match(NotWithUndefsCommute, m_Not(m_Value()))); |
2045 | EXPECT_FALSE(match(NotWithUndefsCommute, m_NotForbidPoison(m_Value()))); |
2046 | |
2047 | Value *NotWithPoisonsCommute = IRB.CreateXor(LHS: VectorMixedPoison, RHS: VectorZero); |
2048 | EXPECT_TRUE(match(NotWithPoisonsCommute, m_Not(m_Value()))); |
2049 | EXPECT_FALSE(match(NotWithPoisonsCommute, m_NotForbidPoison(m_Value()))); |
2050 | } |
2051 | |
2052 | template <typename T> struct MutableConstTest : PatternMatchTest { }; |
2053 | |
2054 | typedef ::testing::Types<std::tuple<Value*, Instruction*>, |
2055 | std::tuple<const Value*, const Instruction *>> |
2056 | MutableConstTestTypes; |
2057 | TYPED_TEST_SUITE(MutableConstTest, MutableConstTestTypes, ); |
2058 | |
2059 | TYPED_TEST(MutableConstTest, ICmp) { |
2060 | auto &IRB = PatternMatchTest::IRB; |
2061 | |
2062 | typedef std::tuple_element_t<0, TypeParam> ValueType; |
2063 | typedef std::tuple_element_t<1, TypeParam> InstructionType; |
2064 | |
2065 | Value *L = IRB.getInt32(1); |
2066 | Value *R = IRB.getInt32(2); |
2067 | ICmpInst::Predicate Pred = ICmpInst::ICMP_UGT; |
2068 | |
2069 | ValueType MatchL; |
2070 | ValueType MatchR; |
2071 | ICmpInst::Predicate MatchPred; |
2072 | |
2073 | EXPECT_TRUE(m_ICmp(MatchPred, m_Value(MatchL), m_Value(MatchR)) |
2074 | .match((InstructionType)IRB.CreateICmp(Pred, L, R))); |
2075 | EXPECT_EQ(L, MatchL); |
2076 | EXPECT_EQ(R, MatchR); |
2077 | } |
2078 | |
2079 | TEST_F(PatternMatchTest, ConstExpr) { |
2080 | Constant *G = |
2081 | M->getOrInsertGlobal(Name: "dummy" , Ty: PointerType::getUnqual(ElementType: IRB.getInt32Ty())); |
2082 | Constant *S = ConstantExpr::getPtrToInt(C: G, Ty: IRB.getInt32Ty()); |
2083 | Type *VecTy = FixedVectorType::get(ElementType: IRB.getInt32Ty(), NumElts: 2); |
2084 | PoisonValue *P = PoisonValue::get(T: VecTy); |
2085 | Constant *V = ConstantExpr::getInsertElement(Vec: P, Elt: S, Idx: IRB.getInt32(C: 0)); |
2086 | |
2087 | // The match succeeds on a constant that is a constant expression itself |
2088 | // or a constant that contains a constant expression. |
2089 | EXPECT_TRUE(match(S, m_ConstantExpr())); |
2090 | EXPECT_TRUE(match(V, m_ConstantExpr())); |
2091 | } |
2092 | |
2093 | TEST_F(PatternMatchTest, PtrAdd) { |
2094 | Type *PtrTy = PointerType::getUnqual(C&: Ctx); |
2095 | Type *IdxTy = Type::getInt64Ty(C&: Ctx); |
2096 | Constant *Null = Constant::getNullValue(Ty: PtrTy); |
2097 | Constant *Offset = ConstantInt::get(Ty: IdxTy, V: 42); |
2098 | Value *PtrAdd = IRB.CreatePtrAdd(Ptr: Null, Offset); |
2099 | Value *OtherGEP = IRB.CreateGEP(Ty: IdxTy, Ptr: Null, IdxList: Offset); |
2100 | Value *PtrAddConst = |
2101 | ConstantExpr::getGetElementPtr(Ty: Type::getInt8Ty(C&: Ctx), C: Null, Idx: Offset); |
2102 | |
2103 | Value *A, *B; |
2104 | EXPECT_TRUE(match(PtrAdd, m_PtrAdd(m_Value(A), m_Value(B)))); |
2105 | EXPECT_EQ(A, Null); |
2106 | EXPECT_EQ(B, Offset); |
2107 | |
2108 | EXPECT_TRUE(match(PtrAddConst, m_PtrAdd(m_Value(A), m_Value(B)))); |
2109 | EXPECT_EQ(A, Null); |
2110 | EXPECT_EQ(B, Offset); |
2111 | |
2112 | EXPECT_FALSE(match(OtherGEP, m_PtrAdd(m_Value(A), m_Value(B)))); |
2113 | } |
2114 | |
2115 | } // anonymous namespace. |
2116 | |