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 MatchSelectPatternTest : 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 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 63 LLVMContext Context; 64 std::unique_ptr<Module> M; 65 Instruction *A, *B; 66 }; 67 68 } 69 70 TEST_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 80 TEST_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 90 TEST_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 100 TEST_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 110 TEST_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 120 TEST_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 130 TEST_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 141 TEST_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 } 151 152 TEST_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"); 159 // The sign of zero doesn't matter in fcmp. 160 expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, true}); 161 } 162 163 TEST_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"); 170 // The sign of zero doesn't matter in fcmp. 171 expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, false}); 172 } 173 174 TEST_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"); 181 // The sign of zero doesn't matter in fcmp. 182 expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, true}); 183 } 184 185 TEST_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"); 192 // The sign of zero doesn't matter in fcmp. 193 expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, false}); 194 } 195 196 TEST_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"); 203 // The sign of zero doesn't matter in fcmp. 204 expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, false}); 205 } 206 207 TEST_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"); 214 // The sign of zero doesn't matter in fcmp. 215 expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, true}); 216 } 217 218 TEST_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"); 225 // The sign of zero doesn't matter in fcmp. 226 expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, false}); 227 } 228 229 TEST_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"); 236 // The sign of zero doesn't matter in fcmp. 237 expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, true}); 238 } 239 240 TEST_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"); 247 // The sign of zero doesn't matter in fcmp. 248 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_NAN, true}); 249 } 250 251 TEST_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"); 258 // The sign of zero doesn't matter in fcmp. 259 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_NAN, false}); 260 } 261 262 TEST_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"); 269 // The sign of zero doesn't matter in fcmp. 270 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_NAN, true}); 271 } 272 273 TEST_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"); 280 // The sign of zero doesn't matter in fcmp. 281 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_NAN, false}); 282 } 283 284 TEST_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"); 291 // The sign of zero doesn't matter in fcmp. 292 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, false}); 293 } 294 295 TEST_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"); 302 // The sign of zero doesn't matter in fcmp. 303 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, true}); 304 } 305 306 TEST_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"); 313 // The sign of zero doesn't matter in fcmp. 314 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, false}); 315 } 316 317 TEST_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"); 324 // The sign of zero doesn't matter in fcmp. 325 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, true}); 326 } 327 328 TEST_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 339 TEST_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. 347 expectPattern({SPF_UNKNOWN, SPNB_NA, false}); 348 } 349 350 TEST_F(MatchSelectPatternTest, VectorFMinimum) { 351 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 364 TEST_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 378 TEST_F(MatchSelectPatternTest, VectorNotFMinimum) { 379 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 394 TEST_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 408 TEST_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 422 TEST_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 436 TEST_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"); 445 // The cast types here aren't the same, so we cannot match an UMIN. 446 expectPattern({SPF_UNKNOWN, SPNB_NA, false}); 447 } 448 449 TEST(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(); 479 bool ExpectedAnswers[] = { 480 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 } 499 500 TEST(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); 516 EXPECT_EQ(ComputeNumSignBits(RVal, M->getDataLayout()), 1u); 517 } 518 519 // No guarantees for canonical IR in this analysis, so this just bails out. 520 TEST(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 539 // 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. 541 TEST(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); 558 EXPECT_EQ(ComputeNumSignBits(RVal, M->getDataLayout()), 1u); 559 } 560 561 TEST(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 589 TEST(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 } 614