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 //===----------------------------------------------------------------------===// 8 9 #include "llvm/Analysis/ValueTracking.h" 10 #include "llvm/Analysis/AssumptionCache.h" 11 #include "llvm/AsmParser/Parser.h" 12 #include "llvm/IR/ConstantRange.h" 13 #include "llvm/IR/Dominators.h" 14 #include "llvm/IR/Function.h" 15 #include "llvm/IR/IRBuilder.h" 16 #include "llvm/IR/InstIterator.h" 17 #include "llvm/IR/Instructions.h" 18 #include "llvm/IR/LLVMContext.h" 19 #include "llvm/IR/Module.h" 20 #include "llvm/Support/ErrorHandling.h" 21 #include "llvm/Support/KnownBits.h" 22 #include "llvm/Support/SourceMgr.h" 23 #include "llvm/Transforms/Utils/Local.h" 24 #include "gtest/gtest.h" 25 26 using namespace llvm; 27 28 namespace { 29 30 static Instruction *findInstructionByNameOrNull(Function *F, StringRef Name) { 31 for (Instruction &I : instructions(F)) 32 if (I.getName() == Name) 33 return &I; 34 35 return nullptr; 36 } 37 38 static Instruction &findInstructionByName(Function *F, StringRef Name) { 39 auto *I = findInstructionByNameOrNull(F, Name); 40 if (I) 41 return *I; 42 43 llvm_unreachable("Expected value not found"); 44 } 45 46 class ValueTrackingTest : public testing::Test { 47 protected: 48 std::unique_ptr<Module> parseModule(StringRef Assembly) { 49 SMDiagnostic Error; 50 std::unique_ptr<Module> M = parseAssemblyString(Assembly, Error, Context); 51 52 std::string errMsg; 53 raw_string_ostream os(errMsg); 54 Error.print("", os); 55 EXPECT_TRUE(M) << os.str(); 56 57 return M; 58 } 59 60 void parseAssembly(StringRef Assembly) { 61 M = parseModule(Assembly); 62 ASSERT_TRUE(M); 63 64 F = M->getFunction("test"); 65 ASSERT_TRUE(F) << "Test must have a function @test"; 66 if (!F) 67 return; 68 69 A = findInstructionByNameOrNull(F, "A"); 70 ASSERT_TRUE(A) << "@test must have an instruction %A"; 71 A2 = findInstructionByNameOrNull(F, "A2"); 72 A3 = findInstructionByNameOrNull(F, "A3"); 73 A4 = findInstructionByNameOrNull(F, "A4"); 74 A5 = findInstructionByNameOrNull(F, "A5"); 75 76 CxtI = findInstructionByNameOrNull(F, "CxtI"); 77 CxtI2 = findInstructionByNameOrNull(F, "CxtI2"); 78 CxtI3 = findInstructionByNameOrNull(F, "CxtI3"); 79 } 80 81 LLVMContext Context; 82 std::unique_ptr<Module> M; 83 Function *F = nullptr; 84 Instruction *A = nullptr; 85 // Instructions (optional) 86 Instruction *A2 = nullptr, *A3 = nullptr, *A4 = nullptr, *A5 = nullptr; 87 88 // Context instructions (optional) 89 Instruction *CxtI = nullptr, *CxtI2 = nullptr, *CxtI3 = nullptr; 90 }; 91 92 class MatchSelectPatternTest : public ValueTrackingTest { 93 protected: 94 void expectPattern(const SelectPatternResult &P) { 95 Value *LHS, *RHS; 96 Instruction::CastOps CastOp; 97 SelectPatternResult R = matchSelectPattern(A, LHS, RHS, &CastOp); 98 EXPECT_EQ(P.Flavor, R.Flavor); 99 EXPECT_EQ(P.NaNBehavior, R.NaNBehavior); 100 EXPECT_EQ(P.Ordered, R.Ordered); 101 } 102 }; 103 104 class ComputeKnownBitsTest : public ValueTrackingTest { 105 protected: 106 void expectKnownBits(uint64_t Zero, uint64_t One) { 107 auto Known = computeKnownBits(A, M->getDataLayout()); 108 ASSERT_FALSE(Known.hasConflict()); 109 EXPECT_EQ(Known.One.getZExtValue(), One); 110 EXPECT_EQ(Known.Zero.getZExtValue(), Zero); 111 } 112 }; 113 114 class ComputeKnownFPClassTest : public ValueTrackingTest { 115 protected: 116 void expectKnownFPClass(unsigned KnownTrue, std::optional<bool> SignBitKnown, 117 Instruction *TestVal = nullptr) { 118 if (!TestVal) 119 TestVal = A; 120 121 KnownFPClass Known = computeKnownFPClass(TestVal, M->getDataLayout()); 122 EXPECT_EQ(KnownTrue, Known.KnownFPClasses); 123 EXPECT_EQ(SignBitKnown, Known.SignBit); 124 } 125 }; 126 } 127 128 TEST_F(MatchSelectPatternTest, SimpleFMin) { 129 parseAssembly( 130 "define float @test(float %a) {\n" 131 " %1 = fcmp ult float %a, 5.0\n" 132 " %A = select i1 %1, float %a, float 5.0\n" 133 " ret float %A\n" 134 "}\n"); 135 expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, false}); 136 } 137 138 TEST_F(MatchSelectPatternTest, SimpleFMax) { 139 parseAssembly( 140 "define float @test(float %a) {\n" 141 " %1 = fcmp ogt float %a, 5.0\n" 142 " %A = select i1 %1, float %a, float 5.0\n" 143 " ret float %A\n" 144 "}\n"); 145 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, true}); 146 } 147 148 TEST_F(MatchSelectPatternTest, SwappedFMax) { 149 parseAssembly( 150 "define float @test(float %a) {\n" 151 " %1 = fcmp olt float 5.0, %a\n" 152 " %A = select i1 %1, float %a, float 5.0\n" 153 " ret float %A\n" 154 "}\n"); 155 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, false}); 156 } 157 158 TEST_F(MatchSelectPatternTest, SwappedFMax2) { 159 parseAssembly( 160 "define float @test(float %a) {\n" 161 " %1 = fcmp olt float %a, 5.0\n" 162 " %A = select i1 %1, float 5.0, float %a\n" 163 " ret float %A\n" 164 "}\n"); 165 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_NAN, false}); 166 } 167 168 TEST_F(MatchSelectPatternTest, SwappedFMax3) { 169 parseAssembly( 170 "define float @test(float %a) {\n" 171 " %1 = fcmp ult float %a, 5.0\n" 172 " %A = select i1 %1, float 5.0, float %a\n" 173 " ret float %A\n" 174 "}\n"); 175 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, true}); 176 } 177 178 TEST_F(MatchSelectPatternTest, FastFMin) { 179 parseAssembly( 180 "define float @test(float %a) {\n" 181 " %1 = fcmp nnan olt float %a, 5.0\n" 182 " %A = select i1 %1, float %a, float 5.0\n" 183 " ret float %A\n" 184 "}\n"); 185 expectPattern({SPF_FMINNUM, SPNB_RETURNS_ANY, false}); 186 } 187 188 TEST_F(MatchSelectPatternTest, FMinConstantZero) { 189 parseAssembly( 190 "define float @test(float %a) {\n" 191 " %1 = fcmp ole float %a, 0.0\n" 192 " %A = select i1 %1, float %a, float 0.0\n" 193 " ret float %A\n" 194 "}\n"); 195 // This shouldn't be matched, as %a could be -0.0. 196 expectPattern({SPF_UNKNOWN, SPNB_NA, false}); 197 } 198 199 TEST_F(MatchSelectPatternTest, FMinConstantZeroNsz) { 200 parseAssembly( 201 "define float @test(float %a) {\n" 202 " %1 = fcmp nsz ole float %a, 0.0\n" 203 " %A = select i1 %1, float %a, float 0.0\n" 204 " ret float %A\n" 205 "}\n"); 206 // But this should be, because we've ignored signed zeroes. 207 expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, true}); 208 } 209 210 TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero1) { 211 parseAssembly( 212 "define float @test(float %a) {\n" 213 " %1 = fcmp olt float -0.0, %a\n" 214 " %A = select i1 %1, float 0.0, float %a\n" 215 " ret float %A\n" 216 "}\n"); 217 // The sign of zero doesn't matter in fcmp. 218 expectPattern({SPF_UNKNOWN, SPNB_NA, false}); 219 } 220 221 TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero2) { 222 parseAssembly( 223 "define float @test(float %a) {\n" 224 " %1 = fcmp ogt float %a, -0.0\n" 225 " %A = select i1 %1, float 0.0, float %a\n" 226 " ret float %A\n" 227 "}\n"); 228 // The sign of zero doesn't matter in fcmp. 229 expectPattern({SPF_UNKNOWN, SPNB_NA, false}); 230 } 231 232 TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero3) { 233 parseAssembly( 234 "define float @test(float %a) {\n" 235 " %1 = fcmp olt float 0.0, %a\n" 236 " %A = select i1 %1, float -0.0, float %a\n" 237 " ret float %A\n" 238 "}\n"); 239 // The sign of zero doesn't matter in fcmp. 240 expectPattern({SPF_UNKNOWN, SPNB_NA, false}); 241 } 242 243 TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero4) { 244 parseAssembly( 245 "define float @test(float %a) {\n" 246 " %1 = fcmp ogt float %a, 0.0\n" 247 " %A = select i1 %1, float -0.0, float %a\n" 248 " ret float %A\n" 249 "}\n"); 250 // The sign of zero doesn't matter in fcmp. 251 expectPattern({SPF_UNKNOWN, SPNB_NA, false}); 252 } 253 254 TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero5) { 255 parseAssembly( 256 "define float @test(float %a) {\n" 257 " %1 = fcmp ogt float -0.0, %a\n" 258 " %A = select i1 %1, float %a, float 0.0\n" 259 " ret float %A\n" 260 "}\n"); 261 // The sign of zero doesn't matter in fcmp. 262 expectPattern({SPF_UNKNOWN, SPNB_NA, false}); 263 } 264 265 TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero6) { 266 parseAssembly( 267 "define float @test(float %a) {\n" 268 " %1 = fcmp olt float %a, -0.0\n" 269 " %A = select i1 %1, float %a, float 0.0\n" 270 " ret float %A\n" 271 "}\n"); 272 // The sign of zero doesn't matter in fcmp. 273 expectPattern({SPF_UNKNOWN, SPNB_NA, false}); 274 } 275 276 TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero7) { 277 parseAssembly( 278 "define float @test(float %a) {\n" 279 " %1 = fcmp ogt float 0.0, %a\n" 280 " %A = select i1 %1, float %a, float -0.0\n" 281 " ret float %A\n" 282 "}\n"); 283 // The sign of zero doesn't matter in fcmp. 284 expectPattern({SPF_UNKNOWN, SPNB_NA, false}); 285 } 286 287 TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero8) { 288 parseAssembly( 289 "define float @test(float %a) {\n" 290 " %1 = fcmp olt float %a, 0.0\n" 291 " %A = select i1 %1, float %a, float -0.0\n" 292 " ret float %A\n" 293 "}\n"); 294 // The sign of zero doesn't matter in fcmp. 295 expectPattern({SPF_UNKNOWN, SPNB_NA, false}); 296 } 297 298 TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero1) { 299 parseAssembly( 300 "define float @test(float %a) {\n" 301 " %1 = fcmp ogt float -0.0, %a\n" 302 " %A = select i1 %1, float 0.0, float %a\n" 303 " ret float %A\n" 304 "}\n"); 305 // The sign of zero doesn't matter in fcmp. 306 expectPattern({SPF_UNKNOWN, SPNB_NA, false}); 307 } 308 309 TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero2) { 310 parseAssembly( 311 "define float @test(float %a) {\n" 312 " %1 = fcmp olt float %a, -0.0\n" 313 " %A = select i1 %1, float 0.0, float %a\n" 314 " ret float %A\n" 315 "}\n"); 316 // The sign of zero doesn't matter in fcmp. 317 expectPattern({SPF_UNKNOWN, SPNB_NA, false}); 318 } 319 320 TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero3) { 321 parseAssembly( 322 "define float @test(float %a) {\n" 323 " %1 = fcmp ogt float 0.0, %a\n" 324 " %A = select i1 %1, float -0.0, float %a\n" 325 " ret float %A\n" 326 "}\n"); 327 // The sign of zero doesn't matter in fcmp. 328 expectPattern({SPF_UNKNOWN, SPNB_NA, false}); 329 } 330 331 TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero4) { 332 parseAssembly( 333 "define float @test(float %a) {\n" 334 " %1 = fcmp olt float %a, 0.0\n" 335 " %A = select i1 %1, float -0.0, float %a\n" 336 " ret float %A\n" 337 "}\n"); 338 // The sign of zero doesn't matter in fcmp. 339 expectPattern({SPF_UNKNOWN, SPNB_NA, false}); 340 } 341 342 TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero5) { 343 parseAssembly( 344 "define float @test(float %a) {\n" 345 " %1 = fcmp olt float -0.0, %a\n" 346 " %A = select i1 %1, float %a, float 0.0\n" 347 " ret float %A\n" 348 "}\n"); 349 // The sign of zero doesn't matter in fcmp. 350 expectPattern({SPF_UNKNOWN, SPNB_NA, false}); 351 } 352 353 TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero6) { 354 parseAssembly( 355 "define float @test(float %a) {\n" 356 " %1 = fcmp ogt float %a, -0.0\n" 357 " %A = select i1 %1, float %a, float 0.0\n" 358 " ret float %A\n" 359 "}\n"); 360 // The sign of zero doesn't matter in fcmp. 361 expectPattern({SPF_UNKNOWN, SPNB_NA, false}); 362 } 363 364 TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero7) { 365 parseAssembly( 366 "define float @test(float %a) {\n" 367 " %1 = fcmp olt float 0.0, %a\n" 368 " %A = select i1 %1, float %a, float -0.0\n" 369 " ret float %A\n" 370 "}\n"); 371 // The sign of zero doesn't matter in fcmp. 372 expectPattern({SPF_UNKNOWN, SPNB_NA, false}); 373 } 374 375 TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero8) { 376 parseAssembly( 377 "define float @test(float %a) {\n" 378 " %1 = fcmp ogt float %a, 0.0\n" 379 " %A = select i1 %1, float %a, float -0.0\n" 380 " ret float %A\n" 381 "}\n"); 382 // The sign of zero doesn't matter in fcmp. 383 expectPattern({SPF_UNKNOWN, SPNB_NA, false}); 384 } 385 386 TEST_F(MatchSelectPatternTest, FMinMismatchConstantZeroVecUndef) { 387 parseAssembly( 388 "define <2 x float> @test(<2 x float> %a) {\n" 389 " %1 = fcmp ogt <2 x float> %a, <float -0.0, float -0.0>\n" 390 " %A = select <2 x i1> %1, <2 x float> <float undef, float 0.0>, <2 x float> %a\n" 391 " ret <2 x float> %A\n" 392 "}\n"); 393 // An undef in a vector constant can not be back-propagated for this analysis. 394 expectPattern({SPF_UNKNOWN, SPNB_NA, false}); 395 } 396 397 TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZeroVecUndef) { 398 parseAssembly( 399 "define <2 x float> @test(<2 x float> %a) {\n" 400 " %1 = fcmp ogt <2 x float> %a, zeroinitializer\n" 401 " %A = select <2 x i1> %1, <2 x float> %a, <2 x float> <float -0.0, float undef>\n" 402 " ret <2 x float> %A\n" 403 "}\n"); 404 // An undef in a vector constant can not be back-propagated for this analysis. 405 expectPattern({SPF_UNKNOWN, SPNB_NA, false}); 406 } 407 408 TEST_F(MatchSelectPatternTest, VectorFMinimum) { 409 parseAssembly( 410 "define <4 x float> @test(<4 x float> %a) {\n" 411 " %1 = fcmp ule <4 x float> %a, \n" 412 " <float 5.0, float 5.0, float 5.0, float 5.0>\n" 413 " %A = select <4 x i1> %1, <4 x float> %a,\n" 414 " <4 x float> <float 5.0, float 5.0, float 5.0, float 5.0>\n" 415 " ret <4 x float> %A\n" 416 "}\n"); 417 // Check that pattern matching works on vectors where each lane has the same 418 // unordered pattern. 419 expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, false}); 420 } 421 422 TEST_F(MatchSelectPatternTest, VectorFMinOtherOrdered) { 423 parseAssembly( 424 "define <4 x float> @test(<4 x float> %a) {\n" 425 " %1 = fcmp ole <4 x float> %a, \n" 426 " <float 5.0, float 5.0, float 5.0, float 5.0>\n" 427 " %A = select <4 x i1> %1, <4 x float> %a,\n" 428 " <4 x float> <float 5.0, float 5.0, float 5.0, float 5.0>\n" 429 " ret <4 x float> %A\n" 430 "}\n"); 431 // Check that pattern matching works on vectors where each lane has the same 432 // ordered pattern. 433 expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, true}); 434 } 435 436 TEST_F(MatchSelectPatternTest, VectorNotFMinimum) { 437 parseAssembly( 438 "define <4 x float> @test(<4 x float> %a) {\n" 439 " %1 = fcmp ule <4 x float> %a, \n" 440 " <float 5.0, float 0x7ff8000000000000, float 5.0, float 5.0>\n" 441 " %A = select <4 x i1> %1, <4 x float> %a,\n" 442 " <4 x float> <float 5.0, float 0x7ff8000000000000, float 5.0, float " 443 "5.0>\n" 444 " ret <4 x float> %A\n" 445 "}\n"); 446 // The lane that contains a NaN (0x7ff80...) behaves like a 447 // non-NaN-propagating min and the other lines behave like a NaN-propagating 448 // min, so check that neither is returned. 449 expectPattern({SPF_UNKNOWN, SPNB_NA, false}); 450 } 451 452 TEST_F(MatchSelectPatternTest, VectorNotFMinZero) { 453 parseAssembly( 454 "define <4 x float> @test(<4 x float> %a) {\n" 455 " %1 = fcmp ule <4 x float> %a, \n" 456 " <float 5.0, float -0.0, float 5.0, float 5.0>\n" 457 " %A = select <4 x i1> %1, <4 x float> %a,\n" 458 " <4 x float> <float 5.0, float 0.0, float 5.0, float 5.0>\n" 459 " ret <4 x float> %A\n" 460 "}\n"); 461 // Always selects the second lane of %a if it is positive or negative zero, so 462 // this is stricter than a min. 463 expectPattern({SPF_UNKNOWN, SPNB_NA, false}); 464 } 465 466 TEST_F(MatchSelectPatternTest, DoubleCastU) { 467 parseAssembly( 468 "define i32 @test(i8 %a, i8 %b) {\n" 469 " %1 = icmp ult i8 %a, %b\n" 470 " %2 = zext i8 %a to i32\n" 471 " %3 = zext i8 %b to i32\n" 472 " %A = select i1 %1, i32 %2, i32 %3\n" 473 " ret i32 %A\n" 474 "}\n"); 475 // We should be able to look through the situation where we cast both operands 476 // to the select. 477 expectPattern({SPF_UMIN, SPNB_NA, false}); 478 } 479 480 TEST_F(MatchSelectPatternTest, DoubleCastS) { 481 parseAssembly( 482 "define i32 @test(i8 %a, i8 %b) {\n" 483 " %1 = icmp slt i8 %a, %b\n" 484 " %2 = sext i8 %a to i32\n" 485 " %3 = sext i8 %b to i32\n" 486 " %A = select i1 %1, i32 %2, i32 %3\n" 487 " ret i32 %A\n" 488 "}\n"); 489 // We should be able to look through the situation where we cast both operands 490 // to the select. 491 expectPattern({SPF_SMIN, SPNB_NA, false}); 492 } 493 494 TEST_F(MatchSelectPatternTest, DoubleCastBad) { 495 parseAssembly( 496 "define i32 @test(i8 %a, i8 %b) {\n" 497 " %1 = icmp ult i8 %a, %b\n" 498 " %2 = zext i8 %a to i32\n" 499 " %3 = sext i8 %b to i32\n" 500 " %A = select i1 %1, i32 %2, i32 %3\n" 501 " ret i32 %A\n" 502 "}\n"); 503 // The cast types here aren't the same, so we cannot match an UMIN. 504 expectPattern({SPF_UNKNOWN, SPNB_NA, false}); 505 } 506 507 TEST_F(MatchSelectPatternTest, NotNotSMin) { 508 parseAssembly( 509 "define i8 @test(i8 %a, i8 %b) {\n" 510 " %cmp = icmp sgt i8 %a, %b\n" 511 " %an = xor i8 %a, -1\n" 512 " %bn = xor i8 %b, -1\n" 513 " %A = select i1 %cmp, i8 %an, i8 %bn\n" 514 " ret i8 %A\n" 515 "}\n"); 516 expectPattern({SPF_SMIN, SPNB_NA, false}); 517 } 518 519 TEST_F(MatchSelectPatternTest, NotNotSMinSwap) { 520 parseAssembly( 521 "define <2 x i8> @test(<2 x i8> %a, <2 x i8> %b) {\n" 522 " %cmp = icmp slt <2 x i8> %a, %b\n" 523 " %an = xor <2 x i8> %a, <i8 -1, i8-1>\n" 524 " %bn = xor <2 x i8> %b, <i8 -1, i8-1>\n" 525 " %A = select <2 x i1> %cmp, <2 x i8> %bn, <2 x i8> %an\n" 526 " ret <2 x i8> %A\n" 527 "}\n"); 528 expectPattern({SPF_SMIN, SPNB_NA, false}); 529 } 530 531 TEST_F(MatchSelectPatternTest, NotNotSMax) { 532 parseAssembly( 533 "define i8 @test(i8 %a, i8 %b) {\n" 534 " %cmp = icmp slt i8 %a, %b\n" 535 " %an = xor i8 %a, -1\n" 536 " %bn = xor i8 %b, -1\n" 537 " %A = select i1 %cmp, i8 %an, i8 %bn\n" 538 " ret i8 %A\n" 539 "}\n"); 540 expectPattern({SPF_SMAX, SPNB_NA, false}); 541 } 542 543 TEST_F(MatchSelectPatternTest, NotNotSMaxSwap) { 544 parseAssembly( 545 "define <2 x i8> @test(<2 x i8> %a, <2 x i8> %b) {\n" 546 " %cmp = icmp sgt <2 x i8> %a, %b\n" 547 " %an = xor <2 x i8> %a, <i8 -1, i8-1>\n" 548 " %bn = xor <2 x i8> %b, <i8 -1, i8-1>\n" 549 " %A = select <2 x i1> %cmp, <2 x i8> %bn, <2 x i8> %an\n" 550 " ret <2 x i8> %A\n" 551 "}\n"); 552 expectPattern({SPF_SMAX, SPNB_NA, false}); 553 } 554 555 TEST_F(MatchSelectPatternTest, NotNotUMin) { 556 parseAssembly( 557 "define <2 x i8> @test(<2 x i8> %a, <2 x i8> %b) {\n" 558 " %cmp = icmp ugt <2 x i8> %a, %b\n" 559 " %an = xor <2 x i8> %a, <i8 -1, i8-1>\n" 560 " %bn = xor <2 x i8> %b, <i8 -1, i8-1>\n" 561 " %A = select <2 x i1> %cmp, <2 x i8> %an, <2 x i8> %bn\n" 562 " ret <2 x i8> %A\n" 563 "}\n"); 564 expectPattern({SPF_UMIN, SPNB_NA, false}); 565 } 566 567 TEST_F(MatchSelectPatternTest, NotNotUMinSwap) { 568 parseAssembly( 569 "define i8 @test(i8 %a, i8 %b) {\n" 570 " %cmp = icmp ult i8 %a, %b\n" 571 " %an = xor i8 %a, -1\n" 572 " %bn = xor i8 %b, -1\n" 573 " %A = select i1 %cmp, i8 %bn, i8 %an\n" 574 " ret i8 %A\n" 575 "}\n"); 576 expectPattern({SPF_UMIN, SPNB_NA, false}); 577 } 578 579 TEST_F(MatchSelectPatternTest, NotNotUMax) { 580 parseAssembly( 581 "define <2 x i8> @test(<2 x i8> %a, <2 x i8> %b) {\n" 582 " %cmp = icmp ult <2 x i8> %a, %b\n" 583 " %an = xor <2 x i8> %a, <i8 -1, i8-1>\n" 584 " %bn = xor <2 x i8> %b, <i8 -1, i8-1>\n" 585 " %A = select <2 x i1> %cmp, <2 x i8> %an, <2 x i8> %bn\n" 586 " ret <2 x i8> %A\n" 587 "}\n"); 588 expectPattern({SPF_UMAX, SPNB_NA, false}); 589 } 590 591 TEST_F(MatchSelectPatternTest, NotNotUMaxSwap) { 592 parseAssembly( 593 "define i8 @test(i8 %a, i8 %b) {\n" 594 " %cmp = icmp ugt i8 %a, %b\n" 595 " %an = xor i8 %a, -1\n" 596 " %bn = xor i8 %b, -1\n" 597 " %A = select i1 %cmp, i8 %bn, i8 %an\n" 598 " ret i8 %A\n" 599 "}\n"); 600 expectPattern({SPF_UMAX, SPNB_NA, false}); 601 } 602 603 TEST_F(MatchSelectPatternTest, NotNotEq) { 604 parseAssembly( 605 "define i8 @test(i8 %a, i8 %b) {\n" 606 " %cmp = icmp eq i8 %a, %b\n" 607 " %an = xor i8 %a, -1\n" 608 " %bn = xor i8 %b, -1\n" 609 " %A = select i1 %cmp, i8 %bn, i8 %an\n" 610 " ret i8 %A\n" 611 "}\n"); 612 expectPattern({SPF_UNKNOWN, SPNB_NA, false}); 613 } 614 615 TEST_F(MatchSelectPatternTest, NotNotNe) { 616 parseAssembly( 617 "define i8 @test(i8 %a, i8 %b) {\n" 618 " %cmp = icmp ne i8 %a, %b\n" 619 " %an = xor i8 %a, -1\n" 620 " %bn = xor i8 %b, -1\n" 621 " %A = select i1 %cmp, i8 %bn, i8 %an\n" 622 " ret i8 %A\n" 623 "}\n"); 624 expectPattern({SPF_UNKNOWN, SPNB_NA, false}); 625 } 626 627 TEST(ValueTracking, GuaranteedToTransferExecutionToSuccessor) { 628 StringRef Assembly = 629 "declare void @nounwind_readonly(ptr) nounwind readonly " 630 "declare void @nounwind_argmemonly(ptr) nounwind argmemonly " 631 "declare void @nounwind_willreturn(ptr) nounwind willreturn " 632 "declare void @throws_but_readonly(ptr) readonly " 633 "declare void @throws_but_argmemonly(ptr) argmemonly " 634 "declare void @throws_but_willreturn(ptr) willreturn " 635 " " 636 "declare void @unknown(ptr) " 637 " " 638 "define void @f(ptr %p) { " 639 " call void @nounwind_readonly(ptr %p) " 640 " call void @nounwind_argmemonly(ptr %p) " 641 " call void @nounwind_willreturn(ptr %p)" 642 " call void @throws_but_readonly(ptr %p) " 643 " call void @throws_but_argmemonly(ptr %p) " 644 " call void @throws_but_willreturn(ptr %p) " 645 " call void @unknown(ptr %p) nounwind readonly " 646 " call void @unknown(ptr %p) nounwind argmemonly " 647 " call void @unknown(ptr %p) nounwind willreturn " 648 " call void @unknown(ptr %p) readonly " 649 " call void @unknown(ptr %p) argmemonly " 650 " call void @unknown(ptr %p) willreturn " 651 " ret void " 652 "} "; 653 654 LLVMContext Context; 655 SMDiagnostic Error; 656 auto M = parseAssemblyString(Assembly, Error, Context); 657 assert(M && "Bad assembly?"); 658 659 auto *F = M->getFunction("f"); 660 assert(F && "Bad assembly?"); 661 662 auto &BB = F->getEntryBlock(); 663 bool ExpectedAnswers[] = { 664 false, // call void @nounwind_readonly(ptr %p) 665 false, // call void @nounwind_argmemonly(ptr %p) 666 true, // call void @nounwind_willreturn(ptr %p) 667 false, // call void @throws_but_readonly(ptr %p) 668 false, // call void @throws_but_argmemonly(ptr %p) 669 false, // call void @throws_but_willreturn(ptr %p) 670 false, // call void @unknown(ptr %p) nounwind readonly 671 false, // call void @unknown(ptr %p) nounwind argmemonly 672 true, // call void @unknown(ptr %p) nounwind willreturn 673 false, // call void @unknown(ptr %p) readonly 674 false, // call void @unknown(ptr %p) argmemonly 675 false, // call void @unknown(ptr %p) willreturn 676 false, // ret void 677 }; 678 679 int Index = 0; 680 for (auto &I : BB) { 681 EXPECT_EQ(isGuaranteedToTransferExecutionToSuccessor(&I), 682 ExpectedAnswers[Index]) 683 << "Incorrect answer at instruction " << Index << " = " << I; 684 Index++; 685 } 686 } 687 688 TEST_F(ValueTrackingTest, ComputeNumSignBits_PR32045) { 689 parseAssembly( 690 "define i32 @test(i32 %a) {\n" 691 " %A = ashr i32 %a, -1\n" 692 " ret i32 %A\n" 693 "}\n"); 694 EXPECT_EQ(ComputeNumSignBits(A, M->getDataLayout()), 1u); 695 } 696 697 // No guarantees for canonical IR in this analysis, so this just bails out. 698 TEST_F(ValueTrackingTest, ComputeNumSignBits_Shuffle) { 699 parseAssembly( 700 "define <2 x i32> @test() {\n" 701 " %A = shufflevector <2 x i32> undef, <2 x i32> undef, <2 x i32> <i32 0, i32 0>\n" 702 " ret <2 x i32> %A\n" 703 "}\n"); 704 EXPECT_EQ(ComputeNumSignBits(A, M->getDataLayout()), 1u); 705 } 706 707 // No guarantees for canonical IR in this analysis, so a shuffle element that 708 // references an undef value means this can't return any extra information. 709 TEST_F(ValueTrackingTest, ComputeNumSignBits_Shuffle2) { 710 parseAssembly( 711 "define <2 x i32> @test(<2 x i1> %x) {\n" 712 " %sext = sext <2 x i1> %x to <2 x i32>\n" 713 " %A = shufflevector <2 x i32> %sext, <2 x i32> undef, <2 x i32> <i32 0, i32 2>\n" 714 " ret <2 x i32> %A\n" 715 "}\n"); 716 EXPECT_EQ(ComputeNumSignBits(A, M->getDataLayout()), 1u); 717 } 718 719 TEST_F(ValueTrackingTest, impliesPoisonTest_Identity) { 720 parseAssembly("define void @test(i32 %x, i32 %y) {\n" 721 " %A = add i32 %x, %y\n" 722 " ret void\n" 723 "}"); 724 EXPECT_TRUE(impliesPoison(A, A)); 725 } 726 727 TEST_F(ValueTrackingTest, impliesPoisonTest_ICmp) { 728 parseAssembly("define void @test(i32 %x) {\n" 729 " %A2 = icmp eq i32 %x, 0\n" 730 " %A = icmp eq i32 %x, 1\n" 731 " ret void\n" 732 "}"); 733 EXPECT_TRUE(impliesPoison(A2, A)); 734 } 735 736 TEST_F(ValueTrackingTest, impliesPoisonTest_ICmpUnknown) { 737 parseAssembly("define void @test(i32 %x, i32 %y) {\n" 738 " %A2 = icmp eq i32 %x, %y\n" 739 " %A = icmp eq i32 %x, 1\n" 740 " ret void\n" 741 "}"); 742 EXPECT_FALSE(impliesPoison(A2, A)); 743 } 744 745 TEST_F(ValueTrackingTest, impliesPoisonTest_AddNswOkay) { 746 parseAssembly("define void @test(i32 %x) {\n" 747 " %A2 = add nsw i32 %x, 1\n" 748 " %A = add i32 %A2, 1\n" 749 " ret void\n" 750 "}"); 751 EXPECT_TRUE(impliesPoison(A2, A)); 752 } 753 754 TEST_F(ValueTrackingTest, impliesPoisonTest_AddNswOkay2) { 755 parseAssembly("define void @test(i32 %x) {\n" 756 " %A2 = add i32 %x, 1\n" 757 " %A = add nsw i32 %A2, 1\n" 758 " ret void\n" 759 "}"); 760 EXPECT_TRUE(impliesPoison(A2, A)); 761 } 762 763 TEST_F(ValueTrackingTest, impliesPoisonTest_AddNsw) { 764 parseAssembly("define void @test(i32 %x) {\n" 765 " %A2 = add nsw i32 %x, 1\n" 766 " %A = add i32 %x, 1\n" 767 " ret void\n" 768 "}"); 769 EXPECT_FALSE(impliesPoison(A2, A)); 770 } 771 772 TEST_F(ValueTrackingTest, impliesPoisonTest_Cmp) { 773 parseAssembly("define void @test(i32 %x, i32 %y, i1 %c) {\n" 774 " %A2 = icmp eq i32 %x, %y\n" 775 " %A0 = icmp ult i32 %x, %y\n" 776 " %A = or i1 %A0, %c\n" 777 " ret void\n" 778 "}"); 779 EXPECT_TRUE(impliesPoison(A2, A)); 780 } 781 782 TEST_F(ValueTrackingTest, impliesPoisonTest_FCmpFMF) { 783 parseAssembly("define void @test(float %x, float %y, i1 %c) {\n" 784 " %A2 = fcmp nnan oeq float %x, %y\n" 785 " %A0 = fcmp olt float %x, %y\n" 786 " %A = or i1 %A0, %c\n" 787 " ret void\n" 788 "}"); 789 EXPECT_FALSE(impliesPoison(A2, A)); 790 } 791 792 TEST_F(ValueTrackingTest, impliesPoisonTest_AddSubSameOps) { 793 parseAssembly("define void @test(i32 %x, i32 %y, i1 %c) {\n" 794 " %A2 = add i32 %x, %y\n" 795 " %A = sub i32 %x, %y\n" 796 " ret void\n" 797 "}"); 798 EXPECT_TRUE(impliesPoison(A2, A)); 799 } 800 801 TEST_F(ValueTrackingTest, impliesPoisonTest_MaskCmp) { 802 parseAssembly("define void @test(i32 %x, i32 %y, i1 %c) {\n" 803 " %M2 = and i32 %x, 7\n" 804 " %A2 = icmp eq i32 %M2, 1\n" 805 " %M = and i32 %x, 15\n" 806 " %A = icmp eq i32 %M, 3\n" 807 " ret void\n" 808 "}"); 809 EXPECT_TRUE(impliesPoison(A2, A)); 810 } 811 812 TEST_F(ValueTrackingTest, ComputeNumSignBits_Shuffle_Pointers) { 813 parseAssembly( 814 "define <2 x ptr> @test(<2 x ptr> %x) {\n" 815 " %A = shufflevector <2 x ptr> zeroinitializer, <2 x ptr> undef, <2 x i32> zeroinitializer\n" 816 " ret <2 x ptr> %A\n" 817 "}\n"); 818 EXPECT_EQ(ComputeNumSignBits(A, M->getDataLayout()), 64u); 819 } 820 821 TEST(ValueTracking, propagatesPoison) { 822 std::string AsmHead = 823 "declare i32 @g(i32)\n" 824 "declare {i32, i1} @llvm.sadd.with.overflow.i32(i32 %a, i32 %b)\n" 825 "declare {i32, i1} @llvm.ssub.with.overflow.i32(i32 %a, i32 %b)\n" 826 "declare {i32, i1} @llvm.smul.with.overflow.i32(i32 %a, i32 %b)\n" 827 "declare {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 %b)\n" 828 "declare {i32, i1} @llvm.usub.with.overflow.i32(i32 %a, i32 %b)\n" 829 "declare {i32, i1} @llvm.umul.with.overflow.i32(i32 %a, i32 %b)\n" 830 "declare float @llvm.sqrt.f32(float)\n" 831 "declare float @llvm.powi.f32.i32(float, i32)\n" 832 "declare float @llvm.sin.f32(float)\n" 833 "declare float @llvm.cos.f32(float)\n" 834 "declare float @llvm.pow.f32(float, float)\n" 835 "declare float @llvm.exp.f32(float)\n" 836 "declare float @llvm.exp2.f32(float)\n" 837 "declare float @llvm.log.f32(float)\n" 838 "declare float @llvm.log10.f32(float)\n" 839 "declare float @llvm.log2.f32(float)\n" 840 "declare float @llvm.fma.f32(float, float, float)\n" 841 "declare float @llvm.fabs.f32(float)\n" 842 "declare float @llvm.minnum.f32(float, float)\n" 843 "declare float @llvm.maxnum.f32(float, float)\n" 844 "declare float @llvm.minimum.f32(float, float)\n" 845 "declare float @llvm.maximum.f32(float, float)\n" 846 "declare float @llvm.copysign.f32(float, float)\n" 847 "declare float @llvm.floor.f32(float)\n" 848 "declare float @llvm.ceil.f32(float)\n" 849 "declare float @llvm.trunc.f32(float)\n" 850 "declare float @llvm.rint.f32(float)\n" 851 "declare float @llvm.nearbyint.f32(float)\n" 852 "declare float @llvm.round.f32(float)\n" 853 "declare float @llvm.roundeven.f32(float)\n" 854 "declare i32 @llvm.lround.f32(float)\n" 855 "declare i64 @llvm.llround.f32(float)\n" 856 "declare i32 @llvm.lrint.f32(float)\n" 857 "declare i64 @llvm.llrint.f32(float)\n" 858 "declare float @llvm.fmuladd.f32(float, float, float)\n" 859 "define void @f(i32 %x, i32 %y, float %fx, float %fy, " 860 "i1 %cond, ptr %p) {\n"; 861 std::string AsmTail = " ret void\n}"; 862 // (propagates poison?, IR instruction) 863 SmallVector<std::tuple<bool, std::string, unsigned>, 32> Data = { 864 {true, "add i32 %x, %y", 0}, 865 {true, "add i32 %x, %y", 1}, 866 {true, "add nsw nuw i32 %x, %y", 0}, 867 {true, "add nsw nuw i32 %x, %y", 1}, 868 {true, "ashr i32 %x, %y", 0}, 869 {true, "ashr i32 %x, %y", 1}, 870 {true, "lshr exact i32 %x, 31", 0}, 871 {true, "lshr exact i32 %x, 31", 1}, 872 {true, "fadd float %fx, %fy", 0}, 873 {true, "fadd float %fx, %fy", 1}, 874 {true, "fsub float %fx, %fy", 0}, 875 {true, "fsub float %fx, %fy", 1}, 876 {true, "fmul float %fx, %fy", 0}, 877 {true, "fmul float %fx, %fy", 1}, 878 {true, "fdiv float %fx, %fy", 0}, 879 {true, "fdiv float %fx, %fy", 1}, 880 {true, "frem float %fx, %fy", 0}, 881 {true, "frem float %fx, %fy", 1}, 882 {true, "fneg float %fx", 0}, 883 {true, "fcmp oeq float %fx, %fy", 0}, 884 {true, "fcmp oeq float %fx, %fy", 1}, 885 {true, "icmp eq i32 %x, %y", 0}, 886 {true, "icmp eq i32 %x, %y", 1}, 887 {true, "getelementptr i8, ptr %p, i32 %x", 0}, 888 {true, "getelementptr i8, ptr %p, i32 %x", 1}, 889 {true, "getelementptr inbounds i8, ptr %p, i32 %x", 0}, 890 {true, "getelementptr inbounds i8, ptr %p, i32 %x", 1}, 891 {true, "bitcast float %fx to i32", 0}, 892 {true, "select i1 %cond, i32 %x, i32 %y", 0}, 893 {false, "select i1 %cond, i32 %x, i32 %y", 1}, 894 {false, "select i1 %cond, i32 %x, i32 %y", 2}, 895 {false, "freeze i32 %x", 0}, 896 {true, "udiv i32 %x, %y", 0}, 897 {true, "udiv i32 %x, %y", 1}, 898 {true, "urem i32 %x, %y", 0}, 899 {true, "urem i32 %x, %y", 1}, 900 {true, "sdiv exact i32 %x, %y", 0}, 901 {true, "sdiv exact i32 %x, %y", 1}, 902 {true, "srem i32 %x, %y", 0}, 903 {true, "srem i32 %x, %y", 1}, 904 {false, "call i32 @g(i32 %x)", 0}, 905 {false, "call i32 @g(i32 %x)", 1}, 906 {true, "call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %x, i32 %y)", 0}, 907 {true, "call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %x, i32 %y)", 0}, 908 {true, "call {i32, i1} @llvm.smul.with.overflow.i32(i32 %x, i32 %y)", 0}, 909 {true, "call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %x, i32 %y)", 0}, 910 {true, "call {i32, i1} @llvm.usub.with.overflow.i32(i32 %x, i32 %y)", 0}, 911 {true, "call {i32, i1} @llvm.umul.with.overflow.i32(i32 %x, i32 %y)", 0}, 912 {false, "call float @llvm.sqrt.f32(float %fx)", 0}, 913 {false, "call float @llvm.powi.f32.i32(float %fx, i32 %x)", 0}, 914 {false, "call float @llvm.sin.f32(float %fx)", 0}, 915 {false, "call float @llvm.cos.f32(float %fx)", 0}, 916 {false, "call float @llvm.pow.f32(float %fx, float %fy)", 0}, 917 {false, "call float @llvm.exp.f32(float %fx)", 0}, 918 {false, "call float @llvm.exp2.f32(float %fx)", 0}, 919 {false, "call float @llvm.log.f32(float %fx)", 0}, 920 {false, "call float @llvm.log10.f32(float %fx)", 0}, 921 {false, "call float @llvm.log2.f32(float %fx)", 0}, 922 {false, "call float @llvm.fma.f32(float %fx, float %fx, float %fy)", 0}, 923 {false, "call float @llvm.fabs.f32(float %fx)", 0}, 924 {false, "call float @llvm.minnum.f32(float %fx, float %fy)", 0}, 925 {false, "call float @llvm.maxnum.f32(float %fx, float %fy)", 0}, 926 {false, "call float @llvm.minimum.f32(float %fx, float %fy)", 0}, 927 {false, "call float @llvm.maximum.f32(float %fx, float %fy)", 0}, 928 {false, "call float @llvm.copysign.f32(float %fx, float %fy)", 0}, 929 {false, "call float @llvm.floor.f32(float %fx)", 0}, 930 {false, "call float @llvm.ceil.f32(float %fx)", 0}, 931 {false, "call float @llvm.trunc.f32(float %fx)", 0}, 932 {false, "call float @llvm.rint.f32(float %fx)", 0}, 933 {false, "call float @llvm.nearbyint.f32(float %fx)", 0}, 934 {false, "call float @llvm.round.f32(float %fx)", 0}, 935 {false, "call float @llvm.roundeven.f32(float %fx)", 0}, 936 {false, "call i32 @llvm.lround.f32(float %fx)", 0}, 937 {false, "call i64 @llvm.llround.f32(float %fx)", 0}, 938 {false, "call i32 @llvm.lrint.f32(float %fx)", 0}, 939 {false, "call i64 @llvm.llrint.f32(float %fx)", 0}, 940 {false, "call float @llvm.fmuladd.f32(float %fx, float %fx, float %fy)", 941 0}}; 942 943 std::string AssemblyStr = AsmHead; 944 for (auto &Itm : Data) 945 AssemblyStr += std::get<1>(Itm) + "\n"; 946 AssemblyStr += AsmTail; 947 948 LLVMContext Context; 949 SMDiagnostic Error; 950 auto M = parseAssemblyString(AssemblyStr, Error, Context); 951 assert(M && "Bad assembly?"); 952 953 auto *F = M->getFunction("f"); 954 assert(F && "Bad assembly?"); 955 956 auto &BB = F->getEntryBlock(); 957 958 int Index = 0; 959 for (auto &I : BB) { 960 if (isa<ReturnInst>(&I)) 961 break; 962 bool ExpectedVal = std::get<0>(Data[Index]); 963 unsigned OpIdx = std::get<2>(Data[Index]); 964 EXPECT_EQ(propagatesPoison(I.getOperandUse(OpIdx)), ExpectedVal) 965 << "Incorrect answer at instruction " << Index << " = " << I; 966 Index++; 967 } 968 } 969 970 TEST_F(ValueTrackingTest, programUndefinedIfPoison) { 971 parseAssembly("declare i32 @any_num()" 972 "define void @test(i32 %mask) {\n" 973 " %A = call i32 @any_num()\n" 974 " %B = or i32 %A, %mask\n" 975 " udiv i32 1, %B" 976 " ret void\n" 977 "}\n"); 978 // If %A was poison, udiv raises UB regardless of %mask's value 979 EXPECT_EQ(programUndefinedIfPoison(A), true); 980 } 981 982 TEST_F(ValueTrackingTest, programUndefinedIfUndefOrPoison) { 983 parseAssembly("declare i32 @any_num()" 984 "define void @test(i32 %mask) {\n" 985 " %A = call i32 @any_num()\n" 986 " %B = or i32 %A, %mask\n" 987 " udiv i32 1, %B" 988 " ret void\n" 989 "}\n"); 990 // If %A was undef and %mask was 1, udiv does not raise UB 991 EXPECT_EQ(programUndefinedIfUndefOrPoison(A), false); 992 } 993 994 TEST_F(ValueTrackingTest, isGuaranteedNotToBePoison_exploitBranchCond) { 995 parseAssembly("declare i1 @any_bool()" 996 "define void @test(i1 %y) {\n" 997 " %A = call i1 @any_bool()\n" 998 " %cond = and i1 %A, %y\n" 999 " br i1 %cond, label %BB1, label %BB2\n" 1000 "BB1:\n" 1001 " ret void\n" 1002 "BB2:\n" 1003 " ret void\n" 1004 "}\n"); 1005 DominatorTree DT(*F); 1006 for (auto &BB : *F) { 1007 if (&BB == &F->getEntryBlock()) 1008 continue; 1009 1010 EXPECT_EQ(isGuaranteedNotToBePoison(A, nullptr, BB.getTerminator(), &DT), 1011 true) 1012 << "isGuaranteedNotToBePoison does not hold at " << *BB.getTerminator(); 1013 } 1014 } 1015 1016 TEST_F(ValueTrackingTest, isGuaranteedNotToBePoison_phi) { 1017 parseAssembly("declare i32 @any_i32(i32)" 1018 "define void @test() {\n" 1019 "ENTRY:\n" 1020 " br label %LOOP\n" 1021 "LOOP:\n" 1022 " %A = phi i32 [0, %ENTRY], [%A.next, %NEXT]\n" 1023 " %A.next = call i32 @any_i32(i32 %A)\n" 1024 " %cond = icmp eq i32 %A.next, 0\n" 1025 " br i1 %cond, label %NEXT, label %EXIT\n" 1026 "NEXT:\n" 1027 " br label %LOOP\n" 1028 "EXIT:\n" 1029 " ret void\n" 1030 "}\n"); 1031 DominatorTree DT(*F); 1032 for (auto &BB : *F) { 1033 if (BB.getName() == "LOOP") { 1034 EXPECT_EQ(isGuaranteedNotToBePoison(A, nullptr, A, &DT), true) 1035 << "isGuaranteedNotToBePoison does not hold"; 1036 } 1037 } 1038 } 1039 1040 TEST_F(ValueTrackingTest, isGuaranteedNotToBeUndefOrPoison) { 1041 parseAssembly("declare void @f(i32 noundef)" 1042 "define void @test(i32 %x) {\n" 1043 " %A = bitcast i32 %x to i32\n" 1044 " call void @f(i32 noundef %x)\n" 1045 " ret void\n" 1046 "}\n"); 1047 EXPECT_EQ(isGuaranteedNotToBeUndefOrPoison(A), true); 1048 EXPECT_EQ(isGuaranteedNotToBeUndefOrPoison(UndefValue::get(IntegerType::get(Context, 8))), false); 1049 EXPECT_EQ(isGuaranteedNotToBeUndefOrPoison(PoisonValue::get(IntegerType::get(Context, 8))), false); 1050 EXPECT_EQ(isGuaranteedNotToBePoison(UndefValue::get(IntegerType::get(Context, 8))), true); 1051 EXPECT_EQ(isGuaranteedNotToBePoison(PoisonValue::get(IntegerType::get(Context, 8))), false); 1052 1053 Type *Int32Ty = Type::getInt32Ty(Context); 1054 Constant *CU = UndefValue::get(Int32Ty); 1055 Constant *CP = PoisonValue::get(Int32Ty); 1056 Constant *C1 = ConstantInt::get(Int32Ty, 1); 1057 Constant *C2 = ConstantInt::get(Int32Ty, 2); 1058 1059 { 1060 Constant *V1 = ConstantVector::get({C1, C2}); 1061 EXPECT_TRUE(isGuaranteedNotToBeUndefOrPoison(V1)); 1062 EXPECT_TRUE(isGuaranteedNotToBePoison(V1)); 1063 } 1064 1065 { 1066 Constant *V2 = ConstantVector::get({C1, CU}); 1067 EXPECT_FALSE(isGuaranteedNotToBeUndefOrPoison(V2)); 1068 EXPECT_TRUE(isGuaranteedNotToBePoison(V2)); 1069 } 1070 1071 { 1072 Constant *V3 = ConstantVector::get({C1, CP}); 1073 EXPECT_FALSE(isGuaranteedNotToBeUndefOrPoison(V3)); 1074 EXPECT_FALSE(isGuaranteedNotToBePoison(V3)); 1075 } 1076 } 1077 1078 TEST_F(ValueTrackingTest, isGuaranteedNotToBeUndefOrPoison_assume) { 1079 parseAssembly("declare i1 @f_i1()\n" 1080 "declare i32 @f_i32()\n" 1081 "declare void @llvm.assume(i1)\n" 1082 "define void @test() {\n" 1083 " %A = call i32 @f_i32()\n" 1084 " %cond = call i1 @f_i1()\n" 1085 " %CxtI = add i32 0, 0\n" 1086 " br i1 %cond, label %BB1, label %EXIT\n" 1087 "BB1:\n" 1088 " %CxtI2 = add i32 0, 0\n" 1089 " %cond2 = call i1 @f_i1()\n" 1090 " call void @llvm.assume(i1 true) [ \"noundef\"(i32 %A) ]\n" 1091 " br i1 %cond2, label %BB2, label %EXIT\n" 1092 "BB2:\n" 1093 " %CxtI3 = add i32 0, 0\n" 1094 " ret void\n" 1095 "EXIT:\n" 1096 " ret void\n" 1097 "}"); 1098 AssumptionCache AC(*F); 1099 DominatorTree DT(*F); 1100 EXPECT_FALSE(isGuaranteedNotToBeUndefOrPoison(A, &AC, CxtI, &DT)); 1101 EXPECT_FALSE(isGuaranteedNotToBeUndefOrPoison(A, &AC, CxtI2, &DT)); 1102 EXPECT_TRUE(isGuaranteedNotToBeUndefOrPoison(A, &AC, CxtI3, &DT)); 1103 } 1104 1105 TEST(ValueTracking, canCreatePoisonOrUndef) { 1106 std::string AsmHead = 1107 "@s = external dso_local global i32, align 1\n" 1108 "declare i32 @g(i32)\n" 1109 "declare {i32, i1} @llvm.sadd.with.overflow.i32(i32 %a, i32 %b)\n" 1110 "declare {i32, i1} @llvm.ssub.with.overflow.i32(i32 %a, i32 %b)\n" 1111 "declare {i32, i1} @llvm.smul.with.overflow.i32(i32 %a, i32 %b)\n" 1112 "declare {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 %b)\n" 1113 "declare {i32, i1} @llvm.usub.with.overflow.i32(i32 %a, i32 %b)\n" 1114 "declare {i32, i1} @llvm.umul.with.overflow.i32(i32 %a, i32 %b)\n" 1115 "define void @f(i32 %x, i32 %y, float %fx, float %fy, i1 %cond, " 1116 "<4 x i32> %vx, <4 x i32> %vx2, <vscale x 4 x i32> %svx, ptr %p) {\n"; 1117 std::string AsmTail = " ret void\n}"; 1118 // (can create poison?, can create undef?, IR instruction) 1119 SmallVector<std::pair<std::pair<bool, bool>, std::string>, 32> Data = { 1120 {{false, false}, "add i32 %x, %y"}, 1121 {{true, false}, "add nsw nuw i32 %x, %y"}, 1122 {{true, false}, "shl i32 %x, %y"}, 1123 {{true, false}, "shl <4 x i32> %vx, %vx2"}, 1124 {{true, false}, "shl nsw i32 %x, %y"}, 1125 {{true, false}, "shl nsw <4 x i32> %vx, <i32 0, i32 1, i32 2, i32 3>"}, 1126 {{false, false}, "shl i32 %x, 31"}, 1127 {{true, false}, "shl i32 %x, 32"}, 1128 {{false, false}, "shl <4 x i32> %vx, <i32 0, i32 1, i32 2, i32 3>"}, 1129 {{true, false}, "shl <4 x i32> %vx, <i32 0, i32 1, i32 2, i32 32>"}, 1130 {{true, false}, "ashr i32 %x, %y"}, 1131 {{true, false}, "ashr exact i32 %x, %y"}, 1132 {{false, false}, "ashr i32 %x, 31"}, 1133 {{true, false}, "ashr exact i32 %x, 31"}, 1134 {{false, false}, "ashr <4 x i32> %vx, <i32 0, i32 1, i32 2, i32 3>"}, 1135 {{true, false}, "ashr <4 x i32> %vx, <i32 0, i32 1, i32 2, i32 32>"}, 1136 {{true, false}, "ashr exact <4 x i32> %vx, <i32 0, i32 1, i32 2, i32 3>"}, 1137 {{true, false}, "lshr i32 %x, %y"}, 1138 {{true, false}, "lshr exact i32 %x, 31"}, 1139 {{false, false}, "udiv i32 %x, %y"}, 1140 {{true, false}, "udiv exact i32 %x, %y"}, 1141 {{false, false}, "getelementptr i8, ptr %p, i32 %x"}, 1142 {{true, false}, "getelementptr inbounds i8, ptr %p, i32 %x"}, 1143 {{true, false}, "fneg nnan float %fx"}, 1144 {{false, false}, "fneg float %fx"}, 1145 {{false, false}, "fadd float %fx, %fy"}, 1146 {{true, false}, "fadd nnan float %fx, %fy"}, 1147 {{false, false}, "urem i32 %x, %y"}, 1148 {{true, false}, "fptoui float %fx to i32"}, 1149 {{true, false}, "fptosi float %fx to i32"}, 1150 {{false, false}, "bitcast float %fx to i32"}, 1151 {{false, false}, "select i1 %cond, i32 %x, i32 %y"}, 1152 {{true, false}, "select nnan i1 %cond, float %fx, float %fy"}, 1153 {{true, false}, "extractelement <4 x i32> %vx, i32 %x"}, 1154 {{false, false}, "extractelement <4 x i32> %vx, i32 3"}, 1155 {{true, false}, "extractelement <vscale x 4 x i32> %svx, i32 4"}, 1156 {{true, false}, "insertelement <4 x i32> %vx, i32 %x, i32 %y"}, 1157 {{false, false}, "insertelement <4 x i32> %vx, i32 %x, i32 3"}, 1158 {{true, false}, "insertelement <vscale x 4 x i32> %svx, i32 %x, i32 4"}, 1159 {{false, false}, "freeze i32 %x"}, 1160 {{false, false}, 1161 "shufflevector <4 x i32> %vx, <4 x i32> %vx2, " 1162 "<4 x i32> <i32 0, i32 1, i32 2, i32 3>"}, 1163 {{false, true}, 1164 "shufflevector <4 x i32> %vx, <4 x i32> %vx2, " 1165 "<4 x i32> <i32 0, i32 1, i32 2, i32 undef>"}, 1166 {{false, true}, 1167 "shufflevector <vscale x 4 x i32> %svx, " 1168 "<vscale x 4 x i32> %svx, <vscale x 4 x i32> undef"}, 1169 {{true, false}, "call i32 @g(i32 %x)"}, 1170 {{false, false}, "call noundef i32 @g(i32 %x)"}, 1171 {{true, false}, "fcmp nnan oeq float %fx, %fy"}, 1172 {{false, false}, "fcmp oeq float %fx, %fy"}, 1173 {{true, false}, "ashr i32 %x, ptrtoint (ptr @s to i32)"}, 1174 {{false, false}, 1175 "call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %x, i32 %y)"}, 1176 {{false, false}, 1177 "call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %x, i32 %y)"}, 1178 {{false, false}, 1179 "call {i32, i1} @llvm.smul.with.overflow.i32(i32 %x, i32 %y)"}, 1180 {{false, false}, 1181 "call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %x, i32 %y)"}, 1182 {{false, false}, 1183 "call {i32, i1} @llvm.usub.with.overflow.i32(i32 %x, i32 %y)"}, 1184 {{false, false}, 1185 "call {i32, i1} @llvm.umul.with.overflow.i32(i32 %x, i32 %y)"}}; 1186 1187 std::string AssemblyStr = AsmHead; 1188 for (auto &Itm : Data) 1189 AssemblyStr += Itm.second + "\n"; 1190 AssemblyStr += AsmTail; 1191 1192 LLVMContext Context; 1193 SMDiagnostic Error; 1194 auto M = parseAssemblyString(AssemblyStr, Error, Context); 1195 assert(M && "Bad assembly?"); 1196 1197 auto *F = M->getFunction("f"); 1198 assert(F && "Bad assembly?"); 1199 1200 auto &BB = F->getEntryBlock(); 1201 1202 int Index = 0; 1203 for (auto &I : BB) { 1204 if (isa<ReturnInst>(&I)) 1205 break; 1206 bool Poison = Data[Index].first.first; 1207 bool Undef = Data[Index].first.second; 1208 EXPECT_EQ(canCreatePoison(cast<Operator>(&I)), Poison) 1209 << "Incorrect answer of canCreatePoison at instruction " << Index 1210 << " = " << I; 1211 EXPECT_EQ(canCreateUndefOrPoison(cast<Operator>(&I)), Undef || Poison) 1212 << "Incorrect answer of canCreateUndef at instruction " << Index 1213 << " = " << I; 1214 Index++; 1215 } 1216 } 1217 1218 TEST_F(ValueTrackingTest, computePtrAlignment) { 1219 parseAssembly("declare i1 @f_i1()\n" 1220 "declare ptr @f_i8p()\n" 1221 "declare void @llvm.assume(i1)\n" 1222 "define void @test() {\n" 1223 " %A = call ptr @f_i8p()\n" 1224 " %cond = call i1 @f_i1()\n" 1225 " %CxtI = add i32 0, 0\n" 1226 " br i1 %cond, label %BB1, label %EXIT\n" 1227 "BB1:\n" 1228 " %CxtI2 = add i32 0, 0\n" 1229 " %cond2 = call i1 @f_i1()\n" 1230 " call void @llvm.assume(i1 true) [ \"align\"(ptr %A, i64 16) ]\n" 1231 " br i1 %cond2, label %BB2, label %EXIT\n" 1232 "BB2:\n" 1233 " %CxtI3 = add i32 0, 0\n" 1234 " ret void\n" 1235 "EXIT:\n" 1236 " ret void\n" 1237 "}"); 1238 AssumptionCache AC(*F); 1239 DominatorTree DT(*F); 1240 const DataLayout &DL = M->getDataLayout(); 1241 EXPECT_EQ(getKnownAlignment(A, DL, CxtI, &AC, &DT), Align(1)); 1242 EXPECT_EQ(getKnownAlignment(A, DL, CxtI2, &AC, &DT), Align(1)); 1243 EXPECT_EQ(getKnownAlignment(A, DL, CxtI3, &AC, &DT), Align(16)); 1244 } 1245 1246 TEST_F(ComputeKnownBitsTest, ComputeKnownBits) { 1247 parseAssembly( 1248 "define i32 @test(i32 %a, i32 %b) {\n" 1249 " %ash = mul i32 %a, 8\n" 1250 " %aad = add i32 %ash, 7\n" 1251 " %aan = and i32 %aad, 4095\n" 1252 " %bsh = shl i32 %b, 4\n" 1253 " %bad = or i32 %bsh, 6\n" 1254 " %ban = and i32 %bad, 4095\n" 1255 " %A = mul i32 %aan, %ban\n" 1256 " ret i32 %A\n" 1257 "}\n"); 1258 expectKnownBits(/*zero*/ 4278190085u, /*one*/ 10u); 1259 } 1260 1261 TEST_F(ComputeKnownBitsTest, ComputeKnownMulBits) { 1262 parseAssembly( 1263 "define i32 @test(i32 %a, i32 %b) {\n" 1264 " %aa = shl i32 %a, 5\n" 1265 " %bb = shl i32 %b, 5\n" 1266 " %aaa = or i32 %aa, 24\n" 1267 " %bbb = or i32 %bb, 28\n" 1268 " %A = mul i32 %aaa, %bbb\n" 1269 " ret i32 %A\n" 1270 "}\n"); 1271 expectKnownBits(/*zero*/ 95u, /*one*/ 32u); 1272 } 1273 1274 TEST_F(ComputeKnownFPClassTest, SelectPos0) { 1275 parseAssembly( 1276 "define float @test(i1 %cond) {\n" 1277 " %A = select i1 %cond, float 0.0, float 0.0" 1278 " ret float %A\n" 1279 "}\n"); 1280 expectKnownFPClass(fcPosZero, false); 1281 } 1282 1283 TEST_F(ComputeKnownFPClassTest, SelectNeg0) { 1284 parseAssembly( 1285 "define float @test(i1 %cond) {\n" 1286 " %A = select i1 %cond, float -0.0, float -0.0" 1287 " ret float %A\n" 1288 "}\n"); 1289 expectKnownFPClass(fcNegZero, true); 1290 } 1291 1292 TEST_F(ComputeKnownFPClassTest, SelectPosOrNeg0) { 1293 parseAssembly( 1294 "define float @test(i1 %cond) {\n" 1295 " %A = select i1 %cond, float 0.0, float -0.0" 1296 " ret float %A\n" 1297 "}\n"); 1298 expectKnownFPClass(fcZero, std::nullopt); 1299 } 1300 1301 TEST_F(ComputeKnownFPClassTest, SelectPosInf) { 1302 parseAssembly( 1303 "define float @test(i1 %cond) {\n" 1304 " %A = select i1 %cond, float 0x7FF0000000000000, float 0x7FF0000000000000" 1305 " ret float %A\n" 1306 "}\n"); 1307 expectKnownFPClass(fcPosInf, false); 1308 } 1309 1310 TEST_F(ComputeKnownFPClassTest, SelectNegInf) { 1311 parseAssembly( 1312 "define float @test(i1 %cond) {\n" 1313 " %A = select i1 %cond, float 0xFFF0000000000000, float 0xFFF0000000000000" 1314 " ret float %A\n" 1315 "}\n"); 1316 expectKnownFPClass(fcNegInf, true); 1317 } 1318 1319 TEST_F(ComputeKnownFPClassTest, SelectPosOrNegInf) { 1320 parseAssembly( 1321 "define float @test(i1 %cond) {\n" 1322 " %A = select i1 %cond, float 0x7FF0000000000000, float 0xFFF0000000000000" 1323 " ret float %A\n" 1324 "}\n"); 1325 expectKnownFPClass(fcInf, std::nullopt); 1326 } 1327 1328 TEST_F(ComputeKnownFPClassTest, SelectNNaN) { 1329 parseAssembly( 1330 "define float @test(i1 %cond, float %arg0, float %arg1) {\n" 1331 " %A = select nnan i1 %cond, float %arg0, float %arg1" 1332 " ret float %A\n" 1333 "}\n"); 1334 expectKnownFPClass(~fcNan, std::nullopt); 1335 } 1336 1337 TEST_F(ComputeKnownFPClassTest, SelectNInf) { 1338 parseAssembly( 1339 "define float @test(i1 %cond, float %arg0, float %arg1) {\n" 1340 " %A = select ninf i1 %cond, float %arg0, float %arg1" 1341 " ret float %A\n" 1342 "}\n"); 1343 expectKnownFPClass(~fcInf, std::nullopt); 1344 } 1345 1346 TEST_F(ComputeKnownFPClassTest, SelectNNaNNInf) { 1347 parseAssembly( 1348 "define float @test(i1 %cond, float %arg0, float %arg1) {\n" 1349 " %A = select nnan ninf i1 %cond, float %arg0, float %arg1" 1350 " ret float %A\n" 1351 "}\n"); 1352 expectKnownFPClass(~(fcNan | fcInf), std::nullopt); 1353 } 1354 1355 TEST_F(ComputeKnownFPClassTest, SelectNoFPClassArgUnionAll) { 1356 parseAssembly( 1357 "define float @test(i1 %cond, float nofpclass(snan ninf nsub pzero pnorm) %arg0, float nofpclass(qnan nnorm nzero psub pinf) %arg1) {\n" 1358 " %A = select i1 %cond, float %arg0, float %arg1" 1359 " ret float %A\n" 1360 "}\n"); 1361 expectKnownFPClass(fcAllFlags, std::nullopt); 1362 } 1363 1364 TEST_F(ComputeKnownFPClassTest, SelectNoFPClassArgNoNan) { 1365 parseAssembly( 1366 "define float @test(i1 %cond, float nofpclass(nan) %arg0, float nofpclass(nan) %arg1) {\n" 1367 " %A = select i1 %cond, float %arg0, float %arg1" 1368 " ret float %A\n" 1369 "}\n"); 1370 expectKnownFPClass(~fcNan, std::nullopt); 1371 } 1372 1373 TEST_F(ComputeKnownFPClassTest, SelectNoFPClassArgNoPInf) { 1374 parseAssembly( 1375 "define float @test(i1 %cond, float nofpclass(inf) %arg0, float nofpclass(pinf) %arg1) {\n" 1376 " %A = select i1 %cond, float %arg0, float %arg1" 1377 " ret float %A\n" 1378 "}\n"); 1379 expectKnownFPClass(~fcPosInf, std::nullopt); 1380 } 1381 1382 TEST_F(ComputeKnownFPClassTest, SelectNoFPClassArgNoNInf) { 1383 parseAssembly( 1384 "define float @test(i1 %cond, float nofpclass(ninf) %arg0, float nofpclass(inf) %arg1) {\n" 1385 " %A = select i1 %cond, float %arg0, float %arg1" 1386 " ret float %A\n" 1387 "}\n"); 1388 expectKnownFPClass(~fcNegInf, std::nullopt); 1389 } 1390 1391 TEST_F(ComputeKnownFPClassTest, SelectNoFPClassCallSiteNoNan) { 1392 parseAssembly( 1393 "declare float @func()\n" 1394 "define float @test() {\n" 1395 " %A = call nofpclass(nan) float @func()\n" 1396 " ret float %A\n" 1397 "}\n"); 1398 expectKnownFPClass(~fcNan, std::nullopt); 1399 } 1400 1401 TEST_F(ComputeKnownFPClassTest, SelectNoFPClassCallSiteNoZeros) { 1402 parseAssembly( 1403 "declare float @func()\n" 1404 "define float @test() {\n" 1405 " %A = call nofpclass(zero) float @func()\n" 1406 " ret float %A\n" 1407 "}\n"); 1408 expectKnownFPClass(~fcZero, std::nullopt); 1409 } 1410 1411 TEST_F(ComputeKnownFPClassTest, SelectNoFPClassDeclarationNoNan) { 1412 parseAssembly( 1413 "declare nofpclass(nan) float @no_nans()\n" 1414 "define float @test() {\n" 1415 " %A = call float @no_nans()\n" 1416 " ret float %A\n" 1417 "}\n"); 1418 expectKnownFPClass(~fcNan, std::nullopt); 1419 } 1420 1421 // Check nofpclass + ninf works on a callsite 1422 TEST_F(ComputeKnownFPClassTest, SelectNoFPClassCallSiteNoZerosNInfFlags) { 1423 parseAssembly( 1424 "declare float @func()\n" 1425 "define float @test() {\n" 1426 " %A = call ninf nofpclass(zero) float @func()\n" 1427 " ret float %A\n" 1428 "}\n"); 1429 expectKnownFPClass(~(fcZero | fcInf), std::nullopt); 1430 } 1431 1432 TEST_F(ComputeKnownFPClassTest, FNegNInf) { 1433 parseAssembly( 1434 "define float @test(float %arg) {\n" 1435 " %A = fneg ninf float %arg" 1436 " ret float %A\n" 1437 "}\n"); 1438 expectKnownFPClass(~fcInf, std::nullopt); 1439 } 1440 1441 TEST_F(ComputeKnownFPClassTest, FabsUnknown) { 1442 parseAssembly( 1443 "declare float @llvm.fabs.f32(float)" 1444 "define float @test(float %arg) {\n" 1445 " %A = call float @llvm.fabs.f32(float %arg)" 1446 " ret float %A\n" 1447 "}\n"); 1448 expectKnownFPClass(fcAllFlags, false); 1449 } 1450 1451 TEST_F(ComputeKnownFPClassTest, FNegFabsUnknown) { 1452 parseAssembly( 1453 "declare float @llvm.fabs.f32(float)" 1454 "define float @test(float %arg) {\n" 1455 " %fabs = call float @llvm.fabs.f32(float %arg)" 1456 " %A = fneg float %fabs" 1457 " ret float %A\n" 1458 "}\n"); 1459 expectKnownFPClass(fcAllFlags, true); 1460 } 1461 1462 TEST_F(ComputeKnownFPClassTest, NegFabsNInf) { 1463 parseAssembly( 1464 "declare float @llvm.fabs.f32(float)" 1465 "define float @test(float %arg) {\n" 1466 " %fabs = call ninf float @llvm.fabs.f32(float %arg)" 1467 " %A = fneg float %fabs" 1468 " ret float %A\n" 1469 "}\n"); 1470 expectKnownFPClass(~fcInf, true); 1471 } 1472 1473 TEST_F(ComputeKnownFPClassTest, FNegFabsNNaN) { 1474 parseAssembly( 1475 "declare float @llvm.fabs.f32(float)" 1476 "define float @test(float %arg) {\n" 1477 " %fabs = call nnan float @llvm.fabs.f32(float %arg)" 1478 " %A = fneg float %fabs" 1479 " ret float %A\n" 1480 "}\n"); 1481 expectKnownFPClass(~fcNan, true); 1482 } 1483 1484 TEST_F(ComputeKnownFPClassTest, CopySignNNanSrc0) { 1485 parseAssembly( 1486 "declare float @llvm.fabs.f32(float)\n" 1487 "declare float @llvm.copysign.f32(float, float)\n" 1488 "define float @test(float %arg0, float %arg1) {\n" 1489 " %fabs = call nnan float @llvm.fabs.f32(float %arg0)" 1490 " %A = call float @llvm.copysign.f32(float %fabs, float %arg1)" 1491 " ret float %A\n" 1492 "}\n"); 1493 expectKnownFPClass(~fcNan, std::nullopt); 1494 } 1495 1496 TEST_F(ComputeKnownFPClassTest, CopySignNInfSrc0_NegSign) { 1497 parseAssembly( 1498 "declare float @llvm.sqrt.f32(float)\n" 1499 "declare float @llvm.copysign.f32(float, float)\n" 1500 "define float @test(float %arg0, float %arg1) {\n" 1501 " %ninf = call ninf float @llvm.sqrt.f32(float %arg0)" 1502 " %A = call float @llvm.copysign.f32(float %ninf, float -1.0)" 1503 " ret float %A\n" 1504 "}\n"); 1505 expectKnownFPClass(fcNegFinite, true); 1506 } 1507 1508 TEST_F(ComputeKnownFPClassTest, CopySignNInfSrc0_PosSign) { 1509 parseAssembly( 1510 "declare float @llvm.sqrt.f32(float)\n" 1511 "declare float @llvm.copysign.f32(float, float)\n" 1512 "define float @test(float %arg0, float %arg1) {\n" 1513 " %ninf = call ninf float @llvm.sqrt.f32(float %arg0)" 1514 " %A = call float @llvm.copysign.f32(float %ninf, float 1.0)" 1515 " ret float %A\n" 1516 "}\n"); 1517 expectKnownFPClass(fcPosFinite, false); 1518 } 1519 1520 TEST_F(ComputeKnownFPClassTest, UIToFP) { 1521 parseAssembly( 1522 "define float @test(i32 %arg0, i16 %arg1) {\n" 1523 " %A = uitofp i32 %arg0 to float" 1524 " %A2 = uitofp i16 %arg1 to half" 1525 " ret float %A\n" 1526 "}\n"); 1527 expectKnownFPClass(fcPosFinite, false, A); 1528 expectKnownFPClass(fcPositive, false, A2); 1529 } 1530 1531 TEST_F(ComputeKnownFPClassTest, SIToFP) { 1532 parseAssembly( 1533 "define float @test(i32 %arg0, i16 %arg1, i17 %arg2) {\n" 1534 " %A = sitofp i32 %arg0 to float" 1535 " %A2 = sitofp i16 %arg1 to half" 1536 " %A3 = sitofp i17 %arg2 to half" 1537 " ret float %A\n" 1538 "}\n"); 1539 expectKnownFPClass(fcFinite, std::nullopt, A); 1540 expectKnownFPClass(fcFinite, std::nullopt, A2); 1541 expectKnownFPClass(~fcNan, std::nullopt, A3); 1542 } 1543 1544 TEST_F(ComputeKnownFPClassTest, FAdd) { 1545 parseAssembly( 1546 "define float @test(float nofpclass(nan inf) %nnan.ninf, float nofpclass(nan) %nnan, float nofpclass(qnan) %no.qnan, float %unknown) {\n" 1547 " %A = fadd float %nnan, %nnan.ninf" 1548 " %A2 = fadd float %nnan.ninf, %nnan" 1549 " %A3 = fadd float %nnan.ninf, %unknown" 1550 " %A4 = fadd float %nnan.ninf, %no.qnan" 1551 " %A5 = fadd float %nnan, %nnan" 1552 " ret float %A\n" 1553 "}\n"); 1554 expectKnownFPClass(fcFinite | fcInf, std::nullopt, A); 1555 expectKnownFPClass(fcFinite | fcInf, std::nullopt, A2); 1556 expectKnownFPClass(fcAllFlags, std::nullopt, A3); 1557 expectKnownFPClass(fcAllFlags, std::nullopt, A4); 1558 expectKnownFPClass(fcAllFlags, std::nullopt, A5); 1559 } 1560 1561 TEST_F(ComputeKnownFPClassTest, FSub) { 1562 parseAssembly( 1563 "define float @test(float nofpclass(nan inf) %nnan.ninf, float nofpclass(nan) %nnan, float nofpclass(qnan) %no.qnan, float %unknown) {\n" 1564 " %A = fsub float %nnan, %nnan.ninf" 1565 " %A2 = fsub float %nnan.ninf, %nnan" 1566 " %A3 = fsub float %nnan.ninf, %unknown" 1567 " %A4 = fsub float %nnan.ninf, %no.qnan" 1568 " %A5 = fsub float %nnan, %nnan" 1569 " ret float %A\n" 1570 "}\n"); 1571 expectKnownFPClass(fcFinite | fcInf, std::nullopt, A); 1572 expectKnownFPClass(fcFinite | fcInf, std::nullopt, A2); 1573 expectKnownFPClass(fcAllFlags, std::nullopt, A3); 1574 expectKnownFPClass(fcAllFlags, std::nullopt, A4); 1575 expectKnownFPClass(fcAllFlags, std::nullopt, A5); 1576 } 1577 1578 TEST_F(ValueTrackingTest, isNonZeroRecurrence) { 1579 parseAssembly(R"( 1580 define i1 @test(i8 %n, i8 %r) { 1581 entry: 1582 br label %loop 1583 loop: 1584 %p = phi i8 [ -1, %entry ], [ %next, %loop ] 1585 %next = add nsw i8 %p, -1 1586 %cmp1 = icmp eq i8 %p, %n 1587 br i1 %cmp1, label %exit, label %loop 1588 exit: 1589 %A = or i8 %p, %r 1590 %CxtI = icmp eq i8 %A, 0 1591 ret i1 %CxtI 1592 } 1593 )"); 1594 const DataLayout &DL = M->getDataLayout(); 1595 AssumptionCache AC(*F); 1596 EXPECT_TRUE(isKnownNonZero(A, DL, 0, &AC, CxtI)); 1597 } 1598 1599 TEST_F(ValueTrackingTest, KnownNonZeroFromDomCond) { 1600 parseAssembly(R"( 1601 declare ptr @f_i8() 1602 define void @test(i1 %c) { 1603 %A = call ptr @f_i8() 1604 %B = call ptr @f_i8() 1605 %c1 = icmp ne ptr %A, null 1606 %cond = and i1 %c1, %c 1607 br i1 %cond, label %T, label %Q 1608 T: 1609 %CxtI = add i32 0, 0 1610 ret void 1611 Q: 1612 %CxtI2 = add i32 0, 0 1613 ret void 1614 } 1615 )"); 1616 AssumptionCache AC(*F); 1617 DominatorTree DT(*F); 1618 const DataLayout &DL = M->getDataLayout(); 1619 EXPECT_EQ(isKnownNonZero(A, DL, 0, &AC, CxtI, &DT), true); 1620 EXPECT_EQ(isKnownNonZero(A, DL, 0, &AC, CxtI2, &DT), false); 1621 } 1622 1623 TEST_F(ValueTrackingTest, KnownNonZeroFromDomCond2) { 1624 parseAssembly(R"( 1625 declare ptr @f_i8() 1626 define void @test(i1 %c) { 1627 %A = call ptr @f_i8() 1628 %B = call ptr @f_i8() 1629 %c1 = icmp ne ptr %A, null 1630 %cond = select i1 %c, i1 %c1, i1 false 1631 br i1 %cond, label %T, label %Q 1632 T: 1633 %CxtI = add i32 0, 0 1634 ret void 1635 Q: 1636 %CxtI2 = add i32 0, 0 1637 ret void 1638 } 1639 )"); 1640 AssumptionCache AC(*F); 1641 DominatorTree DT(*F); 1642 const DataLayout &DL = M->getDataLayout(); 1643 EXPECT_EQ(isKnownNonZero(A, DL, 0, &AC, CxtI, &DT), true); 1644 EXPECT_EQ(isKnownNonZero(A, DL, 0, &AC, CxtI2, &DT), false); 1645 } 1646 1647 TEST_F(ValueTrackingTest, IsImpliedConditionAnd) { 1648 parseAssembly(R"( 1649 define void @test(i32 %x, i32 %y) { 1650 %c1 = icmp ult i32 %x, 10 1651 %c2 = icmp ult i32 %y, 15 1652 %A = and i1 %c1, %c2 1653 ; x < 10 /\ y < 15 1654 %A2 = icmp ult i32 %x, 20 1655 %A3 = icmp uge i32 %y, 20 1656 %A4 = icmp ult i32 %x, 5 1657 ret void 1658 } 1659 )"); 1660 const DataLayout &DL = M->getDataLayout(); 1661 EXPECT_EQ(isImpliedCondition(A, A2, DL), true); 1662 EXPECT_EQ(isImpliedCondition(A, A3, DL), false); 1663 EXPECT_EQ(isImpliedCondition(A, A4, DL), std::nullopt); 1664 } 1665 1666 TEST_F(ValueTrackingTest, IsImpliedConditionAnd2) { 1667 parseAssembly(R"( 1668 define void @test(i32 %x, i32 %y) { 1669 %c1 = icmp ult i32 %x, 10 1670 %c2 = icmp ult i32 %y, 15 1671 %A = select i1 %c1, i1 %c2, i1 false 1672 ; x < 10 /\ y < 15 1673 %A2 = icmp ult i32 %x, 20 1674 %A3 = icmp uge i32 %y, 20 1675 %A4 = icmp ult i32 %x, 5 1676 ret void 1677 } 1678 )"); 1679 const DataLayout &DL = M->getDataLayout(); 1680 EXPECT_EQ(isImpliedCondition(A, A2, DL), true); 1681 EXPECT_EQ(isImpliedCondition(A, A3, DL), false); 1682 EXPECT_EQ(isImpliedCondition(A, A4, DL), std::nullopt); 1683 } 1684 1685 TEST_F(ValueTrackingTest, IsImpliedConditionAndVec) { 1686 parseAssembly(R"( 1687 define void @test(<2 x i8> %x, <2 x i8> %y) { 1688 %A = icmp ult <2 x i8> %x, %y 1689 %A2 = icmp ule <2 x i8> %x, %y 1690 ret void 1691 } 1692 )"); 1693 const DataLayout &DL = M->getDataLayout(); 1694 EXPECT_EQ(isImpliedCondition(A, A2, DL), true); 1695 } 1696 1697 TEST_F(ValueTrackingTest, IsImpliedConditionOr) { 1698 parseAssembly(R"( 1699 define void @test(i32 %x, i32 %y) { 1700 %c1 = icmp ult i32 %x, 10 1701 %c2 = icmp ult i32 %y, 15 1702 %A = or i1 %c1, %c2 ; negated 1703 ; x >= 10 /\ y >= 15 1704 %A2 = icmp ult i32 %x, 5 1705 %A3 = icmp uge i32 %y, 10 1706 %A4 = icmp ult i32 %x, 15 1707 ret void 1708 } 1709 )"); 1710 const DataLayout &DL = M->getDataLayout(); 1711 EXPECT_EQ(isImpliedCondition(A, A2, DL, false), false); 1712 EXPECT_EQ(isImpliedCondition(A, A3, DL, false), true); 1713 EXPECT_EQ(isImpliedCondition(A, A4, DL, false), std::nullopt); 1714 } 1715 1716 TEST_F(ValueTrackingTest, IsImpliedConditionOr2) { 1717 parseAssembly(R"( 1718 define void @test(i32 %x, i32 %y) { 1719 %c1 = icmp ult i32 %x, 10 1720 %c2 = icmp ult i32 %y, 15 1721 %A = select i1 %c1, i1 true, i1 %c2 ; negated 1722 ; x >= 10 /\ y >= 15 1723 %A2 = icmp ult i32 %x, 5 1724 %A3 = icmp uge i32 %y, 10 1725 %A4 = icmp ult i32 %x, 15 1726 ret void 1727 } 1728 )"); 1729 const DataLayout &DL = M->getDataLayout(); 1730 EXPECT_EQ(isImpliedCondition(A, A2, DL, false), false); 1731 EXPECT_EQ(isImpliedCondition(A, A3, DL, false), true); 1732 EXPECT_EQ(isImpliedCondition(A, A4, DL, false), std::nullopt); 1733 } 1734 1735 TEST_F(ComputeKnownBitsTest, KnownNonZeroShift) { 1736 // %q is known nonzero without known bits. 1737 // Because %q is nonzero, %A[0] is known to be zero. 1738 parseAssembly( 1739 "define i8 @test(i8 %p, ptr %pq) {\n" 1740 " %q = load i8, ptr %pq, !range !0\n" 1741 " %A = shl i8 %p, %q\n" 1742 " ret i8 %A\n" 1743 "}\n" 1744 "!0 = !{ i8 1, i8 5 }\n"); 1745 expectKnownBits(/*zero*/ 1u, /*one*/ 0u); 1746 } 1747 1748 TEST_F(ComputeKnownBitsTest, ComputeKnownFshl) { 1749 // fshl(....1111....0000, 00..1111........, 6) 1750 // = 11....000000..11 1751 parseAssembly( 1752 "define i16 @test(i16 %a, i16 %b) {\n" 1753 " %aa = shl i16 %a, 4\n" 1754 " %bb = lshr i16 %b, 2\n" 1755 " %aaa = or i16 %aa, 3840\n" 1756 " %bbb = or i16 %bb, 3840\n" 1757 " %A = call i16 @llvm.fshl.i16(i16 %aaa, i16 %bbb, i16 6)\n" 1758 " ret i16 %A\n" 1759 "}\n" 1760 "declare i16 @llvm.fshl.i16(i16, i16, i16)\n"); 1761 expectKnownBits(/*zero*/ 1008u, /*one*/ 49155u); 1762 } 1763 1764 TEST_F(ComputeKnownBitsTest, ComputeKnownFshr) { 1765 // fshr(....1111....0000, 00..1111........, 26) 1766 // = 11....000000..11 1767 parseAssembly( 1768 "define i16 @test(i16 %a, i16 %b) {\n" 1769 " %aa = shl i16 %a, 4\n" 1770 " %bb = lshr i16 %b, 2\n" 1771 " %aaa = or i16 %aa, 3840\n" 1772 " %bbb = or i16 %bb, 3840\n" 1773 " %A = call i16 @llvm.fshr.i16(i16 %aaa, i16 %bbb, i16 26)\n" 1774 " ret i16 %A\n" 1775 "}\n" 1776 "declare i16 @llvm.fshr.i16(i16, i16, i16)\n"); 1777 expectKnownBits(/*zero*/ 1008u, /*one*/ 49155u); 1778 } 1779 1780 TEST_F(ComputeKnownBitsTest, ComputeKnownFshlZero) { 1781 // fshl(....1111....0000, 00..1111........, 0) 1782 // = ....1111....0000 1783 parseAssembly( 1784 "define i16 @test(i16 %a, i16 %b) {\n" 1785 " %aa = shl i16 %a, 4\n" 1786 " %bb = lshr i16 %b, 2\n" 1787 " %aaa = or i16 %aa, 3840\n" 1788 " %bbb = or i16 %bb, 3840\n" 1789 " %A = call i16 @llvm.fshl.i16(i16 %aaa, i16 %bbb, i16 0)\n" 1790 " ret i16 %A\n" 1791 "}\n" 1792 "declare i16 @llvm.fshl.i16(i16, i16, i16)\n"); 1793 expectKnownBits(/*zero*/ 15u, /*one*/ 3840u); 1794 } 1795 1796 TEST_F(ComputeKnownBitsTest, ComputeKnownUAddSatLeadingOnes) { 1797 // uadd.sat(1111...1, ........) 1798 // = 1111.... 1799 parseAssembly( 1800 "define i8 @test(i8 %a, i8 %b) {\n" 1801 " %aa = or i8 %a, 241\n" 1802 " %A = call i8 @llvm.uadd.sat.i8(i8 %aa, i8 %b)\n" 1803 " ret i8 %A\n" 1804 "}\n" 1805 "declare i8 @llvm.uadd.sat.i8(i8, i8)\n"); 1806 expectKnownBits(/*zero*/ 0u, /*one*/ 240u); 1807 } 1808 1809 TEST_F(ComputeKnownBitsTest, ComputeKnownUAddSatOnesPreserved) { 1810 // uadd.sat(00...011, .1...110) 1811 // = .......1 1812 parseAssembly( 1813 "define i8 @test(i8 %a, i8 %b) {\n" 1814 " %aa = or i8 %a, 3\n" 1815 " %aaa = and i8 %aa, 59\n" 1816 " %bb = or i8 %b, 70\n" 1817 " %bbb = and i8 %bb, 254\n" 1818 " %A = call i8 @llvm.uadd.sat.i8(i8 %aaa, i8 %bbb)\n" 1819 " ret i8 %A\n" 1820 "}\n" 1821 "declare i8 @llvm.uadd.sat.i8(i8, i8)\n"); 1822 expectKnownBits(/*zero*/ 0u, /*one*/ 1u); 1823 } 1824 1825 TEST_F(ComputeKnownBitsTest, ComputeKnownUSubSatLHSLeadingZeros) { 1826 // usub.sat(0000...0, ........) 1827 // = 0000.... 1828 parseAssembly( 1829 "define i8 @test(i8 %a, i8 %b) {\n" 1830 " %aa = and i8 %a, 14\n" 1831 " %A = call i8 @llvm.usub.sat.i8(i8 %aa, i8 %b)\n" 1832 " ret i8 %A\n" 1833 "}\n" 1834 "declare i8 @llvm.usub.sat.i8(i8, i8)\n"); 1835 expectKnownBits(/*zero*/ 240u, /*one*/ 0u); 1836 } 1837 1838 TEST_F(ComputeKnownBitsTest, ComputeKnownUSubSatRHSLeadingOnes) { 1839 // usub.sat(........, 1111...1) 1840 // = 0000.... 1841 parseAssembly( 1842 "define i8 @test(i8 %a, i8 %b) {\n" 1843 " %bb = or i8 %a, 241\n" 1844 " %A = call i8 @llvm.usub.sat.i8(i8 %a, i8 %bb)\n" 1845 " ret i8 %A\n" 1846 "}\n" 1847 "declare i8 @llvm.usub.sat.i8(i8, i8)\n"); 1848 expectKnownBits(/*zero*/ 240u, /*one*/ 0u); 1849 } 1850 1851 TEST_F(ComputeKnownBitsTest, ComputeKnownUSubSatZerosPreserved) { 1852 // usub.sat(11...011, .1...110) 1853 // = ......0. 1854 parseAssembly( 1855 "define i8 @test(i8 %a, i8 %b) {\n" 1856 " %aa = or i8 %a, 195\n" 1857 " %aaa = and i8 %aa, 251\n" 1858 " %bb = or i8 %b, 70\n" 1859 " %bbb = and i8 %bb, 254\n" 1860 " %A = call i8 @llvm.usub.sat.i8(i8 %aaa, i8 %bbb)\n" 1861 " ret i8 %A\n" 1862 "}\n" 1863 "declare i8 @llvm.usub.sat.i8(i8, i8)\n"); 1864 expectKnownBits(/*zero*/ 2u, /*one*/ 0u); 1865 } 1866 1867 TEST_F(ComputeKnownBitsTest, ComputeKnownBitsPtrToIntTrunc) { 1868 // ptrtoint truncates the pointer type. 1869 parseAssembly( 1870 "define void @test(ptr %p) {\n" 1871 " %A = load ptr, ptr %p\n" 1872 " %i = ptrtoint ptr %A to i32\n" 1873 " %m = and i32 %i, 31\n" 1874 " %c = icmp eq i32 %m, 0\n" 1875 " call void @llvm.assume(i1 %c)\n" 1876 " ret void\n" 1877 "}\n" 1878 "declare void @llvm.assume(i1)\n"); 1879 AssumptionCache AC(*F); 1880 KnownBits Known = computeKnownBits( 1881 A, M->getDataLayout(), /* Depth */ 0, &AC, F->front().getTerminator()); 1882 EXPECT_EQ(Known.Zero.getZExtValue(), 31u); 1883 EXPECT_EQ(Known.One.getZExtValue(), 0u); 1884 } 1885 1886 TEST_F(ComputeKnownBitsTest, ComputeKnownBitsPtrToIntZext) { 1887 // ptrtoint zero extends the pointer type. 1888 parseAssembly( 1889 "define void @test(ptr %p) {\n" 1890 " %A = load ptr, ptr %p\n" 1891 " %i = ptrtoint ptr %A to i128\n" 1892 " %m = and i128 %i, 31\n" 1893 " %c = icmp eq i128 %m, 0\n" 1894 " call void @llvm.assume(i1 %c)\n" 1895 " ret void\n" 1896 "}\n" 1897 "declare void @llvm.assume(i1)\n"); 1898 AssumptionCache AC(*F); 1899 KnownBits Known = computeKnownBits( 1900 A, M->getDataLayout(), /* Depth */ 0, &AC, F->front().getTerminator()); 1901 EXPECT_EQ(Known.Zero.getZExtValue(), 31u); 1902 EXPECT_EQ(Known.One.getZExtValue(), 0u); 1903 } 1904 1905 TEST_F(ComputeKnownBitsTest, ComputeKnownBitsFreeze) { 1906 parseAssembly("define void @test() {\n" 1907 " %m = call i32 @any_num()\n" 1908 " %A = freeze i32 %m\n" 1909 " %n = and i32 %m, 31\n" 1910 " %c = icmp eq i32 %n, 0\n" 1911 " call void @llvm.assume(i1 %c)\n" 1912 " ret void\n" 1913 "}\n" 1914 "declare void @llvm.assume(i1)\n" 1915 "declare i32 @any_num()\n"); 1916 AssumptionCache AC(*F); 1917 KnownBits Known = computeKnownBits(A, M->getDataLayout(), /* Depth */ 0, &AC, 1918 F->front().getTerminator()); 1919 EXPECT_EQ(Known.Zero.getZExtValue(), 31u); 1920 EXPECT_EQ(Known.One.getZExtValue(), 0u); 1921 } 1922 1923 TEST_F(ComputeKnownBitsTest, ComputeKnownBitsAddWithRange) { 1924 parseAssembly("define void @test(ptr %p) {\n" 1925 " %A = load i64, ptr %p, !range !{i64 64, i64 65536}\n" 1926 " %APlus512 = add i64 %A, 512\n" 1927 " %c = icmp ugt i64 %APlus512, 523\n" 1928 " call void @llvm.assume(i1 %c)\n" 1929 " ret void\n" 1930 "}\n" 1931 "declare void @llvm.assume(i1)\n"); 1932 AssumptionCache AC(*F); 1933 KnownBits Known = computeKnownBits(A, M->getDataLayout(), /* Depth */ 0, &AC, 1934 F->front().getTerminator()); 1935 EXPECT_EQ(Known.Zero.getZExtValue(), ~(65536llu - 1)); 1936 EXPECT_EQ(Known.One.getZExtValue(), 0u); 1937 Instruction &APlus512 = findInstructionByName(F, "APlus512"); 1938 Known = computeKnownBits(&APlus512, M->getDataLayout(), /* Depth */ 0, &AC, 1939 F->front().getTerminator()); 1940 // We know of one less zero because 512 may have produced a 1 that 1941 // got carried all the way to the first trailing zero. 1942 EXPECT_EQ(Known.Zero.getZExtValue(), (~(65536llu - 1)) << 1); 1943 EXPECT_EQ(Known.One.getZExtValue(), 0u); 1944 // The known range is not precise given computeKnownBits works 1945 // with the masks of zeros and ones, not the ranges. 1946 EXPECT_EQ(Known.getMinValue(), 0u); 1947 EXPECT_EQ(Known.getMaxValue(), 131071); 1948 } 1949 1950 TEST_F(ComputeKnownBitsTest, ComputeKnownBitsUnknownVScale) { 1951 Module M("", Context); 1952 IRBuilder<> Builder(Context); 1953 Function *TheFn = 1954 Intrinsic::getDeclaration(&M, Intrinsic::vscale, {Builder.getInt32Ty()}); 1955 CallInst *CI = Builder.CreateCall(TheFn, {}, {}, ""); 1956 1957 KnownBits Known = computeKnownBits(CI, M.getDataLayout(), /* Depth */ 0); 1958 // There is no parent function so we cannot look up the vscale_range 1959 // attribute to determine the number of bits. 1960 EXPECT_EQ(Known.One.getZExtValue(), 0u); 1961 EXPECT_EQ(Known.Zero.getZExtValue(), 0u); 1962 1963 BasicBlock *BB = BasicBlock::Create(Context); 1964 CI->insertInto(BB, BB->end()); 1965 Known = computeKnownBits(CI, M.getDataLayout(), /* Depth */ 0); 1966 // There is no parent function so we cannot look up the vscale_range 1967 // attribute to determine the number of bits. 1968 EXPECT_EQ(Known.One.getZExtValue(), 0u); 1969 EXPECT_EQ(Known.Zero.getZExtValue(), 0u); 1970 1971 CI->removeFromParent(); 1972 delete CI; 1973 delete BB; 1974 } 1975 1976 // 512 + [32, 64) doesn't produce overlapping bits. 1977 // Make sure we get all the individual bits properly. 1978 TEST_F(ComputeKnownBitsTest, ComputeKnownBitsAddWithRangeNoOverlap) { 1979 parseAssembly("define void @test(ptr %p) {\n" 1980 " %A = load i64, ptr %p, !range !{i64 32, i64 64}\n" 1981 " %APlus512 = add i64 %A, 512\n" 1982 " %c = icmp ugt i64 %APlus512, 523\n" 1983 " call void @llvm.assume(i1 %c)\n" 1984 " ret void\n" 1985 "}\n" 1986 "declare void @llvm.assume(i1)\n"); 1987 AssumptionCache AC(*F); 1988 KnownBits Known = computeKnownBits(A, M->getDataLayout(), /* Depth */ 0, &AC, 1989 F->front().getTerminator()); 1990 EXPECT_EQ(Known.Zero.getZExtValue(), ~(64llu - 1)); 1991 EXPECT_EQ(Known.One.getZExtValue(), 32u); 1992 Instruction &APlus512 = findInstructionByName(F, "APlus512"); 1993 Known = computeKnownBits(&APlus512, M->getDataLayout(), /* Depth */ 0, &AC, 1994 F->front().getTerminator()); 1995 EXPECT_EQ(Known.Zero.getZExtValue(), ~512llu & ~(64llu - 1)); 1996 EXPECT_EQ(Known.One.getZExtValue(), 512u | 32u); 1997 // The known range is not precise given computeKnownBits works 1998 // with the masks of zeros and ones, not the ranges. 1999 EXPECT_EQ(Known.getMinValue(), 544); 2000 EXPECT_EQ(Known.getMaxValue(), 575); 2001 } 2002 2003 TEST_F(ComputeKnownBitsTest, ComputeKnownBitsGEPWithRange) { 2004 parseAssembly( 2005 "define void @test(ptr %p) {\n" 2006 " %A = load i64, ptr %p, !range !{i64 64, i64 65536}\n" 2007 " %APtr = inttoptr i64 %A to float*" 2008 " %APtrPlus512 = getelementptr float, float* %APtr, i32 128\n" 2009 " %c = icmp ugt float* %APtrPlus512, inttoptr (i32 523 to float*)\n" 2010 " call void @llvm.assume(i1 %c)\n" 2011 " ret void\n" 2012 "}\n" 2013 "declare void @llvm.assume(i1)\n"); 2014 AssumptionCache AC(*F); 2015 KnownBits Known = computeKnownBits(A, M->getDataLayout(), /* Depth */ 0, &AC, 2016 F->front().getTerminator()); 2017 EXPECT_EQ(Known.Zero.getZExtValue(), ~(65536llu - 1)); 2018 EXPECT_EQ(Known.One.getZExtValue(), 0u); 2019 Instruction &APtrPlus512 = findInstructionByName(F, "APtrPlus512"); 2020 Known = computeKnownBits(&APtrPlus512, M->getDataLayout(), /* Depth */ 0, &AC, 2021 F->front().getTerminator()); 2022 // We know of one less zero because 512 may have produced a 1 that 2023 // got carried all the way to the first trailing zero. 2024 EXPECT_EQ(Known.Zero.getZExtValue(), ~(65536llu - 1) << 1); 2025 EXPECT_EQ(Known.One.getZExtValue(), 0u); 2026 // The known range is not precise given computeKnownBits works 2027 // with the masks of zeros and ones, not the ranges. 2028 EXPECT_EQ(Known.getMinValue(), 0u); 2029 EXPECT_EQ(Known.getMaxValue(), 131071); 2030 } 2031 2032 // 4*128 + [32, 64) doesn't produce overlapping bits. 2033 // Make sure we get all the individual bits properly. 2034 // This test is useful to check that we account for the scaling factor 2035 // in the gep. Indeed, gep float, [32,64), 128 is not 128 + [32,64). 2036 TEST_F(ComputeKnownBitsTest, ComputeKnownBitsGEPWithRangeNoOverlap) { 2037 parseAssembly( 2038 "define void @test(ptr %p) {\n" 2039 " %A = load i64, ptr %p, !range !{i64 32, i64 64}\n" 2040 " %APtr = inttoptr i64 %A to float*" 2041 " %APtrPlus512 = getelementptr float, float* %APtr, i32 128\n" 2042 " %c = icmp ugt float* %APtrPlus512, inttoptr (i32 523 to float*)\n" 2043 " call void @llvm.assume(i1 %c)\n" 2044 " ret void\n" 2045 "}\n" 2046 "declare void @llvm.assume(i1)\n"); 2047 AssumptionCache AC(*F); 2048 KnownBits Known = computeKnownBits(A, M->getDataLayout(), /* Depth */ 0, &AC, 2049 F->front().getTerminator()); 2050 EXPECT_EQ(Known.Zero.getZExtValue(), ~(64llu - 1)); 2051 EXPECT_EQ(Known.One.getZExtValue(), 32u); 2052 Instruction &APtrPlus512 = findInstructionByName(F, "APtrPlus512"); 2053 Known = computeKnownBits(&APtrPlus512, M->getDataLayout(), /* Depth */ 0, &AC, 2054 F->front().getTerminator()); 2055 EXPECT_EQ(Known.Zero.getZExtValue(), ~512llu & ~(64llu - 1)); 2056 EXPECT_EQ(Known.One.getZExtValue(), 512u | 32u); 2057 // The known range is not precise given computeKnownBits works 2058 // with the masks of zeros and ones, not the ranges. 2059 EXPECT_EQ(Known.getMinValue(), 544); 2060 EXPECT_EQ(Known.getMaxValue(), 575); 2061 } 2062 2063 TEST_F(ValueTrackingTest, HaveNoCommonBitsSet) { 2064 { 2065 // Check for an inverted mask: (X & ~M) op (Y & M). 2066 auto M = parseModule(R"( 2067 define i32 @test(i32 %X, i32 %Y, i32 %M) { 2068 %1 = xor i32 %M, -1 2069 %LHS = and i32 %1, %X 2070 %RHS = and i32 %Y, %M 2071 %Ret = add i32 %LHS, %RHS 2072 ret i32 %Ret 2073 })"); 2074 2075 auto *F = M->getFunction("test"); 2076 auto *LHS = findInstructionByNameOrNull(F, "LHS"); 2077 auto *RHS = findInstructionByNameOrNull(F, "RHS"); 2078 2079 const DataLayout &DL = M->getDataLayout(); 2080 EXPECT_TRUE(haveNoCommonBitsSet(LHS, RHS, DL)); 2081 EXPECT_TRUE(haveNoCommonBitsSet(RHS, LHS, DL)); 2082 } 2083 { 2084 // Check for (A & B) and ~(A | B) 2085 auto M = parseModule(R"( 2086 define void @test(i32 %A, i32 %B) { 2087 %LHS = and i32 %A, %B 2088 %or = or i32 %A, %B 2089 %RHS = xor i32 %or, -1 2090 2091 %LHS2 = and i32 %B, %A 2092 %or2 = or i32 %A, %B 2093 %RHS2 = xor i32 %or2, -1 2094 2095 ret void 2096 })"); 2097 2098 auto *F = M->getFunction("test"); 2099 const DataLayout &DL = M->getDataLayout(); 2100 2101 auto *LHS = findInstructionByNameOrNull(F, "LHS"); 2102 auto *RHS = findInstructionByNameOrNull(F, "RHS"); 2103 EXPECT_TRUE(haveNoCommonBitsSet(LHS, RHS, DL)); 2104 EXPECT_TRUE(haveNoCommonBitsSet(RHS, LHS, DL)); 2105 2106 auto *LHS2 = findInstructionByNameOrNull(F, "LHS2"); 2107 auto *RHS2 = findInstructionByNameOrNull(F, "RHS2"); 2108 EXPECT_TRUE(haveNoCommonBitsSet(LHS2, RHS2, DL)); 2109 EXPECT_TRUE(haveNoCommonBitsSet(RHS2, LHS2, DL)); 2110 } 2111 { 2112 // Check for (A & B) and ~(A | B) in vector version 2113 auto M = parseModule(R"( 2114 define void @test(<2 x i32> %A, <2 x i32> %B) { 2115 %LHS = and <2 x i32> %A, %B 2116 %or = or <2 x i32> %A, %B 2117 %RHS = xor <2 x i32> %or, <i32 -1, i32 -1> 2118 2119 %LHS2 = and <2 x i32> %B, %A 2120 %or2 = or <2 x i32> %A, %B 2121 %RHS2 = xor <2 x i32> %or2, <i32 -1, i32 -1> 2122 2123 ret void 2124 })"); 2125 2126 auto *F = M->getFunction("test"); 2127 const DataLayout &DL = M->getDataLayout(); 2128 2129 auto *LHS = findInstructionByNameOrNull(F, "LHS"); 2130 auto *RHS = findInstructionByNameOrNull(F, "RHS"); 2131 EXPECT_TRUE(haveNoCommonBitsSet(LHS, RHS, DL)); 2132 EXPECT_TRUE(haveNoCommonBitsSet(RHS, LHS, DL)); 2133 2134 auto *LHS2 = findInstructionByNameOrNull(F, "LHS2"); 2135 auto *RHS2 = findInstructionByNameOrNull(F, "RHS2"); 2136 EXPECT_TRUE(haveNoCommonBitsSet(LHS2, RHS2, DL)); 2137 EXPECT_TRUE(haveNoCommonBitsSet(RHS2, LHS2, DL)); 2138 } 2139 } 2140 2141 class IsBytewiseValueTest : public ValueTrackingTest, 2142 public ::testing::WithParamInterface< 2143 std::pair<const char *, const char *>> { 2144 protected: 2145 }; 2146 2147 const std::pair<const char *, const char *> IsBytewiseValueTests[] = { 2148 { 2149 "i8 0", 2150 "i48* null", 2151 }, 2152 { 2153 "i8 undef", 2154 "i48* undef", 2155 }, 2156 { 2157 "i8 0", 2158 "i8 zeroinitializer", 2159 }, 2160 { 2161 "i8 0", 2162 "i8 0", 2163 }, 2164 { 2165 "i8 -86", 2166 "i8 -86", 2167 }, 2168 { 2169 "i8 -1", 2170 "i8 -1", 2171 }, 2172 { 2173 "i8 undef", 2174 "i16 undef", 2175 }, 2176 { 2177 "i8 0", 2178 "i16 0", 2179 }, 2180 { 2181 "", 2182 "i16 7", 2183 }, 2184 { 2185 "i8 -86", 2186 "i16 -21846", 2187 }, 2188 { 2189 "i8 -1", 2190 "i16 -1", 2191 }, 2192 { 2193 "i8 0", 2194 "i48 0", 2195 }, 2196 { 2197 "i8 -1", 2198 "i48 -1", 2199 }, 2200 { 2201 "i8 0", 2202 "i49 0", 2203 }, 2204 { 2205 "", 2206 "i49 -1", 2207 }, 2208 { 2209 "i8 0", 2210 "half 0xH0000", 2211 }, 2212 { 2213 "i8 -85", 2214 "half 0xHABAB", 2215 }, 2216 { 2217 "i8 0", 2218 "float 0.0", 2219 }, 2220 { 2221 "i8 -1", 2222 "float 0xFFFFFFFFE0000000", 2223 }, 2224 { 2225 "i8 0", 2226 "double 0.0", 2227 }, 2228 { 2229 "i8 -15", 2230 "double 0xF1F1F1F1F1F1F1F1", 2231 }, 2232 { 2233 "i8 undef", 2234 "i16* undef", 2235 }, 2236 { 2237 "i8 0", 2238 "i16* inttoptr (i64 0 to i16*)", 2239 }, 2240 { 2241 "i8 -1", 2242 "i16* inttoptr (i64 -1 to i16*)", 2243 }, 2244 { 2245 "i8 -86", 2246 "i16* inttoptr (i64 -6148914691236517206 to i16*)", 2247 }, 2248 { 2249 "", 2250 "i16* inttoptr (i48 -1 to i16*)", 2251 }, 2252 { 2253 "i8 -1", 2254 "i16* inttoptr (i96 -1 to i16*)", 2255 }, 2256 { 2257 "i8 undef", 2258 "[0 x i8] zeroinitializer", 2259 }, 2260 { 2261 "i8 undef", 2262 "[0 x i8] undef", 2263 }, 2264 { 2265 "i8 undef", 2266 "[5 x [0 x i8]] zeroinitializer", 2267 }, 2268 { 2269 "i8 undef", 2270 "[5 x [0 x i8]] undef", 2271 }, 2272 { 2273 "i8 0", 2274 "[6 x i8] zeroinitializer", 2275 }, 2276 { 2277 "i8 undef", 2278 "[6 x i8] undef", 2279 }, 2280 { 2281 "i8 1", 2282 "[5 x i8] [i8 1, i8 1, i8 1, i8 1, i8 1]", 2283 }, 2284 { 2285 "", 2286 "[5 x i64] [i64 1, i64 1, i64 1, i64 1, i64 1]", 2287 }, 2288 { 2289 "i8 -1", 2290 "[5 x i64] [i64 -1, i64 -1, i64 -1, i64 -1, i64 -1]", 2291 }, 2292 { 2293 "", 2294 "[4 x i8] [i8 1, i8 2, i8 1, i8 1]", 2295 }, 2296 { 2297 "i8 1", 2298 "[4 x i8] [i8 1, i8 undef, i8 1, i8 1]", 2299 }, 2300 { 2301 "i8 0", 2302 "<6 x i8> zeroinitializer", 2303 }, 2304 { 2305 "i8 undef", 2306 "<6 x i8> undef", 2307 }, 2308 { 2309 "i8 1", 2310 "<5 x i8> <i8 1, i8 1, i8 1, i8 1, i8 1>", 2311 }, 2312 { 2313 "", 2314 "<5 x i64> <i64 1, i64 1, i64 1, i64 1, i64 1>", 2315 }, 2316 { 2317 "i8 -1", 2318 "<5 x i64> <i64 -1, i64 -1, i64 -1, i64 -1, i64 -1>", 2319 }, 2320 { 2321 "", 2322 "<4 x i8> <i8 1, i8 1, i8 2, i8 1>", 2323 }, 2324 { 2325 "i8 5", 2326 "<2 x i8> < i8 5, i8 undef >", 2327 }, 2328 { 2329 "i8 0", 2330 "[2 x [2 x i16]] zeroinitializer", 2331 }, 2332 { 2333 "i8 undef", 2334 "[2 x [2 x i16]] undef", 2335 }, 2336 { 2337 "i8 -86", 2338 "[2 x [2 x i16]] [[2 x i16] [i16 -21846, i16 -21846], " 2339 "[2 x i16] [i16 -21846, i16 -21846]]", 2340 }, 2341 { 2342 "", 2343 "[2 x [2 x i16]] [[2 x i16] [i16 -21846, i16 -21846], " 2344 "[2 x i16] [i16 -21836, i16 -21846]]", 2345 }, 2346 { 2347 "i8 undef", 2348 "{ } zeroinitializer", 2349 }, 2350 { 2351 "i8 undef", 2352 "{ } undef", 2353 }, 2354 { 2355 "i8 undef", 2356 "{ {}, {} } zeroinitializer", 2357 }, 2358 { 2359 "i8 undef", 2360 "{ {}, {} } undef", 2361 }, 2362 { 2363 "i8 0", 2364 "{i8, i64, i16*} zeroinitializer", 2365 }, 2366 { 2367 "i8 undef", 2368 "{i8, i64, i16*} undef", 2369 }, 2370 { 2371 "i8 -86", 2372 "{i8, i64, i16*} {i8 -86, i64 -6148914691236517206, i16* undef}", 2373 }, 2374 { 2375 "", 2376 "{i8, i64, i16*} {i8 86, i64 -6148914691236517206, i16* undef}", 2377 }, 2378 }; 2379 2380 INSTANTIATE_TEST_SUITE_P(IsBytewiseValueParamTests, IsBytewiseValueTest, 2381 ::testing::ValuesIn(IsBytewiseValueTests)); 2382 2383 TEST_P(IsBytewiseValueTest, IsBytewiseValue) { 2384 auto M = parseModule(std::string("@test = global ") + GetParam().second); 2385 GlobalVariable *GV = dyn_cast<GlobalVariable>(M->getNamedValue("test")); 2386 Value *Actual = isBytewiseValue(GV->getInitializer(), M->getDataLayout()); 2387 std::string Buff; 2388 raw_string_ostream S(Buff); 2389 if (Actual) 2390 S << *Actual; 2391 EXPECT_EQ(GetParam().first, S.str()); 2392 } 2393 2394 TEST_F(ValueTrackingTest, ComputeConstantRange) { 2395 { 2396 // Assumptions: 2397 // * stride >= 5 2398 // * stride < 10 2399 // 2400 // stride = [5, 10) 2401 auto M = parseModule(R"( 2402 declare void @llvm.assume(i1) 2403 2404 define i32 @test(i32 %stride) { 2405 %gt = icmp uge i32 %stride, 5 2406 call void @llvm.assume(i1 %gt) 2407 %lt = icmp ult i32 %stride, 10 2408 call void @llvm.assume(i1 %lt) 2409 %stride.plus.one = add nsw nuw i32 %stride, 1 2410 ret i32 %stride.plus.one 2411 })"); 2412 Function *F = M->getFunction("test"); 2413 2414 AssumptionCache AC(*F); 2415 Value *Stride = &*F->arg_begin(); 2416 ConstantRange CR1 = computeConstantRange(Stride, false, true, &AC, nullptr); 2417 EXPECT_TRUE(CR1.isFullSet()); 2418 2419 Instruction *I = &findInstructionByName(F, "stride.plus.one"); 2420 ConstantRange CR2 = computeConstantRange(Stride, false, true, &AC, I); 2421 EXPECT_EQ(5, CR2.getLower()); 2422 EXPECT_EQ(10, CR2.getUpper()); 2423 } 2424 2425 { 2426 // Assumptions: 2427 // * stride >= 5 2428 // * stride < 200 2429 // * stride == 99 2430 // 2431 // stride = [99, 100) 2432 auto M = parseModule(R"( 2433 declare void @llvm.assume(i1) 2434 2435 define i32 @test(i32 %stride) { 2436 %gt = icmp uge i32 %stride, 5 2437 call void @llvm.assume(i1 %gt) 2438 %lt = icmp ult i32 %stride, 200 2439 call void @llvm.assume(i1 %lt) 2440 %eq = icmp eq i32 %stride, 99 2441 call void @llvm.assume(i1 %eq) 2442 %stride.plus.one = add nsw nuw i32 %stride, 1 2443 ret i32 %stride.plus.one 2444 })"); 2445 Function *F = M->getFunction("test"); 2446 2447 AssumptionCache AC(*F); 2448 Value *Stride = &*F->arg_begin(); 2449 Instruction *I = &findInstructionByName(F, "stride.plus.one"); 2450 ConstantRange CR = computeConstantRange(Stride, false, true, &AC, I); 2451 EXPECT_EQ(99, *CR.getSingleElement()); 2452 } 2453 2454 { 2455 // Assumptions: 2456 // * stride >= 5 2457 // * stride >= 50 2458 // * stride < 100 2459 // * stride < 200 2460 // 2461 // stride = [50, 100) 2462 auto M = parseModule(R"( 2463 declare void @llvm.assume(i1) 2464 2465 define i32 @test(i32 %stride, i1 %cond) { 2466 %gt = icmp uge i32 %stride, 5 2467 call void @llvm.assume(i1 %gt) 2468 %gt.2 = icmp uge i32 %stride, 50 2469 call void @llvm.assume(i1 %gt.2) 2470 br i1 %cond, label %bb1, label %bb2 2471 2472 bb1: 2473 %lt = icmp ult i32 %stride, 200 2474 call void @llvm.assume(i1 %lt) 2475 %lt.2 = icmp ult i32 %stride, 100 2476 call void @llvm.assume(i1 %lt.2) 2477 %stride.plus.one = add nsw nuw i32 %stride, 1 2478 ret i32 %stride.plus.one 2479 2480 bb2: 2481 ret i32 0 2482 })"); 2483 Function *F = M->getFunction("test"); 2484 2485 AssumptionCache AC(*F); 2486 Value *Stride = &*F->arg_begin(); 2487 Instruction *GT2 = &findInstructionByName(F, "gt.2"); 2488 ConstantRange CR = computeConstantRange(Stride, false, true, &AC, GT2); 2489 EXPECT_EQ(5, CR.getLower()); 2490 EXPECT_EQ(0, CR.getUpper()); 2491 2492 Instruction *I = &findInstructionByName(F, "stride.plus.one"); 2493 ConstantRange CR2 = computeConstantRange(Stride, false, true, &AC, I); 2494 EXPECT_EQ(50, CR2.getLower()); 2495 EXPECT_EQ(100, CR2.getUpper()); 2496 } 2497 2498 { 2499 // Assumptions: 2500 // * stride > 5 2501 // * stride < 5 2502 // 2503 // stride = empty range, as the assumptions contradict each other. 2504 auto M = parseModule(R"( 2505 declare void @llvm.assume(i1) 2506 2507 define i32 @test(i32 %stride, i1 %cond) { 2508 %gt = icmp ugt i32 %stride, 5 2509 call void @llvm.assume(i1 %gt) 2510 %lt = icmp ult i32 %stride, 5 2511 call void @llvm.assume(i1 %lt) 2512 %stride.plus.one = add nsw nuw i32 %stride, 1 2513 ret i32 %stride.plus.one 2514 })"); 2515 Function *F = M->getFunction("test"); 2516 2517 AssumptionCache AC(*F); 2518 Value *Stride = &*F->arg_begin(); 2519 2520 Instruction *I = &findInstructionByName(F, "stride.plus.one"); 2521 ConstantRange CR = computeConstantRange(Stride, false, true, &AC, I); 2522 EXPECT_TRUE(CR.isEmptySet()); 2523 } 2524 2525 { 2526 // Assumptions: 2527 // * x.1 >= 5 2528 // * x.2 < x.1 2529 // 2530 // stride = [0, -1) 2531 auto M = parseModule(R"( 2532 declare void @llvm.assume(i1) 2533 2534 define i32 @test(i32 %x.1, i32 %x.2) { 2535 %gt = icmp uge i32 %x.1, 5 2536 call void @llvm.assume(i1 %gt) 2537 %lt = icmp ult i32 %x.2, %x.1 2538 call void @llvm.assume(i1 %lt) 2539 %stride.plus.one = add nsw nuw i32 %x.1, 1 2540 ret i32 %stride.plus.one 2541 })"); 2542 Function *F = M->getFunction("test"); 2543 2544 AssumptionCache AC(*F); 2545 Value *X1 = &*(F->arg_begin()); 2546 Value *X2 = &*std::next(F->arg_begin()); 2547 2548 Instruction *I = &findInstructionByName(F, "stride.plus.one"); 2549 ConstantRange CR1 = computeConstantRange(X1, false, true, &AC, I); 2550 ConstantRange CR2 = computeConstantRange(X2, false, true, &AC, I); 2551 2552 EXPECT_EQ(5, CR1.getLower()); 2553 EXPECT_EQ(0, CR1.getUpper()); 2554 2555 EXPECT_EQ(0, CR2.getLower()); 2556 EXPECT_EQ(0xffffffff, CR2.getUpper()); 2557 2558 // Check the depth cutoff results in a conservative result (full set) by 2559 // passing Depth == MaxDepth == 6. 2560 ConstantRange CR3 = computeConstantRange(X2, false, true, &AC, I, nullptr, 6); 2561 EXPECT_TRUE(CR3.isFullSet()); 2562 } 2563 { 2564 // Assumptions: 2565 // * x.2 <= x.1 2566 auto M = parseModule(R"( 2567 declare void @llvm.assume(i1) 2568 2569 define i32 @test(i32 %x.1, i32 %x.2) { 2570 %lt = icmp ule i32 %x.2, %x.1 2571 call void @llvm.assume(i1 %lt) 2572 %stride.plus.one = add nsw nuw i32 %x.1, 1 2573 ret i32 %stride.plus.one 2574 })"); 2575 Function *F = M->getFunction("test"); 2576 2577 AssumptionCache AC(*F); 2578 Value *X2 = &*std::next(F->arg_begin()); 2579 2580 Instruction *I = &findInstructionByName(F, "stride.plus.one"); 2581 ConstantRange CR1 = computeConstantRange(X2, false, true, &AC, I); 2582 // If we don't know the value of x.2, we don't know the value of x.1. 2583 EXPECT_TRUE(CR1.isFullSet()); 2584 } 2585 } 2586 2587 struct FindAllocaForValueTestParams { 2588 const char *IR; 2589 bool AnyOffsetResult; 2590 bool ZeroOffsetResult; 2591 }; 2592 2593 class FindAllocaForValueTest 2594 : public ValueTrackingTest, 2595 public ::testing::WithParamInterface<FindAllocaForValueTestParams> { 2596 protected: 2597 }; 2598 2599 const FindAllocaForValueTestParams FindAllocaForValueTests[] = { 2600 {R"( 2601 define void @test() { 2602 %a = alloca i64 2603 %r = bitcast ptr %a to ptr 2604 ret void 2605 })", 2606 true, true}, 2607 2608 {R"( 2609 define void @test() { 2610 %a = alloca i32 2611 %r = getelementptr i32, ptr %a, i32 1 2612 ret void 2613 })", 2614 true, false}, 2615 2616 {R"( 2617 define void @test() { 2618 %a = alloca i32 2619 %r = getelementptr i32, ptr %a, i32 0 2620 ret void 2621 })", 2622 true, true}, 2623 2624 {R"( 2625 define void @test(i1 %cond) { 2626 entry: 2627 %a = alloca i32 2628 br label %bb1 2629 2630 bb1: 2631 %r = phi ptr [ %a, %entry ], [ %r, %bb1 ] 2632 br i1 %cond, label %bb1, label %exit 2633 2634 exit: 2635 ret void 2636 })", 2637 true, true}, 2638 2639 {R"( 2640 define void @test(i1 %cond) { 2641 %a = alloca i32 2642 %r = select i1 %cond, ptr %a, ptr %a 2643 ret void 2644 })", 2645 true, true}, 2646 2647 {R"( 2648 define void @test(i1 %cond) { 2649 %a = alloca i32 2650 %b = alloca i32 2651 %r = select i1 %cond, ptr %a, ptr %b 2652 ret void 2653 })", 2654 false, false}, 2655 2656 {R"( 2657 define void @test(i1 %cond) { 2658 entry: 2659 %a = alloca i64 2660 %a32 = bitcast ptr %a to ptr 2661 br label %bb1 2662 2663 bb1: 2664 %x = phi ptr [ %a32, %entry ], [ %x, %bb1 ] 2665 %r = getelementptr i32, ptr %x, i32 1 2666 br i1 %cond, label %bb1, label %exit 2667 2668 exit: 2669 ret void 2670 })", 2671 true, false}, 2672 2673 {R"( 2674 define void @test(i1 %cond) { 2675 entry: 2676 %a = alloca i64 2677 %a32 = bitcast ptr %a to ptr 2678 br label %bb1 2679 2680 bb1: 2681 %x = phi ptr [ %a32, %entry ], [ %r, %bb1 ] 2682 %r = getelementptr i32, ptr %x, i32 1 2683 br i1 %cond, label %bb1, label %exit 2684 2685 exit: 2686 ret void 2687 })", 2688 true, false}, 2689 2690 {R"( 2691 define void @test(i1 %cond, ptr %a) { 2692 entry: 2693 %r = bitcast ptr %a to ptr 2694 ret void 2695 })", 2696 false, false}, 2697 2698 {R"( 2699 define void @test(i1 %cond) { 2700 entry: 2701 %a = alloca i32 2702 %b = alloca i32 2703 br label %bb1 2704 2705 bb1: 2706 %r = phi ptr [ %a, %entry ], [ %b, %bb1 ] 2707 br i1 %cond, label %bb1, label %exit 2708 2709 exit: 2710 ret void 2711 })", 2712 false, false}, 2713 {R"( 2714 declare ptr @retptr(ptr returned) 2715 define void @test(i1 %cond) { 2716 %a = alloca i32 2717 %r = call ptr @retptr(ptr %a) 2718 ret void 2719 })", 2720 true, true}, 2721 {R"( 2722 declare ptr @fun(ptr) 2723 define void @test(i1 %cond) { 2724 %a = alloca i32 2725 %r = call ptr @fun(ptr %a) 2726 ret void 2727 })", 2728 false, false}, 2729 }; 2730 2731 TEST_P(FindAllocaForValueTest, findAllocaForValue) { 2732 auto M = parseModule(GetParam().IR); 2733 Function *F = M->getFunction("test"); 2734 Instruction *I = &findInstructionByName(F, "r"); 2735 const AllocaInst *AI = findAllocaForValue(I); 2736 EXPECT_EQ(!!AI, GetParam().AnyOffsetResult); 2737 } 2738 2739 TEST_P(FindAllocaForValueTest, findAllocaForValueZeroOffset) { 2740 auto M = parseModule(GetParam().IR); 2741 Function *F = M->getFunction("test"); 2742 Instruction *I = &findInstructionByName(F, "r"); 2743 const AllocaInst *AI = findAllocaForValue(I, true); 2744 EXPECT_EQ(!!AI, GetParam().ZeroOffsetResult); 2745 } 2746 2747 INSTANTIATE_TEST_SUITE_P(FindAllocaForValueTest, FindAllocaForValueTest, 2748 ::testing::ValuesIn(FindAllocaForValueTests)); 2749