blob: c4adde4abe345b537b4e93635e6ca3e3793787bd [file] [log] [blame]
James Molloy134bec22015-08-11 09:12:57 +00001//===- ValueTrackingTest.cpp - ValueTracking tests ------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "llvm/Analysis/ValueTracking.h"
11#include "llvm/AsmParser/Parser.h"
12#include "llvm/IR/Function.h"
13#include "llvm/IR/InstIterator.h"
14#include "llvm/IR/LLVMContext.h"
15#include "llvm/IR/Module.h"
16#include "llvm/Support/ErrorHandling.h"
17#include "llvm/Support/SourceMgr.h"
Simon Dardis70dbd5f2017-12-09 23:25:57 +000018#include "llvm/Support/KnownBits.h"
James Molloy134bec22015-08-11 09:12:57 +000019#include "gtest/gtest.h"
20
21using namespace llvm;
22
23namespace {
24
25class MatchSelectPatternTest : public testing::Test {
26protected:
27 void parseAssembly(const char *Assembly) {
28 SMDiagnostic Error;
Mehdi Amini03b42e42016-04-14 21:59:01 +000029 M = parseAssemblyString(Assembly, Error, Context);
James Molloy134bec22015-08-11 09:12:57 +000030
31 std::string errMsg;
32 raw_string_ostream os(errMsg);
33 Error.print("", os);
34
35 // A failure here means that the test itself is buggy.
36 if (!M)
37 report_fatal_error(os.str());
38
39 Function *F = M->getFunction("test");
40 if (F == nullptr)
41 report_fatal_error("Test must have a function named @test");
42
43 A = nullptr;
44 for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
45 if (I->hasName()) {
46 if (I->getName() == "A")
47 A = &*I;
48 }
49 }
50 if (A == nullptr)
51 report_fatal_error("@test must have an instruction %A");
52 }
53
54 void expectPattern(const SelectPatternResult &P) {
55 Value *LHS, *RHS;
56 Instruction::CastOps CastOp;
57 SelectPatternResult R = matchSelectPattern(A, LHS, RHS, &CastOp);
58 EXPECT_EQ(P.Flavor, R.Flavor);
59 EXPECT_EQ(P.NaNBehavior, R.NaNBehavior);
60 EXPECT_EQ(P.Ordered, R.Ordered);
61 }
62
Mehdi Amini03b42e42016-04-14 21:59:01 +000063 LLVMContext Context;
James Molloy134bec22015-08-11 09:12:57 +000064 std::unique_ptr<Module> M;
65 Instruction *A, *B;
66};
67
68}
69
70TEST_F(MatchSelectPatternTest, SimpleFMin) {
71 parseAssembly(
72 "define float @test(float %a) {\n"
73 " %1 = fcmp ult float %a, 5.0\n"
74 " %A = select i1 %1, float %a, float 5.0\n"
75 " ret float %A\n"
76 "}\n");
77 expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, false});
78}
79
80TEST_F(MatchSelectPatternTest, SimpleFMax) {
81 parseAssembly(
82 "define float @test(float %a) {\n"
83 " %1 = fcmp ogt float %a, 5.0\n"
84 " %A = select i1 %1, float %a, float 5.0\n"
85 " ret float %A\n"
86 "}\n");
87 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, true});
88}
89
90TEST_F(MatchSelectPatternTest, SwappedFMax) {
91 parseAssembly(
92 "define float @test(float %a) {\n"
93 " %1 = fcmp olt float 5.0, %a\n"
94 " %A = select i1 %1, float %a, float 5.0\n"
95 " ret float %A\n"
96 "}\n");
97 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, false});
98}
99
100TEST_F(MatchSelectPatternTest, SwappedFMax2) {
101 parseAssembly(
102 "define float @test(float %a) {\n"
103 " %1 = fcmp olt float %a, 5.0\n"
104 " %A = select i1 %1, float 5.0, float %a\n"
105 " ret float %A\n"
106 "}\n");
107 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_NAN, false});
108}
109
110TEST_F(MatchSelectPatternTest, SwappedFMax3) {
111 parseAssembly(
112 "define float @test(float %a) {\n"
113 " %1 = fcmp ult float %a, 5.0\n"
114 " %A = select i1 %1, float 5.0, float %a\n"
115 " ret float %A\n"
116 "}\n");
117 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, true});
118}
119
120TEST_F(MatchSelectPatternTest, FastFMin) {
121 parseAssembly(
122 "define float @test(float %a) {\n"
123 " %1 = fcmp nnan olt float %a, 5.0\n"
124 " %A = select i1 %1, float %a, float 5.0\n"
125 " ret float %A\n"
126 "}\n");
127 expectPattern({SPF_FMINNUM, SPNB_RETURNS_ANY, false});
128}
129
130TEST_F(MatchSelectPatternTest, FMinConstantZero) {
131 parseAssembly(
132 "define float @test(float %a) {\n"
133 " %1 = fcmp ole float %a, 0.0\n"
134 " %A = select i1 %1, float %a, float 0.0\n"
135 " ret float %A\n"
136 "}\n");
137 // This shouldn't be matched, as %a could be -0.0.
138 expectPattern({SPF_UNKNOWN, SPNB_NA, false});
139}
140
141TEST_F(MatchSelectPatternTest, FMinConstantZeroNsz) {
142 parseAssembly(
143 "define float @test(float %a) {\n"
144 " %1 = fcmp nsz ole float %a, 0.0\n"
145 " %A = select i1 %1, float %a, float 0.0\n"
146 " ret float %A\n"
147 "}\n");
148 // But this should be, because we've ignored signed zeroes.
149 expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, true});
150}
James Molloy569cea62015-09-02 17:25:25 +0000151
Sanjay Patel03da6e62018-10-31 21:11:59 +0000152TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero1) {
153 parseAssembly(
154 "define float @test(float %a) {\n"
155 " %1 = fcmp olt float -0.0, %a\n"
156 " %A = select i1 %1, float 0.0, float %a\n"
157 " ret float %A\n"
158 "}\n");
Sanjay Patele7c94ef2018-11-04 14:28:48 +0000159 // The sign of zero doesn't matter in fcmp.
160 expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, true});
Sanjay Patel03da6e62018-10-31 21:11:59 +0000161}
162
163TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero2) {
164 parseAssembly(
165 "define float @test(float %a) {\n"
166 " %1 = fcmp ogt float %a, -0.0\n"
167 " %A = select i1 %1, float 0.0, float %a\n"
168 " ret float %A\n"
169 "}\n");
Sanjay Patele7c94ef2018-11-04 14:28:48 +0000170 // The sign of zero doesn't matter in fcmp.
171 expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, false});
Sanjay Patel03da6e62018-10-31 21:11:59 +0000172}
173
174TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero3) {
175 parseAssembly(
176 "define float @test(float %a) {\n"
177 " %1 = fcmp olt float 0.0, %a\n"
178 " %A = select i1 %1, float -0.0, float %a\n"
179 " ret float %A\n"
180 "}\n");
Sanjay Patele7c94ef2018-11-04 14:28:48 +0000181 // The sign of zero doesn't matter in fcmp.
182 expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, true});
Sanjay Patel03da6e62018-10-31 21:11:59 +0000183}
184
185TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero4) {
186 parseAssembly(
187 "define float @test(float %a) {\n"
188 " %1 = fcmp ogt float %a, 0.0\n"
189 " %A = select i1 %1, float -0.0, float %a\n"
190 " ret float %A\n"
191 "}\n");
Sanjay Patele7c94ef2018-11-04 14:28:48 +0000192 // The sign of zero doesn't matter in fcmp.
193 expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, false});
Sanjay Patel03da6e62018-10-31 21:11:59 +0000194}
195
196TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero5) {
197 parseAssembly(
198 "define float @test(float %a) {\n"
199 " %1 = fcmp ogt float -0.0, %a\n"
200 " %A = select i1 %1, float %a, float 0.0\n"
201 " ret float %A\n"
202 "}\n");
Sanjay Patele7c94ef2018-11-04 14:28:48 +0000203 // The sign of zero doesn't matter in fcmp.
204 expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, false});
Sanjay Patel03da6e62018-10-31 21:11:59 +0000205}
206
207TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero6) {
208 parseAssembly(
209 "define float @test(float %a) {\n"
210 " %1 = fcmp olt float %a, -0.0\n"
211 " %A = select i1 %1, float %a, float 0.0\n"
212 " ret float %A\n"
213 "}\n");
Sanjay Patele7c94ef2018-11-04 14:28:48 +0000214 // The sign of zero doesn't matter in fcmp.
215 expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, true});
Sanjay Patel03da6e62018-10-31 21:11:59 +0000216}
217
218TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero7) {
219 parseAssembly(
220 "define float @test(float %a) {\n"
221 " %1 = fcmp ogt float 0.0, %a\n"
222 " %A = select i1 %1, float %a, float -0.0\n"
223 " ret float %A\n"
224 "}\n");
Sanjay Patele7c94ef2018-11-04 14:28:48 +0000225 // The sign of zero doesn't matter in fcmp.
226 expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, false});
Sanjay Patel03da6e62018-10-31 21:11:59 +0000227}
228
229TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero8) {
230 parseAssembly(
231 "define float @test(float %a) {\n"
232 " %1 = fcmp olt float %a, 0.0\n"
233 " %A = select i1 %1, float %a, float -0.0\n"
234 " ret float %A\n"
235 "}\n");
Sanjay Patele7c94ef2018-11-04 14:28:48 +0000236 // The sign of zero doesn't matter in fcmp.
237 expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, true});
Sanjay Patel03da6e62018-10-31 21:11:59 +0000238}
239
240TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero1) {
241 parseAssembly(
242 "define float @test(float %a) {\n"
243 " %1 = fcmp ogt float -0.0, %a\n"
244 " %A = select i1 %1, float 0.0, float %a\n"
245 " ret float %A\n"
246 "}\n");
Sanjay Patele7c94ef2018-11-04 14:28:48 +0000247 // The sign of zero doesn't matter in fcmp.
248 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_NAN, true});
Sanjay Patel03da6e62018-10-31 21:11:59 +0000249}
250
251TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero2) {
252 parseAssembly(
253 "define float @test(float %a) {\n"
254 " %1 = fcmp olt float %a, -0.0\n"
255 " %A = select i1 %1, float 0.0, float %a\n"
256 " ret float %A\n"
257 "}\n");
Sanjay Patele7c94ef2018-11-04 14:28:48 +0000258 // The sign of zero doesn't matter in fcmp.
259 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_NAN, false});
Sanjay Patel03da6e62018-10-31 21:11:59 +0000260}
261
262TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero3) {
263 parseAssembly(
264 "define float @test(float %a) {\n"
265 " %1 = fcmp ogt float 0.0, %a\n"
266 " %A = select i1 %1, float -0.0, float %a\n"
267 " ret float %A\n"
268 "}\n");
Sanjay Patele7c94ef2018-11-04 14:28:48 +0000269 // The sign of zero doesn't matter in fcmp.
270 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_NAN, true});
Sanjay Patel03da6e62018-10-31 21:11:59 +0000271}
272
273TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero4) {
274 parseAssembly(
275 "define float @test(float %a) {\n"
276 " %1 = fcmp olt float %a, 0.0\n"
277 " %A = select i1 %1, float -0.0, float %a\n"
278 " ret float %A\n"
279 "}\n");
Sanjay Patele7c94ef2018-11-04 14:28:48 +0000280 // The sign of zero doesn't matter in fcmp.
281 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_NAN, false});
Sanjay Patel03da6e62018-10-31 21:11:59 +0000282}
283
284TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero5) {
285 parseAssembly(
286 "define float @test(float %a) {\n"
287 " %1 = fcmp olt float -0.0, %a\n"
288 " %A = select i1 %1, float %a, float 0.0\n"
289 " ret float %A\n"
290 "}\n");
Sanjay Patele7c94ef2018-11-04 14:28:48 +0000291 // The sign of zero doesn't matter in fcmp.
292 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, false});
Sanjay Patel03da6e62018-10-31 21:11:59 +0000293}
294
295TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero6) {
296 parseAssembly(
297 "define float @test(float %a) {\n"
298 " %1 = fcmp ogt float %a, -0.0\n"
299 " %A = select i1 %1, float %a, float 0.0\n"
300 " ret float %A\n"
301 "}\n");
Sanjay Patele7c94ef2018-11-04 14:28:48 +0000302 // The sign of zero doesn't matter in fcmp.
303 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, true});
Sanjay Patel03da6e62018-10-31 21:11:59 +0000304}
305
306TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero7) {
307 parseAssembly(
308 "define float @test(float %a) {\n"
309 " %1 = fcmp olt float 0.0, %a\n"
310 " %A = select i1 %1, float %a, float -0.0\n"
311 " ret float %A\n"
312 "}\n");
Sanjay Patele7c94ef2018-11-04 14:28:48 +0000313 // The sign of zero doesn't matter in fcmp.
314 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, false});
Sanjay Patel03da6e62018-10-31 21:11:59 +0000315}
316
317TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero8) {
318 parseAssembly(
319 "define float @test(float %a) {\n"
320 " %1 = fcmp ogt float %a, 0.0\n"
321 " %A = select i1 %1, float %a, float -0.0\n"
322 " ret float %A\n"
323 "}\n");
Sanjay Patele7c94ef2018-11-04 14:28:48 +0000324 // The sign of zero doesn't matter in fcmp.
325 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, true});
326}
327
328TEST_F(MatchSelectPatternTest, FMinMismatchConstantZeroVecUndef) {
329 parseAssembly(
330 "define <2 x float> @test(<2 x float> %a) {\n"
331 " %1 = fcmp ogt <2 x float> %a, <float -0.0, float -0.0>\n"
332 " %A = select <2 x i1> %1, <2 x float> <float undef, float 0.0>, <2 x float> %a\n"
333 " ret <2 x float> %A\n"
334 "}\n");
335 // An undef in a vector constant can not be back-propagated for this analysis.
336 expectPattern({SPF_UNKNOWN, SPNB_NA, false});
337}
338
339TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZeroVecUndef) {
340 parseAssembly(
341 "define <2 x float> @test(<2 x float> %a) {\n"
342 " %1 = fcmp ogt <2 x float> %a, zeroinitializer\n"
343 " %A = select <2 x i1> %1, <2 x float> %a, <2 x float> <float -0.0, float undef>\n"
344 " ret <2 x float> %A\n"
345 "}\n");
346 // An undef in a vector constant can not be back-propagated for this analysis.
Sanjay Patel03da6e62018-10-31 21:11:59 +0000347 expectPattern({SPF_UNKNOWN, SPNB_NA, false});
348}
349
Thomas Lively30f1d692018-10-24 22:49:55 +0000350TEST_F(MatchSelectPatternTest, VectorFMinimum) {
Thomas Livelyd47b5c72018-09-28 21:36:43 +0000351 parseAssembly(
352 "define <4 x float> @test(<4 x float> %a) {\n"
353 " %1 = fcmp ule <4 x float> %a, \n"
354 " <float 5.0, float 5.0, float 5.0, float 5.0>\n"
355 " %A = select <4 x i1> %1, <4 x float> %a,\n"
356 " <4 x float> <float 5.0, float 5.0, float 5.0, float 5.0>\n"
357 " ret <4 x float> %A\n"
358 "}\n");
359 // Check that pattern matching works on vectors where each lane has the same
360 // unordered pattern.
361 expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, false});
362}
363
364TEST_F(MatchSelectPatternTest, VectorFMinOtherOrdered) {
365 parseAssembly(
366 "define <4 x float> @test(<4 x float> %a) {\n"
367 " %1 = fcmp ole <4 x float> %a, \n"
368 " <float 5.0, float 5.0, float 5.0, float 5.0>\n"
369 " %A = select <4 x i1> %1, <4 x float> %a,\n"
370 " <4 x float> <float 5.0, float 5.0, float 5.0, float 5.0>\n"
371 " ret <4 x float> %A\n"
372 "}\n");
373 // Check that pattern matching works on vectors where each lane has the same
374 // ordered pattern.
375 expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, true});
376}
377
Thomas Lively30f1d692018-10-24 22:49:55 +0000378TEST_F(MatchSelectPatternTest, VectorNotFMinimum) {
Thomas Livelyd47b5c72018-09-28 21:36:43 +0000379 parseAssembly(
380 "define <4 x float> @test(<4 x float> %a) {\n"
381 " %1 = fcmp ule <4 x float> %a, \n"
382 " <float 5.0, float 0x7ff8000000000000, float 5.0, float 5.0>\n"
383 " %A = select <4 x i1> %1, <4 x float> %a,\n"
384 " <4 x float> <float 5.0, float 0x7ff8000000000000, float 5.0, float "
385 "5.0>\n"
386 " ret <4 x float> %A\n"
387 "}\n");
388 // The lane that contains a NaN (0x7ff80...) behaves like a
389 // non-NaN-propagating min and the other lines behave like a NaN-propagating
390 // min, so check that neither is returned.
391 expectPattern({SPF_UNKNOWN, SPNB_NA, false});
392}
393
394TEST_F(MatchSelectPatternTest, VectorNotFMinZero) {
395 parseAssembly(
396 "define <4 x float> @test(<4 x float> %a) {\n"
397 " %1 = fcmp ule <4 x float> %a, \n"
398 " <float 5.0, float -0.0, float 5.0, float 5.0>\n"
399 " %A = select <4 x i1> %1, <4 x float> %a,\n"
400 " <4 x float> <float 5.0, float 0.0, float 5.0, float 5.0>\n"
401 " ret <4 x float> %A\n"
402 "}\n");
403 // Always selects the second lane of %a if it is positive or negative zero, so
404 // this is stricter than a min.
405 expectPattern({SPF_UNKNOWN, SPNB_NA, false});
406}
407
James Molloy569cea62015-09-02 17:25:25 +0000408TEST_F(MatchSelectPatternTest, DoubleCastU) {
409 parseAssembly(
410 "define i32 @test(i8 %a, i8 %b) {\n"
411 " %1 = icmp ult i8 %a, %b\n"
412 " %2 = zext i8 %a to i32\n"
413 " %3 = zext i8 %b to i32\n"
414 " %A = select i1 %1, i32 %2, i32 %3\n"
415 " ret i32 %A\n"
416 "}\n");
417 // We should be able to look through the situation where we cast both operands
418 // to the select.
419 expectPattern({SPF_UMIN, SPNB_NA, false});
420}
421
422TEST_F(MatchSelectPatternTest, DoubleCastS) {
423 parseAssembly(
424 "define i32 @test(i8 %a, i8 %b) {\n"
425 " %1 = icmp slt i8 %a, %b\n"
426 " %2 = sext i8 %a to i32\n"
427 " %3 = sext i8 %b to i32\n"
428 " %A = select i1 %1, i32 %2, i32 %3\n"
429 " ret i32 %A\n"
430 "}\n");
431 // We should be able to look through the situation where we cast both operands
432 // to the select.
433 expectPattern({SPF_SMIN, SPNB_NA, false});
434}
435
436TEST_F(MatchSelectPatternTest, DoubleCastBad) {
437 parseAssembly(
438 "define i32 @test(i8 %a, i8 %b) {\n"
439 " %1 = icmp ult i8 %a, %b\n"
440 " %2 = zext i8 %a to i32\n"
441 " %3 = sext i8 %b to i32\n"
442 " %A = select i1 %1, i32 %2, i32 %3\n"
443 " ret i32 %A\n"
444 "}\n");
James Molloy687a8442015-09-02 17:29:54 +0000445 // The cast types here aren't the same, so we cannot match an UMIN.
James Molloy569cea62015-09-02 17:25:25 +0000446 expectPattern({SPF_UNKNOWN, SPNB_NA, false});
447}
Sanjoy Das3bb2dbd2016-12-31 22:12:34 +0000448
449TEST(ValueTracking, GuaranteedToTransferExecutionToSuccessor) {
450 StringRef Assembly =
451 "declare void @nounwind_readonly(i32*) nounwind readonly "
452 "declare void @nounwind_argmemonly(i32*) nounwind argmemonly "
453 "declare void @throws_but_readonly(i32*) readonly "
454 "declare void @throws_but_argmemonly(i32*) argmemonly "
455 " "
456 "declare void @unknown(i32*) "
457 " "
458 "define void @f(i32* %p) { "
459 " call void @nounwind_readonly(i32* %p) "
460 " call void @nounwind_argmemonly(i32* %p) "
461 " call void @throws_but_readonly(i32* %p) "
462 " call void @throws_but_argmemonly(i32* %p) "
463 " call void @unknown(i32* %p) nounwind readonly "
464 " call void @unknown(i32* %p) nounwind argmemonly "
465 " call void @unknown(i32* %p) readonly "
466 " call void @unknown(i32* %p) argmemonly "
467 " ret void "
468 "} ";
469
470 LLVMContext Context;
471 SMDiagnostic Error;
472 auto M = parseAssemblyString(Assembly, Error, Context);
473 assert(M && "Bad assembly?");
474
475 auto *F = M->getFunction("f");
476 assert(F && "Bad assembly?");
477
478 auto &BB = F->getEntryBlock();
Craig Topper8580cd42017-04-14 17:59:19 +0000479 bool ExpectedAnswers[] = {
Sanjoy Das3bb2dbd2016-12-31 22:12:34 +0000480 true, // call void @nounwind_readonly(i32* %p)
481 true, // call void @nounwind_argmemonly(i32* %p)
482 false, // call void @throws_but_readonly(i32* %p)
483 false, // call void @throws_but_argmemonly(i32* %p)
484 true, // call void @unknown(i32* %p) nounwind readonly
485 true, // call void @unknown(i32* %p) nounwind argmemonly
486 false, // call void @unknown(i32* %p) readonly
487 false, // call void @unknown(i32* %p) argmemonly
488 false, // ret void
489 };
490
491 int Index = 0;
492 for (auto &I : BB) {
493 EXPECT_EQ(isGuaranteedToTransferExecutionToSuccessor(&I),
494 ExpectedAnswers[Index])
495 << "Incorrect answer at instruction " << Index << " = " << I;
496 Index++;
497 }
498}
Sanjoy Das39a684d2017-02-25 20:30:45 +0000499
500TEST(ValueTracking, ComputeNumSignBits_PR32045) {
501 StringRef Assembly = "define i32 @f(i32 %a) { "
502 " %val = ashr i32 %a, -1 "
503 " ret i32 %val "
504 "} ";
505
506 LLVMContext Context;
507 SMDiagnostic Error;
508 auto M = parseAssemblyString(Assembly, Error, Context);
509 assert(M && "Bad assembly?");
510
511 auto *F = M->getFunction("f");
512 assert(F && "Bad assembly?");
513
514 auto *RVal =
515 cast<ReturnInst>(F->getEntryBlock().getTerminator())->getOperand(0);
Sanjoy Das4897cea2017-02-25 22:25:48 +0000516 EXPECT_EQ(ComputeNumSignBits(RVal, M->getDataLayout()), 1u);
Sanjoy Das39a684d2017-02-25 20:30:45 +0000517}
Simon Dardis70dbd5f2017-12-09 23:25:57 +0000518
Sanjay Patela68096c2018-11-02 15:51:47 +0000519// No guarantees for canonical IR in this analysis, so this just bails out.
520TEST(ValueTracking, ComputeNumSignBits_Shuffle) {
521 StringRef Assembly = "define <2 x i32> @f() { "
522 " %val = shufflevector <2 x i32> undef, <2 x i32> undef, <2 x i32> <i32 0, i32 0> "
523 " ret <2 x i32> %val "
524 "} ";
525
526 LLVMContext Context;
527 SMDiagnostic Error;
528 auto M = parseAssemblyString(Assembly, Error, Context);
529 assert(M && "Bad assembly?");
530
531 auto *F = M->getFunction("f");
532 assert(F && "Bad assembly?");
533
534 auto *RVal =
535 cast<ReturnInst>(F->getEntryBlock().getTerminator())->getOperand(0);
536 EXPECT_EQ(ComputeNumSignBits(RVal, M->getDataLayout()), 1u);
537}
538
Sanjay Patel45a148d2018-11-02 18:14:24 +0000539// No guarantees for canonical IR in this analysis, so a shuffle element that
540// references an undef value means this can't return any extra information.
541TEST(ValueTracking, ComputeNumSignBits_Shuffle2) {
542 StringRef Assembly = "define <2 x i32> @f(<2 x i1> %x) { "
543 " %sext = sext <2 x i1> %x to <2 x i32> "
544 " %val = shufflevector <2 x i32> %sext, <2 x i32> undef, <2 x i32> <i32 0, i32 2> "
545 " ret <2 x i32> %val "
546 "} ";
547
548 LLVMContext Context;
549 SMDiagnostic Error;
550 auto M = parseAssemblyString(Assembly, Error, Context);
551 assert(M && "Bad assembly?");
552
553 auto *F = M->getFunction("f");
554 assert(F && "Bad assembly?");
555
556 auto *RVal =
557 cast<ReturnInst>(F->getEntryBlock().getTerminator())->getOperand(0);
Sanjay Patelcac28b42018-11-03 13:18:55 +0000558 EXPECT_EQ(ComputeNumSignBits(RVal, M->getDataLayout()), 1u);
Sanjay Patel45a148d2018-11-02 18:14:24 +0000559}
560
Simon Dardis70dbd5f2017-12-09 23:25:57 +0000561TEST(ValueTracking, ComputeKnownBits) {
562 StringRef Assembly = "define i32 @f(i32 %a, i32 %b) { "
563 " %ash = mul i32 %a, 8 "
564 " %aad = add i32 %ash, 7 "
565 " %aan = and i32 %aad, 4095 "
566 " %bsh = shl i32 %b, 4 "
567 " %bad = or i32 %bsh, 6 "
568 " %ban = and i32 %bad, 4095 "
569 " %mul = mul i32 %aan, %ban "
570 " ret i32 %mul "
571 "} ";
572
573 LLVMContext Context;
574 SMDiagnostic Error;
575 auto M = parseAssemblyString(Assembly, Error, Context);
576 assert(M && "Bad assembly?");
577
578 auto *F = M->getFunction("f");
579 assert(F && "Bad assembly?");
580
581 auto *RVal =
582 cast<ReturnInst>(F->getEntryBlock().getTerminator())->getOperand(0);
583 auto Known = computeKnownBits(RVal, M->getDataLayout());
584 ASSERT_FALSE(Known.hasConflict());
585 EXPECT_EQ(Known.One.getZExtValue(), 10u);
586 EXPECT_EQ(Known.Zero.getZExtValue(), 4278190085u);
587}
588
589TEST(ValueTracking, ComputeKnownMulBits) {
590 StringRef Assembly = "define i32 @f(i32 %a, i32 %b) { "
591 " %aa = shl i32 %a, 5 "
592 " %bb = shl i32 %b, 5 "
593 " %aaa = or i32 %aa, 24 "
594 " %bbb = or i32 %bb, 28 "
595 " %mul = mul i32 %aaa, %bbb "
596 " ret i32 %mul "
597 "} ";
598
599 LLVMContext Context;
600 SMDiagnostic Error;
601 auto M = parseAssemblyString(Assembly, Error, Context);
602 assert(M && "Bad assembly?");
603
604 auto *F = M->getFunction("f");
605 assert(F && "Bad assembly?");
606
607 auto *RVal =
608 cast<ReturnInst>(F->getEntryBlock().getTerminator())->getOperand(0);
609 auto Known = computeKnownBits(RVal, M->getDataLayout());
610 ASSERT_FALSE(Known.hasConflict());
611 EXPECT_EQ(Known.One.getZExtValue(), 32u);
612 EXPECT_EQ(Known.Zero.getZExtValue(), 95u);
613}