1 //===- 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"
18 #include "llvm/Support/KnownBits.h"
19 #include "gtest/gtest.h"
20 
21 using namespace llvm;
22 
23 namespace {
24 
25 class ValueTrackingTest : public testing::Test {
26 protected:
27   void parseAssembly(const char *Assembly) {
28     SMDiagnostic Error;
29     M = parseAssemblyString(Assembly, Error, Context);
30 
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   LLVMContext Context;
55   std::unique_ptr<Module> M;
56   Instruction *A;
57 };
58 
59 class MatchSelectPatternTest : public ValueTrackingTest {
60 protected:
61   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   }
69 };
70 
71 class ComputeKnownBitsTest : public ValueTrackingTest {
72 protected:
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   }
79 };
80 
81 }
82 
83 TEST_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 
93 TEST_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 
103 TEST_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 
113 TEST_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 
123 TEST_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 
133 TEST_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 
143 TEST_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 
154 TEST_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 }
164 
165 TEST_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");
172   // The sign of zero doesn't matter in fcmp.
173   expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, true});
174 }
175 
176 TEST_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");
183   // The sign of zero doesn't matter in fcmp.
184   expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, false});
185 }
186 
187 TEST_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");
194   // The sign of zero doesn't matter in fcmp.
195   expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, true});
196 }
197 
198 TEST_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");
205   // The sign of zero doesn't matter in fcmp.
206   expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, false});
207 }
208 
209 TEST_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");
216   // The sign of zero doesn't matter in fcmp.
217   expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, false});
218 }
219 
220 TEST_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");
227   // The sign of zero doesn't matter in fcmp.
228   expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, true});
229 }
230 
231 TEST_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");
238   // The sign of zero doesn't matter in fcmp.
239   expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, false});
240 }
241 
242 TEST_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");
249   // The sign of zero doesn't matter in fcmp.
250   expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, true});
251 }
252 
253 TEST_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");
260   // The sign of zero doesn't matter in fcmp.
261   expectPattern({SPF_FMAXNUM, SPNB_RETURNS_NAN, true});
262 }
263 
264 TEST_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");
271   // The sign of zero doesn't matter in fcmp.
272   expectPattern({SPF_FMAXNUM, SPNB_RETURNS_NAN, false});
273 }
274 
275 TEST_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");
282   // The sign of zero doesn't matter in fcmp.
283   expectPattern({SPF_FMAXNUM, SPNB_RETURNS_NAN, true});
284 }
285 
286 TEST_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");
293   // The sign of zero doesn't matter in fcmp.
294   expectPattern({SPF_FMAXNUM, SPNB_RETURNS_NAN, false});
295 }
296 
297 TEST_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");
304   // The sign of zero doesn't matter in fcmp.
305   expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, false});
306 }
307 
308 TEST_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");
315   // The sign of zero doesn't matter in fcmp.
316   expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, true});
317 }
318 
319 TEST_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");
326   // The sign of zero doesn't matter in fcmp.
327   expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, false});
328 }
329 
330 TEST_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");
337   // The sign of zero doesn't matter in fcmp.
338   expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, true});
339 }
340 
341 TEST_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 
352 TEST_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.
360   expectPattern({SPF_UNKNOWN, SPNB_NA, false});
361 }
362 
363 TEST_F(MatchSelectPatternTest, VectorFMinimum) {
364   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 
377 TEST_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 
391 TEST_F(MatchSelectPatternTest, VectorNotFMinimum) {
392   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 
407 TEST_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 
421 TEST_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 
435 TEST_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 
449 TEST_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");
458   // The cast types here aren't the same, so we cannot match an UMIN.
459   expectPattern({SPF_UNKNOWN, SPNB_NA, false});
460 }
461 
462 TEST(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();
492   bool ExpectedAnswers[] = {
493       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 }
512 
513 TEST_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);
520 }
521 
522 // No guarantees for canonical IR in this analysis, so this just bails out.
523 TEST_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);
530 }
531 
532 // 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.
534 TEST_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);
542 }
543 
544 TEST_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);
557 }
558 
559 TEST_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);
570 }
571 
572 TEST_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 
588 TEST_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 
604 TEST_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 }
619