Revert r354244 "[DAGCombiner] Eliminate dead stores to stack."
[llvm-complete.git] / unittests / Analysis / ValueTrackingTest.cpp
bloba0f5aed2b6d97b63d2141ccf0aab3d4775a676a5
1 //===- ValueTrackingTest.cpp - ValueTracking 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 //===----------------------------------------------------------------------===//
9 #include "llvm/Analysis/ValueTracking.h"
10 #include "llvm/AsmParser/Parser.h"
11 #include "llvm/IR/Function.h"
12 #include "llvm/IR/InstIterator.h"
13 #include "llvm/IR/LLVMContext.h"
14 #include "llvm/IR/Module.h"
15 #include "llvm/Support/ErrorHandling.h"
16 #include "llvm/Support/SourceMgr.h"
17 #include "llvm/Support/KnownBits.h"
18 #include "gtest/gtest.h"
20 using namespace llvm;
22 namespace {
24 class ValueTrackingTest : public testing::Test {
25 protected:
26 void parseAssembly(const char *Assembly) {
27 SMDiagnostic Error;
28 M = parseAssemblyString(Assembly, Error, Context);
30 std::string errMsg;
31 raw_string_ostream os(errMsg);
32 Error.print("", os);
34 // A failure here means that the test itself is buggy.
35 if (!M)
36 report_fatal_error(os.str());
38 Function *F = M->getFunction("test");
39 if (F == nullptr)
40 report_fatal_error("Test must have a function named @test");
42 A = nullptr;
43 for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
44 if (I->hasName()) {
45 if (I->getName() == "A")
46 A = &*I;
49 if (A == nullptr)
50 report_fatal_error("@test must have an instruction %A");
53 LLVMContext Context;
54 std::unique_ptr<Module> M;
55 Instruction *A;
58 class MatchSelectPatternTest : public ValueTrackingTest {
59 protected:
60 void expectPattern(const SelectPatternResult &P) {
61 Value *LHS, *RHS;
62 Instruction::CastOps CastOp;
63 SelectPatternResult R = matchSelectPattern(A, LHS, RHS, &CastOp);
64 EXPECT_EQ(P.Flavor, R.Flavor);
65 EXPECT_EQ(P.NaNBehavior, R.NaNBehavior);
66 EXPECT_EQ(P.Ordered, R.Ordered);
70 class ComputeKnownBitsTest : public ValueTrackingTest {
71 protected:
72 void expectKnownBits(uint64_t Zero, uint64_t One) {
73 auto Known = computeKnownBits(A, M->getDataLayout());
74 ASSERT_FALSE(Known.hasConflict());
75 EXPECT_EQ(Known.One.getZExtValue(), One);
76 EXPECT_EQ(Known.Zero.getZExtValue(), Zero);
82 TEST_F(MatchSelectPatternTest, SimpleFMin) {
83 parseAssembly(
84 "define float @test(float %a) {\n"
85 " %1 = fcmp ult float %a, 5.0\n"
86 " %A = select i1 %1, float %a, float 5.0\n"
87 " ret float %A\n"
88 "}\n");
89 expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, false});
92 TEST_F(MatchSelectPatternTest, SimpleFMax) {
93 parseAssembly(
94 "define float @test(float %a) {\n"
95 " %1 = fcmp ogt float %a, 5.0\n"
96 " %A = select i1 %1, float %a, float 5.0\n"
97 " ret float %A\n"
98 "}\n");
99 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, true});
102 TEST_F(MatchSelectPatternTest, SwappedFMax) {
103 parseAssembly(
104 "define float @test(float %a) {\n"
105 " %1 = fcmp olt float 5.0, %a\n"
106 " %A = select i1 %1, float %a, float 5.0\n"
107 " ret float %A\n"
108 "}\n");
109 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, false});
112 TEST_F(MatchSelectPatternTest, SwappedFMax2) {
113 parseAssembly(
114 "define float @test(float %a) {\n"
115 " %1 = fcmp olt float %a, 5.0\n"
116 " %A = select i1 %1, float 5.0, float %a\n"
117 " ret float %A\n"
118 "}\n");
119 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_NAN, false});
122 TEST_F(MatchSelectPatternTest, SwappedFMax3) {
123 parseAssembly(
124 "define float @test(float %a) {\n"
125 " %1 = fcmp ult float %a, 5.0\n"
126 " %A = select i1 %1, float 5.0, float %a\n"
127 " ret float %A\n"
128 "}\n");
129 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, true});
132 TEST_F(MatchSelectPatternTest, FastFMin) {
133 parseAssembly(
134 "define float @test(float %a) {\n"
135 " %1 = fcmp nnan olt float %a, 5.0\n"
136 " %A = select i1 %1, float %a, float 5.0\n"
137 " ret float %A\n"
138 "}\n");
139 expectPattern({SPF_FMINNUM, SPNB_RETURNS_ANY, false});
142 TEST_F(MatchSelectPatternTest, FMinConstantZero) {
143 parseAssembly(
144 "define float @test(float %a) {\n"
145 " %1 = fcmp ole float %a, 0.0\n"
146 " %A = select i1 %1, float %a, float 0.0\n"
147 " ret float %A\n"
148 "}\n");
149 // This shouldn't be matched, as %a could be -0.0.
150 expectPattern({SPF_UNKNOWN, SPNB_NA, false});
153 TEST_F(MatchSelectPatternTest, FMinConstantZeroNsz) {
154 parseAssembly(
155 "define float @test(float %a) {\n"
156 " %1 = fcmp nsz ole float %a, 0.0\n"
157 " %A = select i1 %1, float %a, float 0.0\n"
158 " ret float %A\n"
159 "}\n");
160 // But this should be, because we've ignored signed zeroes.
161 expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, true});
164 TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero1) {
165 parseAssembly(
166 "define float @test(float %a) {\n"
167 " %1 = fcmp olt float -0.0, %a\n"
168 " %A = select i1 %1, float 0.0, float %a\n"
169 " ret float %A\n"
170 "}\n");
171 // The sign of zero doesn't matter in fcmp.
172 expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, true});
175 TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero2) {
176 parseAssembly(
177 "define float @test(float %a) {\n"
178 " %1 = fcmp ogt float %a, -0.0\n"
179 " %A = select i1 %1, float 0.0, float %a\n"
180 " ret float %A\n"
181 "}\n");
182 // The sign of zero doesn't matter in fcmp.
183 expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, false});
186 TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero3) {
187 parseAssembly(
188 "define float @test(float %a) {\n"
189 " %1 = fcmp olt float 0.0, %a\n"
190 " %A = select i1 %1, float -0.0, float %a\n"
191 " ret float %A\n"
192 "}\n");
193 // The sign of zero doesn't matter in fcmp.
194 expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, true});
197 TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero4) {
198 parseAssembly(
199 "define float @test(float %a) {\n"
200 " %1 = fcmp ogt float %a, 0.0\n"
201 " %A = select i1 %1, float -0.0, float %a\n"
202 " ret float %A\n"
203 "}\n");
204 // The sign of zero doesn't matter in fcmp.
205 expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, false});
208 TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero5) {
209 parseAssembly(
210 "define float @test(float %a) {\n"
211 " %1 = fcmp ogt float -0.0, %a\n"
212 " %A = select i1 %1, float %a, float 0.0\n"
213 " ret float %A\n"
214 "}\n");
215 // The sign of zero doesn't matter in fcmp.
216 expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, false});
219 TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero6) {
220 parseAssembly(
221 "define float @test(float %a) {\n"
222 " %1 = fcmp olt float %a, -0.0\n"
223 " %A = select i1 %1, float %a, float 0.0\n"
224 " ret float %A\n"
225 "}\n");
226 // The sign of zero doesn't matter in fcmp.
227 expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, true});
230 TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero7) {
231 parseAssembly(
232 "define float @test(float %a) {\n"
233 " %1 = fcmp ogt float 0.0, %a\n"
234 " %A = select i1 %1, float %a, float -0.0\n"
235 " ret float %A\n"
236 "}\n");
237 // The sign of zero doesn't matter in fcmp.
238 expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, false});
241 TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero8) {
242 parseAssembly(
243 "define float @test(float %a) {\n"
244 " %1 = fcmp olt float %a, 0.0\n"
245 " %A = select i1 %1, float %a, float -0.0\n"
246 " ret float %A\n"
247 "}\n");
248 // The sign of zero doesn't matter in fcmp.
249 expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, true});
252 TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero1) {
253 parseAssembly(
254 "define float @test(float %a) {\n"
255 " %1 = fcmp ogt float -0.0, %a\n"
256 " %A = select i1 %1, float 0.0, float %a\n"
257 " ret float %A\n"
258 "}\n");
259 // The sign of zero doesn't matter in fcmp.
260 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_NAN, true});
263 TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero2) {
264 parseAssembly(
265 "define float @test(float %a) {\n"
266 " %1 = fcmp olt float %a, -0.0\n"
267 " %A = select i1 %1, float 0.0, float %a\n"
268 " ret float %A\n"
269 "}\n");
270 // The sign of zero doesn't matter in fcmp.
271 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_NAN, false});
274 TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero3) {
275 parseAssembly(
276 "define float @test(float %a) {\n"
277 " %1 = fcmp ogt float 0.0, %a\n"
278 " %A = select i1 %1, float -0.0, float %a\n"
279 " ret float %A\n"
280 "}\n");
281 // The sign of zero doesn't matter in fcmp.
282 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_NAN, true});
285 TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero4) {
286 parseAssembly(
287 "define float @test(float %a) {\n"
288 " %1 = fcmp olt float %a, 0.0\n"
289 " %A = select i1 %1, float -0.0, float %a\n"
290 " ret float %A\n"
291 "}\n");
292 // The sign of zero doesn't matter in fcmp.
293 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_NAN, false});
296 TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero5) {
297 parseAssembly(
298 "define float @test(float %a) {\n"
299 " %1 = fcmp olt float -0.0, %a\n"
300 " %A = select i1 %1, float %a, float 0.0\n"
301 " ret float %A\n"
302 "}\n");
303 // The sign of zero doesn't matter in fcmp.
304 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, false});
307 TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero6) {
308 parseAssembly(
309 "define float @test(float %a) {\n"
310 " %1 = fcmp ogt float %a, -0.0\n"
311 " %A = select i1 %1, float %a, float 0.0\n"
312 " ret float %A\n"
313 "}\n");
314 // The sign of zero doesn't matter in fcmp.
315 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, true});
318 TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero7) {
319 parseAssembly(
320 "define float @test(float %a) {\n"
321 " %1 = fcmp olt float 0.0, %a\n"
322 " %A = select i1 %1, float %a, float -0.0\n"
323 " ret float %A\n"
324 "}\n");
325 // The sign of zero doesn't matter in fcmp.
326 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, false});
329 TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero8) {
330 parseAssembly(
331 "define float @test(float %a) {\n"
332 " %1 = fcmp ogt float %a, 0.0\n"
333 " %A = select i1 %1, float %a, float -0.0\n"
334 " ret float %A\n"
335 "}\n");
336 // The sign of zero doesn't matter in fcmp.
337 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, true});
340 TEST_F(MatchSelectPatternTest, FMinMismatchConstantZeroVecUndef) {
341 parseAssembly(
342 "define <2 x float> @test(<2 x float> %a) {\n"
343 " %1 = fcmp ogt <2 x float> %a, <float -0.0, float -0.0>\n"
344 " %A = select <2 x i1> %1, <2 x float> <float undef, float 0.0>, <2 x float> %a\n"
345 " ret <2 x float> %A\n"
346 "}\n");
347 // An undef in a vector constant can not be back-propagated for this analysis.
348 expectPattern({SPF_UNKNOWN, SPNB_NA, false});
351 TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZeroVecUndef) {
352 parseAssembly(
353 "define <2 x float> @test(<2 x float> %a) {\n"
354 " %1 = fcmp ogt <2 x float> %a, zeroinitializer\n"
355 " %A = select <2 x i1> %1, <2 x float> %a, <2 x float> <float -0.0, float undef>\n"
356 " ret <2 x float> %A\n"
357 "}\n");
358 // An undef in a vector constant can not be back-propagated for this analysis.
359 expectPattern({SPF_UNKNOWN, SPNB_NA, false});
362 TEST_F(MatchSelectPatternTest, VectorFMinimum) {
363 parseAssembly(
364 "define <4 x float> @test(<4 x float> %a) {\n"
365 " %1 = fcmp ule <4 x float> %a, \n"
366 " <float 5.0, float 5.0, float 5.0, float 5.0>\n"
367 " %A = select <4 x i1> %1, <4 x float> %a,\n"
368 " <4 x float> <float 5.0, float 5.0, float 5.0, float 5.0>\n"
369 " ret <4 x float> %A\n"
370 "}\n");
371 // Check that pattern matching works on vectors where each lane has the same
372 // unordered pattern.
373 expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, false});
376 TEST_F(MatchSelectPatternTest, VectorFMinOtherOrdered) {
377 parseAssembly(
378 "define <4 x float> @test(<4 x float> %a) {\n"
379 " %1 = fcmp ole <4 x float> %a, \n"
380 " <float 5.0, float 5.0, float 5.0, float 5.0>\n"
381 " %A = select <4 x i1> %1, <4 x float> %a,\n"
382 " <4 x float> <float 5.0, float 5.0, float 5.0, float 5.0>\n"
383 " ret <4 x float> %A\n"
384 "}\n");
385 // Check that pattern matching works on vectors where each lane has the same
386 // ordered pattern.
387 expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, true});
390 TEST_F(MatchSelectPatternTest, VectorNotFMinimum) {
391 parseAssembly(
392 "define <4 x float> @test(<4 x float> %a) {\n"
393 " %1 = fcmp ule <4 x float> %a, \n"
394 " <float 5.0, float 0x7ff8000000000000, float 5.0, float 5.0>\n"
395 " %A = select <4 x i1> %1, <4 x float> %a,\n"
396 " <4 x float> <float 5.0, float 0x7ff8000000000000, float 5.0, float "
397 "5.0>\n"
398 " ret <4 x float> %A\n"
399 "}\n");
400 // The lane that contains a NaN (0x7ff80...) behaves like a
401 // non-NaN-propagating min and the other lines behave like a NaN-propagating
402 // min, so check that neither is returned.
403 expectPattern({SPF_UNKNOWN, SPNB_NA, false});
406 TEST_F(MatchSelectPatternTest, VectorNotFMinZero) {
407 parseAssembly(
408 "define <4 x float> @test(<4 x float> %a) {\n"
409 " %1 = fcmp ule <4 x float> %a, \n"
410 " <float 5.0, float -0.0, float 5.0, float 5.0>\n"
411 " %A = select <4 x i1> %1, <4 x float> %a,\n"
412 " <4 x float> <float 5.0, float 0.0, float 5.0, float 5.0>\n"
413 " ret <4 x float> %A\n"
414 "}\n");
415 // Always selects the second lane of %a if it is positive or negative zero, so
416 // this is stricter than a min.
417 expectPattern({SPF_UNKNOWN, SPNB_NA, false});
420 TEST_F(MatchSelectPatternTest, DoubleCastU) {
421 parseAssembly(
422 "define i32 @test(i8 %a, i8 %b) {\n"
423 " %1 = icmp ult i8 %a, %b\n"
424 " %2 = zext i8 %a to i32\n"
425 " %3 = zext i8 %b to i32\n"
426 " %A = select i1 %1, i32 %2, i32 %3\n"
427 " ret i32 %A\n"
428 "}\n");
429 // We should be able to look through the situation where we cast both operands
430 // to the select.
431 expectPattern({SPF_UMIN, SPNB_NA, false});
434 TEST_F(MatchSelectPatternTest, DoubleCastS) {
435 parseAssembly(
436 "define i32 @test(i8 %a, i8 %b) {\n"
437 " %1 = icmp slt i8 %a, %b\n"
438 " %2 = sext i8 %a to i32\n"
439 " %3 = sext i8 %b to i32\n"
440 " %A = select i1 %1, i32 %2, i32 %3\n"
441 " ret i32 %A\n"
442 "}\n");
443 // We should be able to look through the situation where we cast both operands
444 // to the select.
445 expectPattern({SPF_SMIN, SPNB_NA, false});
448 TEST_F(MatchSelectPatternTest, DoubleCastBad) {
449 parseAssembly(
450 "define i32 @test(i8 %a, i8 %b) {\n"
451 " %1 = icmp ult i8 %a, %b\n"
452 " %2 = zext i8 %a to i32\n"
453 " %3 = sext i8 %b to i32\n"
454 " %A = select i1 %1, i32 %2, i32 %3\n"
455 " ret i32 %A\n"
456 "}\n");
457 // The cast types here aren't the same, so we cannot match an UMIN.
458 expectPattern({SPF_UNKNOWN, SPNB_NA, false});
461 TEST(ValueTracking, GuaranteedToTransferExecutionToSuccessor) {
462 StringRef Assembly =
463 "declare void @nounwind_readonly(i32*) nounwind readonly "
464 "declare void @nounwind_argmemonly(i32*) nounwind argmemonly "
465 "declare void @throws_but_readonly(i32*) readonly "
466 "declare void @throws_but_argmemonly(i32*) argmemonly "
468 "declare void @unknown(i32*) "
470 "define void @f(i32* %p) { "
471 " call void @nounwind_readonly(i32* %p) "
472 " call void @nounwind_argmemonly(i32* %p) "
473 " call void @throws_but_readonly(i32* %p) "
474 " call void @throws_but_argmemonly(i32* %p) "
475 " call void @unknown(i32* %p) nounwind readonly "
476 " call void @unknown(i32* %p) nounwind argmemonly "
477 " call void @unknown(i32* %p) readonly "
478 " call void @unknown(i32* %p) argmemonly "
479 " ret void "
480 "} ";
482 LLVMContext Context;
483 SMDiagnostic Error;
484 auto M = parseAssemblyString(Assembly, Error, Context);
485 assert(M && "Bad assembly?");
487 auto *F = M->getFunction("f");
488 assert(F && "Bad assembly?");
490 auto &BB = F->getEntryBlock();
491 bool ExpectedAnswers[] = {
492 true, // call void @nounwind_readonly(i32* %p)
493 true, // call void @nounwind_argmemonly(i32* %p)
494 false, // call void @throws_but_readonly(i32* %p)
495 false, // call void @throws_but_argmemonly(i32* %p)
496 true, // call void @unknown(i32* %p) nounwind readonly
497 true, // call void @unknown(i32* %p) nounwind argmemonly
498 false, // call void @unknown(i32* %p) readonly
499 false, // call void @unknown(i32* %p) argmemonly
500 false, // ret void
503 int Index = 0;
504 for (auto &I : BB) {
505 EXPECT_EQ(isGuaranteedToTransferExecutionToSuccessor(&I),
506 ExpectedAnswers[Index])
507 << "Incorrect answer at instruction " << Index << " = " << I;
508 Index++;
512 TEST_F(ValueTrackingTest, ComputeNumSignBits_PR32045) {
513 parseAssembly(
514 "define i32 @test(i32 %a) {\n"
515 " %A = ashr i32 %a, -1\n"
516 " ret i32 %A\n"
517 "}\n");
518 EXPECT_EQ(ComputeNumSignBits(A, M->getDataLayout()), 1u);
521 // No guarantees for canonical IR in this analysis, so this just bails out.
522 TEST_F(ValueTrackingTest, ComputeNumSignBits_Shuffle) {
523 parseAssembly(
524 "define <2 x i32> @test() {\n"
525 " %A = shufflevector <2 x i32> undef, <2 x i32> undef, <2 x i32> <i32 0, i32 0>\n"
526 " ret <2 x i32> %A\n"
527 "}\n");
528 EXPECT_EQ(ComputeNumSignBits(A, M->getDataLayout()), 1u);
531 // No guarantees for canonical IR in this analysis, so a shuffle element that
532 // references an undef value means this can't return any extra information.
533 TEST_F(ValueTrackingTest, ComputeNumSignBits_Shuffle2) {
534 parseAssembly(
535 "define <2 x i32> @test(<2 x i1> %x) {\n"
536 " %sext = sext <2 x i1> %x to <2 x i32>\n"
537 " %A = shufflevector <2 x i32> %sext, <2 x i32> undef, <2 x i32> <i32 0, i32 2>\n"
538 " ret <2 x i32> %A\n"
539 "}\n");
540 EXPECT_EQ(ComputeNumSignBits(A, M->getDataLayout()), 1u);
543 TEST_F(ComputeKnownBitsTest, ComputeKnownBits) {
544 parseAssembly(
545 "define i32 @test(i32 %a, i32 %b) {\n"
546 " %ash = mul i32 %a, 8\n"
547 " %aad = add i32 %ash, 7\n"
548 " %aan = and i32 %aad, 4095\n"
549 " %bsh = shl i32 %b, 4\n"
550 " %bad = or i32 %bsh, 6\n"
551 " %ban = and i32 %bad, 4095\n"
552 " %A = mul i32 %aan, %ban\n"
553 " ret i32 %A\n"
554 "}\n");
555 expectKnownBits(/*zero*/ 4278190085u, /*one*/ 10u);
558 TEST_F(ComputeKnownBitsTest, ComputeKnownMulBits) {
559 parseAssembly(
560 "define i32 @test(i32 %a, i32 %b) {\n"
561 " %aa = shl i32 %a, 5\n"
562 " %bb = shl i32 %b, 5\n"
563 " %aaa = or i32 %aa, 24\n"
564 " %bbb = or i32 %bb, 28\n"
565 " %A = mul i32 %aaa, %bbb\n"
566 " ret i32 %A\n"
567 "}\n");
568 expectKnownBits(/*zero*/ 95u, /*one*/ 32u);
571 TEST_F(ComputeKnownBitsTest, ComputeKnownFshl) {
572 // fshl(....1111....0000, 00..1111........, 6)
573 // = 11....000000..11
574 parseAssembly(
575 "define i16 @test(i16 %a, i16 %b) {\n"
576 " %aa = shl i16 %a, 4\n"
577 " %bb = lshr i16 %b, 2\n"
578 " %aaa = or i16 %aa, 3840\n"
579 " %bbb = or i16 %bb, 3840\n"
580 " %A = call i16 @llvm.fshl.i16(i16 %aaa, i16 %bbb, i16 6)\n"
581 " ret i16 %A\n"
582 "}\n"
583 "declare i16 @llvm.fshl.i16(i16, i16, i16)\n");
584 expectKnownBits(/*zero*/ 1008u, /*one*/ 49155u);
587 TEST_F(ComputeKnownBitsTest, ComputeKnownFshr) {
588 // fshr(....1111....0000, 00..1111........, 26)
589 // = 11....000000..11
590 parseAssembly(
591 "define i16 @test(i16 %a, i16 %b) {\n"
592 " %aa = shl i16 %a, 4\n"
593 " %bb = lshr i16 %b, 2\n"
594 " %aaa = or i16 %aa, 3840\n"
595 " %bbb = or i16 %bb, 3840\n"
596 " %A = call i16 @llvm.fshr.i16(i16 %aaa, i16 %bbb, i16 26)\n"
597 " ret i16 %A\n"
598 "}\n"
599 "declare i16 @llvm.fshr.i16(i16, i16, i16)\n");
600 expectKnownBits(/*zero*/ 1008u, /*one*/ 49155u);
603 TEST_F(ComputeKnownBitsTest, ComputeKnownFshlZero) {
604 // fshl(....1111....0000, 00..1111........, 0)
605 // = ....1111....0000
606 parseAssembly(
607 "define i16 @test(i16 %a, i16 %b) {\n"
608 " %aa = shl i16 %a, 4\n"
609 " %bb = lshr i16 %b, 2\n"
610 " %aaa = or i16 %aa, 3840\n"
611 " %bbb = or i16 %bb, 3840\n"
612 " %A = call i16 @llvm.fshl.i16(i16 %aaa, i16 %bbb, i16 0)\n"
613 " ret i16 %A\n"
614 "}\n"
615 "declare i16 @llvm.fshl.i16(i16, i16, i16)\n");
616 expectKnownBits(/*zero*/ 15u, /*one*/ 3840u);