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