blob: 5b36d63b3906304f42f4d11b33e41ae6fa32f5ff [file] [log] [blame]
James Molloycd45f4f2015-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 Dardis1134b2a2017-12-09 23:25:57 +000018#include "llvm/Support/KnownBits.h"
James Molloycd45f4f2015-08-11 09:12:57 +000019#include "gtest/gtest.h"
20
21using namespace llvm;
22
23namespace {
24
Nikita Popovc16c6e62018-11-30 22:22:30 +000025class ValueTrackingTest : public testing::Test {
James Molloycd45f4f2015-08-11 09:12:57 +000026protected:
27 void parseAssembly(const char *Assembly) {
28 SMDiagnostic Error;
Mehdi Amini8be77072016-04-14 21:59:01 +000029 M = parseAssemblyString(Assembly, Error, Context);
James Molloycd45f4f2015-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
Nikita Popovc16c6e62018-11-30 22:22:30 +000054 LLVMContext Context;
55 std::unique_ptr<Module> M;
56 Instruction *A;
57};
58
59class MatchSelectPatternTest : public ValueTrackingTest {
60protected:
James Molloycd45f4f2015-08-11 09:12:57 +000061 void expectPattern(const SelectPatternResult &P) {
62 Value *LHS, *RHS;
63 Instruction::CastOps CastOp;
64 SelectPatternResult R = matchSelectPattern(A, LHS, RHS, &CastOp);
65 EXPECT_EQ(P.Flavor, R.Flavor);
66 EXPECT_EQ(P.NaNBehavior, R.NaNBehavior);
67 EXPECT_EQ(P.Ordered, R.Ordered);
68 }
Nikita Popovc16c6e62018-11-30 22:22:30 +000069};
James Molloycd45f4f2015-08-11 09:12:57 +000070
Nikita Popovc16c6e62018-11-30 22:22:30 +000071class ComputeKnownBitsTest : public ValueTrackingTest {
72protected:
73 void expectKnownBits(uint64_t Zero, uint64_t One) {
74 auto Known = computeKnownBits(A, M->getDataLayout());
75 ASSERT_FALSE(Known.hasConflict());
76 EXPECT_EQ(Known.One.getZExtValue(), One);
77 EXPECT_EQ(Known.Zero.getZExtValue(), Zero);
78 }
James Molloycd45f4f2015-08-11 09:12:57 +000079};
80
81}
82
83TEST_F(MatchSelectPatternTest, SimpleFMin) {
84 parseAssembly(
85 "define float @test(float %a) {\n"
86 " %1 = fcmp ult float %a, 5.0\n"
87 " %A = select i1 %1, float %a, float 5.0\n"
88 " ret float %A\n"
89 "}\n");
90 expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, false});
91}
92
93TEST_F(MatchSelectPatternTest, SimpleFMax) {
94 parseAssembly(
95 "define float @test(float %a) {\n"
96 " %1 = fcmp ogt float %a, 5.0\n"
97 " %A = select i1 %1, float %a, float 5.0\n"
98 " ret float %A\n"
99 "}\n");
100 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, true});
101}
102
103TEST_F(MatchSelectPatternTest, SwappedFMax) {
104 parseAssembly(
105 "define float @test(float %a) {\n"
106 " %1 = fcmp olt float 5.0, %a\n"
107 " %A = select i1 %1, float %a, float 5.0\n"
108 " ret float %A\n"
109 "}\n");
110 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, false});
111}
112
113TEST_F(MatchSelectPatternTest, SwappedFMax2) {
114 parseAssembly(
115 "define float @test(float %a) {\n"
116 " %1 = fcmp olt float %a, 5.0\n"
117 " %A = select i1 %1, float 5.0, float %a\n"
118 " ret float %A\n"
119 "}\n");
120 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_NAN, false});
121}
122
123TEST_F(MatchSelectPatternTest, SwappedFMax3) {
124 parseAssembly(
125 "define float @test(float %a) {\n"
126 " %1 = fcmp ult float %a, 5.0\n"
127 " %A = select i1 %1, float 5.0, float %a\n"
128 " ret float %A\n"
129 "}\n");
130 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, true});
131}
132
133TEST_F(MatchSelectPatternTest, FastFMin) {
134 parseAssembly(
135 "define float @test(float %a) {\n"
136 " %1 = fcmp nnan olt float %a, 5.0\n"
137 " %A = select i1 %1, float %a, float 5.0\n"
138 " ret float %A\n"
139 "}\n");
140 expectPattern({SPF_FMINNUM, SPNB_RETURNS_ANY, false});
141}
142
143TEST_F(MatchSelectPatternTest, FMinConstantZero) {
144 parseAssembly(
145 "define float @test(float %a) {\n"
146 " %1 = fcmp ole float %a, 0.0\n"
147 " %A = select i1 %1, float %a, float 0.0\n"
148 " ret float %A\n"
149 "}\n");
150 // This shouldn't be matched, as %a could be -0.0.
151 expectPattern({SPF_UNKNOWN, SPNB_NA, false});
152}
153
154TEST_F(MatchSelectPatternTest, FMinConstantZeroNsz) {
155 parseAssembly(
156 "define float @test(float %a) {\n"
157 " %1 = fcmp nsz ole float %a, 0.0\n"
158 " %A = select i1 %1, float %a, float 0.0\n"
159 " ret float %A\n"
160 "}\n");
161 // But this should be, because we've ignored signed zeroes.
162 expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, true});
163}
James Molloy983cfca2015-09-02 17:25:25 +0000164
Sanjay Patelb98edf72018-10-31 21:11:59 +0000165TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero1) {
166 parseAssembly(
167 "define float @test(float %a) {\n"
168 " %1 = fcmp olt float -0.0, %a\n"
169 " %A = select i1 %1, float 0.0, float %a\n"
170 " ret float %A\n"
171 "}\n");
Sanjay Patelfd7c7dd2018-11-04 14:28:48 +0000172 // The sign of zero doesn't matter in fcmp.
173 expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, true});
Sanjay Patelb98edf72018-10-31 21:11:59 +0000174}
175
176TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero2) {
177 parseAssembly(
178 "define float @test(float %a) {\n"
179 " %1 = fcmp ogt float %a, -0.0\n"
180 " %A = select i1 %1, float 0.0, float %a\n"
181 " ret float %A\n"
182 "}\n");
Sanjay Patelfd7c7dd2018-11-04 14:28:48 +0000183 // The sign of zero doesn't matter in fcmp.
184 expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, false});
Sanjay Patelb98edf72018-10-31 21:11:59 +0000185}
186
187TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero3) {
188 parseAssembly(
189 "define float @test(float %a) {\n"
190 " %1 = fcmp olt float 0.0, %a\n"
191 " %A = select i1 %1, float -0.0, float %a\n"
192 " ret float %A\n"
193 "}\n");
Sanjay Patelfd7c7dd2018-11-04 14:28:48 +0000194 // The sign of zero doesn't matter in fcmp.
195 expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, true});
Sanjay Patelb98edf72018-10-31 21:11:59 +0000196}
197
198TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero4) {
199 parseAssembly(
200 "define float @test(float %a) {\n"
201 " %1 = fcmp ogt float %a, 0.0\n"
202 " %A = select i1 %1, float -0.0, float %a\n"
203 " ret float %A\n"
204 "}\n");
Sanjay Patelfd7c7dd2018-11-04 14:28:48 +0000205 // The sign of zero doesn't matter in fcmp.
206 expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, false});
Sanjay Patelb98edf72018-10-31 21:11:59 +0000207}
208
209TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero5) {
210 parseAssembly(
211 "define float @test(float %a) {\n"
212 " %1 = fcmp ogt float -0.0, %a\n"
213 " %A = select i1 %1, float %a, float 0.0\n"
214 " ret float %A\n"
215 "}\n");
Sanjay Patelfd7c7dd2018-11-04 14:28:48 +0000216 // The sign of zero doesn't matter in fcmp.
217 expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, false});
Sanjay Patelb98edf72018-10-31 21:11:59 +0000218}
219
220TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero6) {
221 parseAssembly(
222 "define float @test(float %a) {\n"
223 " %1 = fcmp olt float %a, -0.0\n"
224 " %A = select i1 %1, float %a, float 0.0\n"
225 " ret float %A\n"
226 "}\n");
Sanjay Patelfd7c7dd2018-11-04 14:28:48 +0000227 // The sign of zero doesn't matter in fcmp.
228 expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, true});
Sanjay Patelb98edf72018-10-31 21:11:59 +0000229}
230
231TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero7) {
232 parseAssembly(
233 "define float @test(float %a) {\n"
234 " %1 = fcmp ogt float 0.0, %a\n"
235 " %A = select i1 %1, float %a, float -0.0\n"
236 " ret float %A\n"
237 "}\n");
Sanjay Patelfd7c7dd2018-11-04 14:28:48 +0000238 // The sign of zero doesn't matter in fcmp.
239 expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, false});
Sanjay Patelb98edf72018-10-31 21:11:59 +0000240}
241
242TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero8) {
243 parseAssembly(
244 "define float @test(float %a) {\n"
245 " %1 = fcmp olt float %a, 0.0\n"
246 " %A = select i1 %1, float %a, float -0.0\n"
247 " ret float %A\n"
248 "}\n");
Sanjay Patelfd7c7dd2018-11-04 14:28:48 +0000249 // The sign of zero doesn't matter in fcmp.
250 expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, true});
Sanjay Patelb98edf72018-10-31 21:11:59 +0000251}
252
253TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero1) {
254 parseAssembly(
255 "define float @test(float %a) {\n"
256 " %1 = fcmp ogt float -0.0, %a\n"
257 " %A = select i1 %1, float 0.0, float %a\n"
258 " ret float %A\n"
259 "}\n");
Sanjay Patelfd7c7dd2018-11-04 14:28:48 +0000260 // The sign of zero doesn't matter in fcmp.
261 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_NAN, true});
Sanjay Patelb98edf72018-10-31 21:11:59 +0000262}
263
264TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero2) {
265 parseAssembly(
266 "define float @test(float %a) {\n"
267 " %1 = fcmp olt float %a, -0.0\n"
268 " %A = select i1 %1, float 0.0, float %a\n"
269 " ret float %A\n"
270 "}\n");
Sanjay Patelfd7c7dd2018-11-04 14:28:48 +0000271 // The sign of zero doesn't matter in fcmp.
272 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_NAN, false});
Sanjay Patelb98edf72018-10-31 21:11:59 +0000273}
274
275TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero3) {
276 parseAssembly(
277 "define float @test(float %a) {\n"
278 " %1 = fcmp ogt float 0.0, %a\n"
279 " %A = select i1 %1, float -0.0, float %a\n"
280 " ret float %A\n"
281 "}\n");
Sanjay Patelfd7c7dd2018-11-04 14:28:48 +0000282 // The sign of zero doesn't matter in fcmp.
283 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_NAN, true});
Sanjay Patelb98edf72018-10-31 21:11:59 +0000284}
285
286TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero4) {
287 parseAssembly(
288 "define float @test(float %a) {\n"
289 " %1 = fcmp olt float %a, 0.0\n"
290 " %A = select i1 %1, float -0.0, float %a\n"
291 " ret float %A\n"
292 "}\n");
Sanjay Patelfd7c7dd2018-11-04 14:28:48 +0000293 // The sign of zero doesn't matter in fcmp.
294 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_NAN, false});
Sanjay Patelb98edf72018-10-31 21:11:59 +0000295}
296
297TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero5) {
298 parseAssembly(
299 "define float @test(float %a) {\n"
300 " %1 = fcmp olt float -0.0, %a\n"
301 " %A = select i1 %1, float %a, float 0.0\n"
302 " ret float %A\n"
303 "}\n");
Sanjay Patelfd7c7dd2018-11-04 14:28:48 +0000304 // The sign of zero doesn't matter in fcmp.
305 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, false});
Sanjay Patelb98edf72018-10-31 21:11:59 +0000306}
307
308TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero6) {
309 parseAssembly(
310 "define float @test(float %a) {\n"
311 " %1 = fcmp ogt float %a, -0.0\n"
312 " %A = select i1 %1, float %a, float 0.0\n"
313 " ret float %A\n"
314 "}\n");
Sanjay Patelfd7c7dd2018-11-04 14:28:48 +0000315 // The sign of zero doesn't matter in fcmp.
316 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, true});
Sanjay Patelb98edf72018-10-31 21:11:59 +0000317}
318
319TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero7) {
320 parseAssembly(
321 "define float @test(float %a) {\n"
322 " %1 = fcmp olt float 0.0, %a\n"
323 " %A = select i1 %1, float %a, float -0.0\n"
324 " ret float %A\n"
325 "}\n");
Sanjay Patelfd7c7dd2018-11-04 14:28:48 +0000326 // The sign of zero doesn't matter in fcmp.
327 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, false});
Sanjay Patelb98edf72018-10-31 21:11:59 +0000328}
329
330TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero8) {
331 parseAssembly(
332 "define float @test(float %a) {\n"
333 " %1 = fcmp ogt float %a, 0.0\n"
334 " %A = select i1 %1, float %a, float -0.0\n"
335 " ret float %A\n"
336 "}\n");
Sanjay Patelfd7c7dd2018-11-04 14:28:48 +0000337 // The sign of zero doesn't matter in fcmp.
338 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, true});
339}
340
341TEST_F(MatchSelectPatternTest, FMinMismatchConstantZeroVecUndef) {
342 parseAssembly(
343 "define <2 x float> @test(<2 x float> %a) {\n"
344 " %1 = fcmp ogt <2 x float> %a, <float -0.0, float -0.0>\n"
345 " %A = select <2 x i1> %1, <2 x float> <float undef, float 0.0>, <2 x float> %a\n"
346 " ret <2 x float> %A\n"
347 "}\n");
348 // An undef in a vector constant can not be back-propagated for this analysis.
349 expectPattern({SPF_UNKNOWN, SPNB_NA, false});
350}
351
352TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZeroVecUndef) {
353 parseAssembly(
354 "define <2 x float> @test(<2 x float> %a) {\n"
355 " %1 = fcmp ogt <2 x float> %a, zeroinitializer\n"
356 " %A = select <2 x i1> %1, <2 x float> %a, <2 x float> <float -0.0, float undef>\n"
357 " ret <2 x float> %A\n"
358 "}\n");
359 // An undef in a vector constant can not be back-propagated for this analysis.
Sanjay Patelb98edf72018-10-31 21:11:59 +0000360 expectPattern({SPF_UNKNOWN, SPNB_NA, false});
361}
362
Thomas Livelybbc2ea92018-10-24 22:49:55 +0000363TEST_F(MatchSelectPatternTest, VectorFMinimum) {
Thomas Lively30635bc2018-09-28 21:36:43 +0000364 parseAssembly(
365 "define <4 x float> @test(<4 x float> %a) {\n"
366 " %1 = fcmp ule <4 x float> %a, \n"
367 " <float 5.0, float 5.0, float 5.0, float 5.0>\n"
368 " %A = select <4 x i1> %1, <4 x float> %a,\n"
369 " <4 x float> <float 5.0, float 5.0, float 5.0, float 5.0>\n"
370 " ret <4 x float> %A\n"
371 "}\n");
372 // Check that pattern matching works on vectors where each lane has the same
373 // unordered pattern.
374 expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, false});
375}
376
377TEST_F(MatchSelectPatternTest, VectorFMinOtherOrdered) {
378 parseAssembly(
379 "define <4 x float> @test(<4 x float> %a) {\n"
380 " %1 = fcmp ole <4 x float> %a, \n"
381 " <float 5.0, float 5.0, float 5.0, float 5.0>\n"
382 " %A = select <4 x i1> %1, <4 x float> %a,\n"
383 " <4 x float> <float 5.0, float 5.0, float 5.0, float 5.0>\n"
384 " ret <4 x float> %A\n"
385 "}\n");
386 // Check that pattern matching works on vectors where each lane has the same
387 // ordered pattern.
388 expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, true});
389}
390
Thomas Livelybbc2ea92018-10-24 22:49:55 +0000391TEST_F(MatchSelectPatternTest, VectorNotFMinimum) {
Thomas Lively30635bc2018-09-28 21:36:43 +0000392 parseAssembly(
393 "define <4 x float> @test(<4 x float> %a) {\n"
394 " %1 = fcmp ule <4 x float> %a, \n"
395 " <float 5.0, float 0x7ff8000000000000, float 5.0, float 5.0>\n"
396 " %A = select <4 x i1> %1, <4 x float> %a,\n"
397 " <4 x float> <float 5.0, float 0x7ff8000000000000, float 5.0, float "
398 "5.0>\n"
399 " ret <4 x float> %A\n"
400 "}\n");
401 // The lane that contains a NaN (0x7ff80...) behaves like a
402 // non-NaN-propagating min and the other lines behave like a NaN-propagating
403 // min, so check that neither is returned.
404 expectPattern({SPF_UNKNOWN, SPNB_NA, false});
405}
406
407TEST_F(MatchSelectPatternTest, VectorNotFMinZero) {
408 parseAssembly(
409 "define <4 x float> @test(<4 x float> %a) {\n"
410 " %1 = fcmp ule <4 x float> %a, \n"
411 " <float 5.0, float -0.0, float 5.0, float 5.0>\n"
412 " %A = select <4 x i1> %1, <4 x float> %a,\n"
413 " <4 x float> <float 5.0, float 0.0, float 5.0, float 5.0>\n"
414 " ret <4 x float> %A\n"
415 "}\n");
416 // Always selects the second lane of %a if it is positive or negative zero, so
417 // this is stricter than a min.
418 expectPattern({SPF_UNKNOWN, SPNB_NA, false});
419}
420
James Molloy983cfca2015-09-02 17:25:25 +0000421TEST_F(MatchSelectPatternTest, DoubleCastU) {
422 parseAssembly(
423 "define i32 @test(i8 %a, i8 %b) {\n"
424 " %1 = icmp ult i8 %a, %b\n"
425 " %2 = zext i8 %a to i32\n"
426 " %3 = zext i8 %b to i32\n"
427 " %A = select i1 %1, i32 %2, i32 %3\n"
428 " ret i32 %A\n"
429 "}\n");
430 // We should be able to look through the situation where we cast both operands
431 // to the select.
432 expectPattern({SPF_UMIN, SPNB_NA, false});
433}
434
435TEST_F(MatchSelectPatternTest, DoubleCastS) {
436 parseAssembly(
437 "define i32 @test(i8 %a, i8 %b) {\n"
438 " %1 = icmp slt i8 %a, %b\n"
439 " %2 = sext i8 %a to i32\n"
440 " %3 = sext i8 %b to i32\n"
441 " %A = select i1 %1, i32 %2, i32 %3\n"
442 " ret i32 %A\n"
443 "}\n");
444 // We should be able to look through the situation where we cast both operands
445 // to the select.
446 expectPattern({SPF_SMIN, SPNB_NA, false});
447}
448
449TEST_F(MatchSelectPatternTest, DoubleCastBad) {
450 parseAssembly(
451 "define i32 @test(i8 %a, i8 %b) {\n"
452 " %1 = icmp ult i8 %a, %b\n"
453 " %2 = zext i8 %a to i32\n"
454 " %3 = sext i8 %b to i32\n"
455 " %A = select i1 %1, i32 %2, i32 %3\n"
456 " ret i32 %A\n"
457 "}\n");
James Molloy2616a822015-09-02 17:29:54 +0000458 // The cast types here aren't the same, so we cannot match an UMIN.
James Molloy983cfca2015-09-02 17:25:25 +0000459 expectPattern({SPF_UNKNOWN, SPNB_NA, false});
460}
Sanjoy Dasf67baf02016-12-31 22:12:34 +0000461
462TEST(ValueTracking, GuaranteedToTransferExecutionToSuccessor) {
463 StringRef Assembly =
464 "declare void @nounwind_readonly(i32*) nounwind readonly "
465 "declare void @nounwind_argmemonly(i32*) nounwind argmemonly "
466 "declare void @throws_but_readonly(i32*) readonly "
467 "declare void @throws_but_argmemonly(i32*) argmemonly "
468 " "
469 "declare void @unknown(i32*) "
470 " "
471 "define void @f(i32* %p) { "
472 " call void @nounwind_readonly(i32* %p) "
473 " call void @nounwind_argmemonly(i32* %p) "
474 " call void @throws_but_readonly(i32* %p) "
475 " call void @throws_but_argmemonly(i32* %p) "
476 " call void @unknown(i32* %p) nounwind readonly "
477 " call void @unknown(i32* %p) nounwind argmemonly "
478 " call void @unknown(i32* %p) readonly "
479 " call void @unknown(i32* %p) argmemonly "
480 " ret void "
481 "} ";
482
483 LLVMContext Context;
484 SMDiagnostic Error;
485 auto M = parseAssemblyString(Assembly, Error, Context);
486 assert(M && "Bad assembly?");
487
488 auto *F = M->getFunction("f");
489 assert(F && "Bad assembly?");
490
491 auto &BB = F->getEntryBlock();
Craig Topperb4e05012017-04-14 17:59:19 +0000492 bool ExpectedAnswers[] = {
Sanjoy Dasf67baf02016-12-31 22:12:34 +0000493 true, // call void @nounwind_readonly(i32* %p)
494 true, // call void @nounwind_argmemonly(i32* %p)
495 false, // call void @throws_but_readonly(i32* %p)
496 false, // call void @throws_but_argmemonly(i32* %p)
497 true, // call void @unknown(i32* %p) nounwind readonly
498 true, // call void @unknown(i32* %p) nounwind argmemonly
499 false, // call void @unknown(i32* %p) readonly
500 false, // call void @unknown(i32* %p) argmemonly
501 false, // ret void
502 };
503
504 int Index = 0;
505 for (auto &I : BB) {
506 EXPECT_EQ(isGuaranteedToTransferExecutionToSuccessor(&I),
507 ExpectedAnswers[Index])
508 << "Incorrect answer at instruction " << Index << " = " << I;
509 Index++;
510 }
511}
Sanjoy Das9b2526d2017-02-25 20:30:45 +0000512
Nikita Popovc16c6e62018-11-30 22:22:30 +0000513TEST_F(ValueTrackingTest, ComputeNumSignBits_PR32045) {
514 parseAssembly(
515 "define i32 @test(i32 %a) {\n"
516 " %A = ashr i32 %a, -1\n"
517 " ret i32 %A\n"
518 "}\n");
519 EXPECT_EQ(ComputeNumSignBits(A, M->getDataLayout()), 1u);
Sanjoy Das9b2526d2017-02-25 20:30:45 +0000520}
Simon Dardis1134b2a2017-12-09 23:25:57 +0000521
Sanjay Patel67093482018-11-02 15:51:47 +0000522// No guarantees for canonical IR in this analysis, so this just bails out.
Nikita Popovc16c6e62018-11-30 22:22:30 +0000523TEST_F(ValueTrackingTest, ComputeNumSignBits_Shuffle) {
524 parseAssembly(
525 "define <2 x i32> @test() {\n"
526 " %A = shufflevector <2 x i32> undef, <2 x i32> undef, <2 x i32> <i32 0, i32 0>\n"
527 " ret <2 x i32> %A\n"
528 "}\n");
529 EXPECT_EQ(ComputeNumSignBits(A, M->getDataLayout()), 1u);
Sanjay Patel67093482018-11-02 15:51:47 +0000530}
531
Sanjay Patel6892afb2018-11-02 18:14:24 +0000532// No guarantees for canonical IR in this analysis, so a shuffle element that
533// references an undef value means this can't return any extra information.
Nikita Popovc16c6e62018-11-30 22:22:30 +0000534TEST_F(ValueTrackingTest, ComputeNumSignBits_Shuffle2) {
535 parseAssembly(
536 "define <2 x i32> @test(<2 x i1> %x) {\n"
537 " %sext = sext <2 x i1> %x to <2 x i32>\n"
538 " %A = shufflevector <2 x i32> %sext, <2 x i32> undef, <2 x i32> <i32 0, i32 2>\n"
539 " ret <2 x i32> %A\n"
540 "}\n");
541 EXPECT_EQ(ComputeNumSignBits(A, M->getDataLayout()), 1u);
Sanjay Patel6892afb2018-11-02 18:14:24 +0000542}
543
Nikita Popovc16c6e62018-11-30 22:22:30 +0000544TEST_F(ComputeKnownBitsTest, ComputeKnownBits) {
545 parseAssembly(
546 "define i32 @test(i32 %a, i32 %b) {\n"
547 " %ash = mul i32 %a, 8\n"
548 " %aad = add i32 %ash, 7\n"
549 " %aan = and i32 %aad, 4095\n"
550 " %bsh = shl i32 %b, 4\n"
551 " %bad = or i32 %bsh, 6\n"
552 " %ban = and i32 %bad, 4095\n"
553 " %A = mul i32 %aan, %ban\n"
554 " ret i32 %A\n"
555 "}\n");
556 expectKnownBits(/*zero*/ 4278190085u, /*one*/ 10u);
Simon Dardis1134b2a2017-12-09 23:25:57 +0000557}
558
Nikita Popovc16c6e62018-11-30 22:22:30 +0000559TEST_F(ComputeKnownBitsTest, ComputeKnownMulBits) {
560 parseAssembly(
561 "define i32 @test(i32 %a, i32 %b) {\n"
562 " %aa = shl i32 %a, 5\n"
563 " %bb = shl i32 %b, 5\n"
564 " %aaa = or i32 %aa, 24\n"
565 " %bbb = or i32 %bb, 28\n"
566 " %A = mul i32 %aaa, %bbb\n"
567 " ret i32 %A\n"
568 "}\n");
569 expectKnownBits(/*zero*/ 95u, /*one*/ 32u);
Simon Dardis1134b2a2017-12-09 23:25:57 +0000570}
Nikita Popov90548322018-12-02 14:14:11 +0000571
572TEST_F(ComputeKnownBitsTest, ComputeKnownFshl) {
573 // fshl(....1111....0000, 00..1111........, 6)
574 // = 11....000000..11
575 parseAssembly(
576 "define i16 @test(i16 %a, i16 %b) {\n"
577 " %aa = shl i16 %a, 4\n"
578 " %bb = lshr i16 %b, 2\n"
579 " %aaa = or i16 %aa, 3840\n"
580 " %bbb = or i16 %bb, 3840\n"
581 " %A = call i16 @llvm.fshl.i16(i16 %aaa, i16 %bbb, i16 6)\n"
582 " ret i16 %A\n"
583 "}\n"
584 "declare i16 @llvm.fshl.i16(i16, i16, i16)\n");
585 expectKnownBits(/*zero*/ 1008u, /*one*/ 49155u);
586}
587
588TEST_F(ComputeKnownBitsTest, ComputeKnownFshr) {
589 // fshr(....1111....0000, 00..1111........, 26)
590 // = 11....000000..11
591 parseAssembly(
592 "define i16 @test(i16 %a, i16 %b) {\n"
593 " %aa = shl i16 %a, 4\n"
594 " %bb = lshr i16 %b, 2\n"
595 " %aaa = or i16 %aa, 3840\n"
596 " %bbb = or i16 %bb, 3840\n"
597 " %A = call i16 @llvm.fshr.i16(i16 %aaa, i16 %bbb, i16 26)\n"
598 " ret i16 %A\n"
599 "}\n"
600 "declare i16 @llvm.fshr.i16(i16, i16, i16)\n");
601 expectKnownBits(/*zero*/ 1008u, /*one*/ 49155u);
602}
603
604TEST_F(ComputeKnownBitsTest, ComputeKnownFshlZero) {
605 // fshl(....1111....0000, 00..1111........, 0)
606 // = ....1111....0000
607 parseAssembly(
608 "define i16 @test(i16 %a, i16 %b) {\n"
609 " %aa = shl i16 %a, 4\n"
610 " %bb = lshr i16 %b, 2\n"
611 " %aaa = or i16 %aa, 3840\n"
612 " %bbb = or i16 %bb, 3840\n"
613 " %A = call i16 @llvm.fshl.i16(i16 %aaa, i16 %bbb, i16 0)\n"
614 " ret i16 %A\n"
615 "}\n"
616 "declare i16 @llvm.fshl.i16(i16, i16, i16)\n");
617 expectKnownBits(/*zero*/ 15u, /*one*/ 3840u);
618}