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/InstIterator.h" 16 #include "llvm/IR/Instructions.h" 17 #include "llvm/IR/LLVMContext.h" 18 #include "llvm/IR/Module.h" 19 #include "llvm/Support/ErrorHandling.h" 20 #include "llvm/Support/KnownBits.h" 21 #include "llvm/Support/SourceMgr.h" 22 #include "gtest/gtest.h" 23 24 using namespace llvm; 25 26 namespace { 27 28 static Instruction *findInstructionByNameOrNull(Function *F, StringRef Name) { 29 for (Instruction &I : instructions(F)) 30 if (I.getName() == Name) 31 return &I; 32 33 return nullptr; 34 } 35 36 static Instruction &findInstructionByName(Function *F, StringRef Name) { 37 auto *I = findInstructionByNameOrNull(F, Name); 38 if (I) 39 return *I; 40 41 llvm_unreachable("Expected value not found"); 42 } 43 44 class ValueTrackingTest : public testing::Test { 45 protected: 46 std::unique_ptr<Module> parseModule(StringRef Assembly) { 47 SMDiagnostic Error; 48 std::unique_ptr<Module> M = parseAssemblyString(Assembly, Error, Context); 49 50 std::string errMsg; 51 raw_string_ostream os(errMsg); 52 Error.print("", os); 53 EXPECT_TRUE(M) << os.str(); 54 55 return M; 56 } 57 58 void parseAssembly(StringRef Assembly) { 59 M = parseModule(Assembly); 60 ASSERT_TRUE(M); 61 62 F = M->getFunction("test"); 63 ASSERT_TRUE(F) << "Test must have a function @test"; 64 if (!F) 65 return; 66 67 A = findInstructionByNameOrNull(F, "A"); 68 ASSERT_TRUE(A) << "@test must have an instruction %A"; 69 70 CxtI = findInstructionByNameOrNull(F, "CxtI"); 71 CxtI2 = findInstructionByNameOrNull(F, "CxtI2"); 72 CxtI3 = findInstructionByNameOrNull(F, "CxtI3"); 73 } 74 75 LLVMContext Context; 76 std::unique_ptr<Module> M; 77 Function *F = nullptr; 78 Instruction *A = nullptr; 79 80 // Context instructions (optional) 81 Instruction *CxtI = nullptr, *CxtI2 = nullptr, *CxtI3 = nullptr; 82 }; 83 84 class MatchSelectPatternTest : public ValueTrackingTest { 85 protected: 86 void expectPattern(const SelectPatternResult &P) { 87 Value *LHS, *RHS; 88 Instruction::CastOps CastOp; 89 SelectPatternResult R = matchSelectPattern(A, LHS, RHS, &CastOp); 90 EXPECT_EQ(P.Flavor, R.Flavor); 91 EXPECT_EQ(P.NaNBehavior, R.NaNBehavior); 92 EXPECT_EQ(P.Ordered, R.Ordered); 93 } 94 }; 95 96 class ComputeKnownBitsTest : public ValueTrackingTest { 97 protected: 98 void expectKnownBits(uint64_t Zero, uint64_t One) { 99 auto Known = computeKnownBits(A, M->getDataLayout()); 100 ASSERT_FALSE(Known.hasConflict()); 101 EXPECT_EQ(Known.One.getZExtValue(), One); 102 EXPECT_EQ(Known.Zero.getZExtValue(), Zero); 103 } 104 }; 105 106 } 107 108 TEST_F(MatchSelectPatternTest, SimpleFMin) { 109 parseAssembly( 110 "define float @test(float %a) {\n" 111 " %1 = fcmp ult float %a, 5.0\n" 112 " %A = select i1 %1, float %a, float 5.0\n" 113 " ret float %A\n" 114 "}\n"); 115 expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, false}); 116 } 117 118 TEST_F(MatchSelectPatternTest, SimpleFMax) { 119 parseAssembly( 120 "define float @test(float %a) {\n" 121 " %1 = fcmp ogt float %a, 5.0\n" 122 " %A = select i1 %1, float %a, float 5.0\n" 123 " ret float %A\n" 124 "}\n"); 125 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, true}); 126 } 127 128 TEST_F(MatchSelectPatternTest, SwappedFMax) { 129 parseAssembly( 130 "define float @test(float %a) {\n" 131 " %1 = fcmp olt float 5.0, %a\n" 132 " %A = select i1 %1, float %a, float 5.0\n" 133 " ret float %A\n" 134 "}\n"); 135 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, false}); 136 } 137 138 TEST_F(MatchSelectPatternTest, SwappedFMax2) { 139 parseAssembly( 140 "define float @test(float %a) {\n" 141 " %1 = fcmp olt float %a, 5.0\n" 142 " %A = select i1 %1, float 5.0, float %a\n" 143 " ret float %A\n" 144 "}\n"); 145 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_NAN, false}); 146 } 147 148 TEST_F(MatchSelectPatternTest, SwappedFMax3) { 149 parseAssembly( 150 "define float @test(float %a) {\n" 151 " %1 = fcmp ult float %a, 5.0\n" 152 " %A = select i1 %1, float 5.0, float %a\n" 153 " ret float %A\n" 154 "}\n"); 155 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, true}); 156 } 157 158 TEST_F(MatchSelectPatternTest, FastFMin) { 159 parseAssembly( 160 "define float @test(float %a) {\n" 161 " %1 = fcmp nnan olt float %a, 5.0\n" 162 " %A = select i1 %1, float %a, float 5.0\n" 163 " ret float %A\n" 164 "}\n"); 165 expectPattern({SPF_FMINNUM, SPNB_RETURNS_ANY, false}); 166 } 167 168 TEST_F(MatchSelectPatternTest, FMinConstantZero) { 169 parseAssembly( 170 "define float @test(float %a) {\n" 171 " %1 = fcmp ole float %a, 0.0\n" 172 " %A = select i1 %1, float %a, float 0.0\n" 173 " ret float %A\n" 174 "}\n"); 175 // This shouldn't be matched, as %a could be -0.0. 176 expectPattern({SPF_UNKNOWN, SPNB_NA, false}); 177 } 178 179 TEST_F(MatchSelectPatternTest, FMinConstantZeroNsz) { 180 parseAssembly( 181 "define float @test(float %a) {\n" 182 " %1 = fcmp nsz ole float %a, 0.0\n" 183 " %A = select i1 %1, float %a, float 0.0\n" 184 " ret float %A\n" 185 "}\n"); 186 // But this should be, because we've ignored signed zeroes. 187 expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, true}); 188 } 189 190 TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero1) { 191 parseAssembly( 192 "define float @test(float %a) {\n" 193 " %1 = fcmp olt float -0.0, %a\n" 194 " %A = select i1 %1, float 0.0, float %a\n" 195 " ret float %A\n" 196 "}\n"); 197 // The sign of zero doesn't matter in fcmp. 198 expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, true}); 199 } 200 201 TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero2) { 202 parseAssembly( 203 "define float @test(float %a) {\n" 204 " %1 = fcmp ogt float %a, -0.0\n" 205 " %A = select i1 %1, float 0.0, float %a\n" 206 " ret float %A\n" 207 "}\n"); 208 // The sign of zero doesn't matter in fcmp. 209 expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, false}); 210 } 211 212 TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero3) { 213 parseAssembly( 214 "define float @test(float %a) {\n" 215 " %1 = fcmp olt float 0.0, %a\n" 216 " %A = select i1 %1, float -0.0, float %a\n" 217 " ret float %A\n" 218 "}\n"); 219 // The sign of zero doesn't matter in fcmp. 220 expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, true}); 221 } 222 223 TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero4) { 224 parseAssembly( 225 "define float @test(float %a) {\n" 226 " %1 = fcmp ogt float %a, 0.0\n" 227 " %A = select i1 %1, float -0.0, float %a\n" 228 " ret float %A\n" 229 "}\n"); 230 // The sign of zero doesn't matter in fcmp. 231 expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, false}); 232 } 233 234 TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero5) { 235 parseAssembly( 236 "define float @test(float %a) {\n" 237 " %1 = fcmp ogt float -0.0, %a\n" 238 " %A = select i1 %1, float %a, float 0.0\n" 239 " ret float %A\n" 240 "}\n"); 241 // The sign of zero doesn't matter in fcmp. 242 expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, false}); 243 } 244 245 TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero6) { 246 parseAssembly( 247 "define float @test(float %a) {\n" 248 " %1 = fcmp olt float %a, -0.0\n" 249 " %A = select i1 %1, float %a, float 0.0\n" 250 " ret float %A\n" 251 "}\n"); 252 // The sign of zero doesn't matter in fcmp. 253 expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, true}); 254 } 255 256 TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero7) { 257 parseAssembly( 258 "define float @test(float %a) {\n" 259 " %1 = fcmp ogt float 0.0, %a\n" 260 " %A = select i1 %1, float %a, float -0.0\n" 261 " ret float %A\n" 262 "}\n"); 263 // The sign of zero doesn't matter in fcmp. 264 expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, false}); 265 } 266 267 TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero8) { 268 parseAssembly( 269 "define float @test(float %a) {\n" 270 " %1 = fcmp olt float %a, 0.0\n" 271 " %A = select i1 %1, float %a, float -0.0\n" 272 " ret float %A\n" 273 "}\n"); 274 // The sign of zero doesn't matter in fcmp. 275 expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, true}); 276 } 277 278 TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero1) { 279 parseAssembly( 280 "define float @test(float %a) {\n" 281 " %1 = fcmp ogt float -0.0, %a\n" 282 " %A = select i1 %1, float 0.0, float %a\n" 283 " ret float %A\n" 284 "}\n"); 285 // The sign of zero doesn't matter in fcmp. 286 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_NAN, true}); 287 } 288 289 TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero2) { 290 parseAssembly( 291 "define float @test(float %a) {\n" 292 " %1 = fcmp olt float %a, -0.0\n" 293 " %A = select i1 %1, float 0.0, float %a\n" 294 " ret float %A\n" 295 "}\n"); 296 // The sign of zero doesn't matter in fcmp. 297 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_NAN, false}); 298 } 299 300 TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero3) { 301 parseAssembly( 302 "define float @test(float %a) {\n" 303 " %1 = fcmp ogt float 0.0, %a\n" 304 " %A = select i1 %1, float -0.0, float %a\n" 305 " ret float %A\n" 306 "}\n"); 307 // The sign of zero doesn't matter in fcmp. 308 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_NAN, true}); 309 } 310 311 TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero4) { 312 parseAssembly( 313 "define float @test(float %a) {\n" 314 " %1 = fcmp olt float %a, 0.0\n" 315 " %A = select i1 %1, float -0.0, float %a\n" 316 " ret float %A\n" 317 "}\n"); 318 // The sign of zero doesn't matter in fcmp. 319 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_NAN, false}); 320 } 321 322 TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero5) { 323 parseAssembly( 324 "define float @test(float %a) {\n" 325 " %1 = fcmp olt float -0.0, %a\n" 326 " %A = select i1 %1, float %a, float 0.0\n" 327 " ret float %A\n" 328 "}\n"); 329 // The sign of zero doesn't matter in fcmp. 330 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, false}); 331 } 332 333 TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero6) { 334 parseAssembly( 335 "define float @test(float %a) {\n" 336 " %1 = fcmp ogt float %a, -0.0\n" 337 " %A = select i1 %1, float %a, float 0.0\n" 338 " ret float %A\n" 339 "}\n"); 340 // The sign of zero doesn't matter in fcmp. 341 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, true}); 342 } 343 344 TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero7) { 345 parseAssembly( 346 "define float @test(float %a) {\n" 347 " %1 = fcmp olt float 0.0, %a\n" 348 " %A = select i1 %1, float %a, float -0.0\n" 349 " ret float %A\n" 350 "}\n"); 351 // The sign of zero doesn't matter in fcmp. 352 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, false}); 353 } 354 355 TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero8) { 356 parseAssembly( 357 "define float @test(float %a) {\n" 358 " %1 = fcmp ogt float %a, 0.0\n" 359 " %A = select i1 %1, float %a, float -0.0\n" 360 " ret float %A\n" 361 "}\n"); 362 // The sign of zero doesn't matter in fcmp. 363 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, true}); 364 } 365 366 TEST_F(MatchSelectPatternTest, FMinMismatchConstantZeroVecUndef) { 367 parseAssembly( 368 "define <2 x float> @test(<2 x float> %a) {\n" 369 " %1 = fcmp ogt <2 x float> %a, <float -0.0, float -0.0>\n" 370 " %A = select <2 x i1> %1, <2 x float> <float undef, float 0.0>, <2 x float> %a\n" 371 " ret <2 x float> %A\n" 372 "}\n"); 373 // An undef in a vector constant can not be back-propagated for this analysis. 374 expectPattern({SPF_UNKNOWN, SPNB_NA, false}); 375 } 376 377 TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZeroVecUndef) { 378 parseAssembly( 379 "define <2 x float> @test(<2 x float> %a) {\n" 380 " %1 = fcmp ogt <2 x float> %a, zeroinitializer\n" 381 " %A = select <2 x i1> %1, <2 x float> %a, <2 x float> <float -0.0, float undef>\n" 382 " ret <2 x float> %A\n" 383 "}\n"); 384 // An undef in a vector constant can not be back-propagated for this analysis. 385 expectPattern({SPF_UNKNOWN, SPNB_NA, false}); 386 } 387 388 TEST_F(MatchSelectPatternTest, VectorFMinimum) { 389 parseAssembly( 390 "define <4 x float> @test(<4 x float> %a) {\n" 391 " %1 = fcmp ule <4 x float> %a, \n" 392 " <float 5.0, float 5.0, float 5.0, float 5.0>\n" 393 " %A = select <4 x i1> %1, <4 x float> %a,\n" 394 " <4 x float> <float 5.0, float 5.0, float 5.0, float 5.0>\n" 395 " ret <4 x float> %A\n" 396 "}\n"); 397 // Check that pattern matching works on vectors where each lane has the same 398 // unordered pattern. 399 expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, false}); 400 } 401 402 TEST_F(MatchSelectPatternTest, VectorFMinOtherOrdered) { 403 parseAssembly( 404 "define <4 x float> @test(<4 x float> %a) {\n" 405 " %1 = fcmp ole <4 x float> %a, \n" 406 " <float 5.0, float 5.0, float 5.0, float 5.0>\n" 407 " %A = select <4 x i1> %1, <4 x float> %a,\n" 408 " <4 x float> <float 5.0, float 5.0, float 5.0, float 5.0>\n" 409 " ret <4 x float> %A\n" 410 "}\n"); 411 // Check that pattern matching works on vectors where each lane has the same 412 // ordered pattern. 413 expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, true}); 414 } 415 416 TEST_F(MatchSelectPatternTest, VectorNotFMinimum) { 417 parseAssembly( 418 "define <4 x float> @test(<4 x float> %a) {\n" 419 " %1 = fcmp ule <4 x float> %a, \n" 420 " <float 5.0, float 0x7ff8000000000000, float 5.0, float 5.0>\n" 421 " %A = select <4 x i1> %1, <4 x float> %a,\n" 422 " <4 x float> <float 5.0, float 0x7ff8000000000000, float 5.0, float " 423 "5.0>\n" 424 " ret <4 x float> %A\n" 425 "}\n"); 426 // The lane that contains a NaN (0x7ff80...) behaves like a 427 // non-NaN-propagating min and the other lines behave like a NaN-propagating 428 // min, so check that neither is returned. 429 expectPattern({SPF_UNKNOWN, SPNB_NA, false}); 430 } 431 432 TEST_F(MatchSelectPatternTest, VectorNotFMinZero) { 433 parseAssembly( 434 "define <4 x float> @test(<4 x float> %a) {\n" 435 " %1 = fcmp ule <4 x float> %a, \n" 436 " <float 5.0, float -0.0, float 5.0, float 5.0>\n" 437 " %A = select <4 x i1> %1, <4 x float> %a,\n" 438 " <4 x float> <float 5.0, float 0.0, float 5.0, float 5.0>\n" 439 " ret <4 x float> %A\n" 440 "}\n"); 441 // Always selects the second lane of %a if it is positive or negative zero, so 442 // this is stricter than a min. 443 expectPattern({SPF_UNKNOWN, SPNB_NA, false}); 444 } 445 446 TEST_F(MatchSelectPatternTest, DoubleCastU) { 447 parseAssembly( 448 "define i32 @test(i8 %a, i8 %b) {\n" 449 " %1 = icmp ult i8 %a, %b\n" 450 " %2 = zext i8 %a to i32\n" 451 " %3 = zext i8 %b to i32\n" 452 " %A = select i1 %1, i32 %2, i32 %3\n" 453 " ret i32 %A\n" 454 "}\n"); 455 // We should be able to look through the situation where we cast both operands 456 // to the select. 457 expectPattern({SPF_UMIN, SPNB_NA, false}); 458 } 459 460 TEST_F(MatchSelectPatternTest, DoubleCastS) { 461 parseAssembly( 462 "define i32 @test(i8 %a, i8 %b) {\n" 463 " %1 = icmp slt i8 %a, %b\n" 464 " %2 = sext i8 %a to i32\n" 465 " %3 = sext i8 %b to i32\n" 466 " %A = select i1 %1, i32 %2, i32 %3\n" 467 " ret i32 %A\n" 468 "}\n"); 469 // We should be able to look through the situation where we cast both operands 470 // to the select. 471 expectPattern({SPF_SMIN, SPNB_NA, false}); 472 } 473 474 TEST_F(MatchSelectPatternTest, DoubleCastBad) { 475 parseAssembly( 476 "define i32 @test(i8 %a, i8 %b) {\n" 477 " %1 = icmp ult i8 %a, %b\n" 478 " %2 = zext i8 %a to i32\n" 479 " %3 = sext i8 %b to i32\n" 480 " %A = select i1 %1, i32 %2, i32 %3\n" 481 " ret i32 %A\n" 482 "}\n"); 483 // The cast types here aren't the same, so we cannot match an UMIN. 484 expectPattern({SPF_UNKNOWN, SPNB_NA, false}); 485 } 486 487 TEST_F(MatchSelectPatternTest, NotNotSMin) { 488 parseAssembly( 489 "define i8 @test(i8 %a, i8 %b) {\n" 490 " %cmp = icmp sgt i8 %a, %b\n" 491 " %an = xor i8 %a, -1\n" 492 " %bn = xor i8 %b, -1\n" 493 " %A = select i1 %cmp, i8 %an, i8 %bn\n" 494 " ret i8 %A\n" 495 "}\n"); 496 expectPattern({SPF_SMIN, SPNB_NA, false}); 497 } 498 499 TEST_F(MatchSelectPatternTest, NotNotSMinSwap) { 500 parseAssembly( 501 "define <2 x i8> @test(<2 x i8> %a, <2 x i8> %b) {\n" 502 " %cmp = icmp slt <2 x i8> %a, %b\n" 503 " %an = xor <2 x i8> %a, <i8 -1, i8-1>\n" 504 " %bn = xor <2 x i8> %b, <i8 -1, i8-1>\n" 505 " %A = select <2 x i1> %cmp, <2 x i8> %bn, <2 x i8> %an\n" 506 " ret <2 x i8> %A\n" 507 "}\n"); 508 expectPattern({SPF_SMIN, SPNB_NA, false}); 509 } 510 511 TEST_F(MatchSelectPatternTest, NotNotSMax) { 512 parseAssembly( 513 "define i8 @test(i8 %a, i8 %b) {\n" 514 " %cmp = icmp slt i8 %a, %b\n" 515 " %an = xor i8 %a, -1\n" 516 " %bn = xor i8 %b, -1\n" 517 " %A = select i1 %cmp, i8 %an, i8 %bn\n" 518 " ret i8 %A\n" 519 "}\n"); 520 expectPattern({SPF_SMAX, SPNB_NA, false}); 521 } 522 523 TEST_F(MatchSelectPatternTest, NotNotSMaxSwap) { 524 parseAssembly( 525 "define <2 x i8> @test(<2 x i8> %a, <2 x i8> %b) {\n" 526 " %cmp = icmp sgt <2 x i8> %a, %b\n" 527 " %an = xor <2 x i8> %a, <i8 -1, i8-1>\n" 528 " %bn = xor <2 x i8> %b, <i8 -1, i8-1>\n" 529 " %A = select <2 x i1> %cmp, <2 x i8> %bn, <2 x i8> %an\n" 530 " ret <2 x i8> %A\n" 531 "}\n"); 532 expectPattern({SPF_SMAX, SPNB_NA, false}); 533 } 534 535 TEST_F(MatchSelectPatternTest, NotNotUMin) { 536 parseAssembly( 537 "define <2 x i8> @test(<2 x i8> %a, <2 x i8> %b) {\n" 538 " %cmp = icmp ugt <2 x i8> %a, %b\n" 539 " %an = xor <2 x i8> %a, <i8 -1, i8-1>\n" 540 " %bn = xor <2 x i8> %b, <i8 -1, i8-1>\n" 541 " %A = select <2 x i1> %cmp, <2 x i8> %an, <2 x i8> %bn\n" 542 " ret <2 x i8> %A\n" 543 "}\n"); 544 expectPattern({SPF_UMIN, SPNB_NA, false}); 545 } 546 547 TEST_F(MatchSelectPatternTest, NotNotUMinSwap) { 548 parseAssembly( 549 "define i8 @test(i8 %a, i8 %b) {\n" 550 " %cmp = icmp ult i8 %a, %b\n" 551 " %an = xor i8 %a, -1\n" 552 " %bn = xor i8 %b, -1\n" 553 " %A = select i1 %cmp, i8 %bn, i8 %an\n" 554 " ret i8 %A\n" 555 "}\n"); 556 expectPattern({SPF_UMIN, SPNB_NA, false}); 557 } 558 559 TEST_F(MatchSelectPatternTest, NotNotUMax) { 560 parseAssembly( 561 "define <2 x i8> @test(<2 x i8> %a, <2 x i8> %b) {\n" 562 " %cmp = icmp ult <2 x i8> %a, %b\n" 563 " %an = xor <2 x i8> %a, <i8 -1, i8-1>\n" 564 " %bn = xor <2 x i8> %b, <i8 -1, i8-1>\n" 565 " %A = select <2 x i1> %cmp, <2 x i8> %an, <2 x i8> %bn\n" 566 " ret <2 x i8> %A\n" 567 "}\n"); 568 expectPattern({SPF_UMAX, SPNB_NA, false}); 569 } 570 571 TEST_F(MatchSelectPatternTest, NotNotUMaxSwap) { 572 parseAssembly( 573 "define i8 @test(i8 %a, i8 %b) {\n" 574 " %cmp = icmp ugt i8 %a, %b\n" 575 " %an = xor i8 %a, -1\n" 576 " %bn = xor i8 %b, -1\n" 577 " %A = select i1 %cmp, i8 %bn, i8 %an\n" 578 " ret i8 %A\n" 579 "}\n"); 580 expectPattern({SPF_UMAX, SPNB_NA, false}); 581 } 582 583 TEST_F(MatchSelectPatternTest, NotNotEq) { 584 parseAssembly( 585 "define i8 @test(i8 %a, i8 %b) {\n" 586 " %cmp = icmp eq i8 %a, %b\n" 587 " %an = xor i8 %a, -1\n" 588 " %bn = xor i8 %b, -1\n" 589 " %A = select i1 %cmp, i8 %bn, i8 %an\n" 590 " ret i8 %A\n" 591 "}\n"); 592 expectPattern({SPF_UNKNOWN, SPNB_NA, false}); 593 } 594 595 TEST_F(MatchSelectPatternTest, NotNotNe) { 596 parseAssembly( 597 "define i8 @test(i8 %a, i8 %b) {\n" 598 " %cmp = icmp ne i8 %a, %b\n" 599 " %an = xor i8 %a, -1\n" 600 " %bn = xor i8 %b, -1\n" 601 " %A = select i1 %cmp, i8 %bn, i8 %an\n" 602 " ret i8 %A\n" 603 "}\n"); 604 expectPattern({SPF_UNKNOWN, SPNB_NA, false}); 605 } 606 607 TEST(ValueTracking, GuaranteedToTransferExecutionToSuccessor) { 608 StringRef Assembly = 609 "declare void @nounwind_readonly(i32*) nounwind readonly " 610 "declare void @nounwind_argmemonly(i32*) nounwind argmemonly " 611 "declare void @throws_but_readonly(i32*) readonly " 612 "declare void @throws_but_argmemonly(i32*) argmemonly " 613 "declare void @nounwind_willreturn(i32*) nounwind willreturn" 614 " " 615 "declare void @unknown(i32*) " 616 " " 617 "define void @f(i32* %p) { " 618 " call void @nounwind_readonly(i32* %p) " 619 " call void @nounwind_argmemonly(i32* %p) " 620 " call void @throws_but_readonly(i32* %p) " 621 " call void @throws_but_argmemonly(i32* %p) " 622 " call void @unknown(i32* %p) nounwind readonly " 623 " call void @unknown(i32* %p) nounwind argmemonly " 624 " call void @unknown(i32* %p) readonly " 625 " call void @unknown(i32* %p) argmemonly " 626 " call void @nounwind_willreturn(i32* %p)" 627 " ret void " 628 "} "; 629 630 LLVMContext Context; 631 SMDiagnostic Error; 632 auto M = parseAssemblyString(Assembly, Error, Context); 633 assert(M && "Bad assembly?"); 634 635 auto *F = M->getFunction("f"); 636 assert(F && "Bad assembly?"); 637 638 auto &BB = F->getEntryBlock(); 639 bool ExpectedAnswers[] = { 640 true, // call void @nounwind_readonly(i32* %p) 641 true, // call void @nounwind_argmemonly(i32* %p) 642 false, // call void @throws_but_readonly(i32* %p) 643 false, // call void @throws_but_argmemonly(i32* %p) 644 true, // call void @unknown(i32* %p) nounwind readonly 645 true, // call void @unknown(i32* %p) nounwind argmemonly 646 false, // call void @unknown(i32* %p) readonly 647 false, // call void @unknown(i32* %p) argmemonly 648 true, // call void @nounwind_willreturn(i32* %p) 649 false, // ret void 650 }; 651 652 int Index = 0; 653 for (auto &I : BB) { 654 EXPECT_EQ(isGuaranteedToTransferExecutionToSuccessor(&I), 655 ExpectedAnswers[Index]) 656 << "Incorrect answer at instruction " << Index << " = " << I; 657 Index++; 658 } 659 } 660 661 TEST_F(ValueTrackingTest, ComputeNumSignBits_PR32045) { 662 parseAssembly( 663 "define i32 @test(i32 %a) {\n" 664 " %A = ashr i32 %a, -1\n" 665 " ret i32 %A\n" 666 "}\n"); 667 EXPECT_EQ(ComputeNumSignBits(A, M->getDataLayout()), 1u); 668 } 669 670 // No guarantees for canonical IR in this analysis, so this just bails out. 671 TEST_F(ValueTrackingTest, ComputeNumSignBits_Shuffle) { 672 parseAssembly( 673 "define <2 x i32> @test() {\n" 674 " %A = shufflevector <2 x i32> undef, <2 x i32> undef, <2 x i32> <i32 0, i32 0>\n" 675 " ret <2 x i32> %A\n" 676 "}\n"); 677 EXPECT_EQ(ComputeNumSignBits(A, M->getDataLayout()), 1u); 678 } 679 680 // No guarantees for canonical IR in this analysis, so a shuffle element that 681 // references an undef value means this can't return any extra information. 682 TEST_F(ValueTrackingTest, ComputeNumSignBits_Shuffle2) { 683 parseAssembly( 684 "define <2 x i32> @test(<2 x i1> %x) {\n" 685 " %sext = sext <2 x i1> %x to <2 x i32>\n" 686 " %A = shufflevector <2 x i32> %sext, <2 x i32> undef, <2 x i32> <i32 0, i32 2>\n" 687 " ret <2 x i32> %A\n" 688 "}\n"); 689 EXPECT_EQ(ComputeNumSignBits(A, M->getDataLayout()), 1u); 690 } 691 692 TEST(ValueTracking, propagatesPoison) { 693 std::string AsmHead = "declare i32 @g(i32)\n" 694 "define void @f(i32 %x, i32 %y, float %fx, float %fy, " 695 "i1 %cond, i8* %p) {\n"; 696 std::string AsmTail = " ret void\n}"; 697 // (propagates poison?, IR instruction) 698 SmallVector<std::pair<bool, std::string>, 32> Data = { 699 {true, "add i32 %x, %y"}, 700 {true, "add nsw nuw i32 %x, %y"}, 701 {true, "ashr i32 %x, %y"}, 702 {true, "lshr exact i32 %x, 31"}, 703 {true, "fcmp oeq float %fx, %fy"}, 704 {true, "icmp eq i32 %x, %y"}, 705 {true, "getelementptr i8, i8* %p, i32 %x"}, 706 {true, "getelementptr inbounds i8, i8* %p, i32 %x"}, 707 {true, "bitcast float %fx to i32"}, 708 {false, "select i1 %cond, i32 %x, i32 %y"}, 709 {false, "freeze i32 %x"}, 710 {true, "udiv i32 %x, %y"}, 711 {true, "urem i32 %x, %y"}, 712 {true, "sdiv exact i32 %x, %y"}, 713 {true, "srem i32 %x, %y"}, 714 {false, "call i32 @g(i32 %x)"}}; 715 716 std::string AssemblyStr = AsmHead; 717 for (auto &Itm : Data) 718 AssemblyStr += Itm.second + "\n"; 719 AssemblyStr += AsmTail; 720 721 LLVMContext Context; 722 SMDiagnostic Error; 723 auto M = parseAssemblyString(AssemblyStr, Error, Context); 724 assert(M && "Bad assembly?"); 725 726 auto *F = M->getFunction("f"); 727 assert(F && "Bad assembly?"); 728 729 auto &BB = F->getEntryBlock(); 730 731 int Index = 0; 732 for (auto &I : BB) { 733 if (isa<ReturnInst>(&I)) 734 break; 735 EXPECT_EQ(propagatesPoison(cast<Operator>(&I)), Data[Index].first) 736 << "Incorrect answer at instruction " << Index << " = " << I; 737 Index++; 738 } 739 } 740 741 TEST_F(ValueTrackingTest, programUndefinedIfPoison) { 742 parseAssembly("declare i32 @any_num()" 743 "define void @test(i32 %mask) {\n" 744 " %A = call i32 @any_num()\n" 745 " %B = or i32 %A, %mask\n" 746 " udiv i32 1, %B" 747 " ret void\n" 748 "}\n"); 749 // If %A was poison, udiv raises UB regardless of %mask's value 750 EXPECT_EQ(programUndefinedIfPoison(A), true); 751 } 752 753 TEST_F(ValueTrackingTest, programUndefinedIfUndefOrPoison) { 754 parseAssembly("declare i32 @any_num()" 755 "define void @test(i32 %mask) {\n" 756 " %A = call i32 @any_num()\n" 757 " %B = or i32 %A, %mask\n" 758 " udiv i32 1, %B" 759 " ret void\n" 760 "}\n"); 761 // If %A was undef and %mask was 1, udiv does not raise UB 762 EXPECT_EQ(programUndefinedIfUndefOrPoison(A), false); 763 } 764 765 TEST_F(ValueTrackingTest, isGuaranteedNotToBePoison_exploitBranchCond) { 766 parseAssembly("declare i1 @any_bool()" 767 "define void @test(i1 %y) {\n" 768 " %A = call i1 @any_bool()\n" 769 " %cond = and i1 %A, %y\n" 770 " br i1 %cond, label %BB1, label %BB2\n" 771 "BB1:\n" 772 " ret void\n" 773 "BB2:\n" 774 " ret void\n" 775 "}\n"); 776 DominatorTree DT(*F); 777 for (auto &BB : *F) { 778 if (&BB == &F->getEntryBlock()) 779 continue; 780 781 EXPECT_EQ(isGuaranteedNotToBePoison(A, nullptr, BB.getTerminator(), &DT), 782 true) 783 << "isGuaranteedNotToBePoison does not hold at " << *BB.getTerminator(); 784 } 785 } 786 787 TEST_F(ValueTrackingTest, isGuaranteedNotToBePoison_phi) { 788 parseAssembly("declare i32 @any_i32(i32)" 789 "define void @test() {\n" 790 "ENTRY:\n" 791 " br label %LOOP\n" 792 "LOOP:\n" 793 " %A = phi i32 [0, %ENTRY], [%A.next, %NEXT]\n" 794 " %A.next = call i32 @any_i32(i32 %A)\n" 795 " %cond = icmp eq i32 %A.next, 0\n" 796 " br i1 %cond, label %NEXT, label %EXIT\n" 797 "NEXT:\n" 798 " br label %LOOP\n" 799 "EXIT:\n" 800 " ret void\n" 801 "}\n"); 802 DominatorTree DT(*F); 803 for (auto &BB : *F) { 804 if (BB.getName() == "LOOP") { 805 EXPECT_EQ(isGuaranteedNotToBePoison(A, nullptr, A, &DT), true) 806 << "isGuaranteedNotToBePoison does not hold"; 807 } 808 } 809 } 810 811 TEST_F(ValueTrackingTest, isGuaranteedNotToBeUndefOrPoison) { 812 parseAssembly("declare void @f(i32 noundef)" 813 "define void @test(i32 %x) {\n" 814 " %A = bitcast i32 %x to i32\n" 815 " call void @f(i32 noundef %x)\n" 816 " ret void\n" 817 "}\n"); 818 EXPECT_EQ(isGuaranteedNotToBeUndefOrPoison(A), true); 819 } 820 821 TEST_F(ValueTrackingTest, isGuaranteedNotToBeUndefOrPoison_assume) { 822 parseAssembly("declare i1 @f_i1()\n" 823 "declare i32 @f_i32()\n" 824 "declare void @llvm.assume(i1)\n" 825 "define void @test() {\n" 826 " %A = call i32 @f_i32()\n" 827 " %cond = call i1 @f_i1()\n" 828 " %CxtI = add i32 0, 0\n" 829 " br i1 %cond, label %BB1, label %EXIT\n" 830 "BB1:\n" 831 " %CxtI2 = add i32 0, 0\n" 832 " %cond2 = call i1 @f_i1()\n" 833 " call void @llvm.assume(i1 true) [ \"noundef\"(i32 %A) ]\n" 834 " br i1 %cond2, label %BB2, label %EXIT\n" 835 "BB2:\n" 836 " %CxtI3 = add i32 0, 0\n" 837 " ret void\n" 838 "EXIT:\n" 839 " ret void\n" 840 "}"); 841 AssumptionCache AC(*F); 842 DominatorTree DT(*F); 843 EXPECT_FALSE(isGuaranteedNotToBeUndefOrPoison(A, &AC, CxtI, &DT)); 844 EXPECT_FALSE(isGuaranteedNotToBeUndefOrPoison(A, &AC, CxtI2, &DT)); 845 EXPECT_TRUE(isGuaranteedNotToBeUndefOrPoison(A, &AC, CxtI3, &DT)); 846 } 847 848 TEST(ValueTracking, canCreatePoisonOrUndef) { 849 std::string AsmHead = 850 "declare i32 @g(i32)\n" 851 "define void @f(i32 %x, i32 %y, float %fx, float %fy, i1 %cond, " 852 "<4 x i32> %vx, <4 x i32> %vx2, <vscale x 4 x i32> %svx, i8* %p) {\n"; 853 std::string AsmTail = " ret void\n}"; 854 // (can create poison?, can create undef?, IR instruction) 855 SmallVector<std::pair<std::pair<bool, bool>, std::string>, 32> Data = { 856 {{false, false}, "add i32 %x, %y"}, 857 {{true, false}, "add nsw nuw i32 %x, %y"}, 858 {{true, false}, "shl i32 %x, %y"}, 859 {{true, false}, "shl <4 x i32> %vx, %vx2"}, 860 {{true, false}, "shl nsw i32 %x, %y"}, 861 {{true, false}, "shl nsw <4 x i32> %vx, <i32 0, i32 1, i32 2, i32 3>"}, 862 {{false, false}, "shl i32 %x, 31"}, 863 {{true, false}, "shl i32 %x, 32"}, 864 {{false, false}, "shl <4 x i32> %vx, <i32 0, i32 1, i32 2, i32 3>"}, 865 {{true, false}, "shl <4 x i32> %vx, <i32 0, i32 1, i32 2, i32 32>"}, 866 {{true, false}, "ashr i32 %x, %y"}, 867 {{true, false}, "ashr exact i32 %x, %y"}, 868 {{false, false}, "ashr i32 %x, 31"}, 869 {{true, false}, "ashr exact i32 %x, 31"}, 870 {{false, false}, "ashr <4 x i32> %vx, <i32 0, i32 1, i32 2, i32 3>"}, 871 {{true, false}, "ashr <4 x i32> %vx, <i32 0, i32 1, i32 2, i32 32>"}, 872 {{true, false}, "ashr exact <4 x i32> %vx, <i32 0, i32 1, i32 2, i32 3>"}, 873 {{true, false}, "lshr i32 %x, %y"}, 874 {{true, false}, "lshr exact i32 %x, 31"}, 875 {{false, false}, "udiv i32 %x, %y"}, 876 {{true, false}, "udiv exact i32 %x, %y"}, 877 {{false, false}, "getelementptr i8, i8* %p, i32 %x"}, 878 {{true, false}, "getelementptr inbounds i8, i8* %p, i32 %x"}, 879 {{true, false}, "fneg nnan float %fx"}, 880 {{false, false}, "fneg float %fx"}, 881 {{false, false}, "fadd float %fx, %fy"}, 882 {{true, false}, "fadd nnan float %fx, %fy"}, 883 {{false, false}, "urem i32 %x, %y"}, 884 {{true, false}, "fptoui float %fx to i32"}, 885 {{true, false}, "fptosi float %fx to i32"}, 886 {{false, false}, "bitcast float %fx to i32"}, 887 {{false, false}, "select i1 %cond, i32 %x, i32 %y"}, 888 {{true, false}, "select nnan i1 %cond, float %fx, float %fy"}, 889 {{true, false}, "extractelement <4 x i32> %vx, i32 %x"}, 890 {{false, false}, "extractelement <4 x i32> %vx, i32 3"}, 891 {{true, false}, "extractelement <vscale x 4 x i32> %svx, i32 4"}, 892 {{true, false}, "insertelement <4 x i32> %vx, i32 %x, i32 %y"}, 893 {{false, false}, "insertelement <4 x i32> %vx, i32 %x, i32 3"}, 894 {{true, false}, "insertelement <vscale x 4 x i32> %svx, i32 %x, i32 4"}, 895 {{false, false}, "freeze i32 %x"}, 896 {{false, false}, 897 "shufflevector <4 x i32> %vx, <4 x i32> %vx2, " 898 "<4 x i32> <i32 0, i32 1, i32 2, i32 3>"}, 899 {{false, true}, 900 "shufflevector <4 x i32> %vx, <4 x i32> %vx2, " 901 "<4 x i32> <i32 0, i32 1, i32 2, i32 undef>"}, 902 {{false, true}, 903 "shufflevector <vscale x 4 x i32> %svx, " 904 "<vscale x 4 x i32> %svx, <vscale x 4 x i32> undef"}, 905 {{true, false}, "call i32 @g(i32 %x)"}, 906 {{false, false}, "call noundef i32 @g(i32 %x)"}, 907 {{true, false}, "fcmp nnan oeq float %fx, %fy"}, 908 {{false, false}, "fcmp oeq float %fx, %fy"}}; 909 910 std::string AssemblyStr = AsmHead; 911 for (auto &Itm : Data) 912 AssemblyStr += Itm.second + "\n"; 913 AssemblyStr += AsmTail; 914 915 LLVMContext Context; 916 SMDiagnostic Error; 917 auto M = parseAssemblyString(AssemblyStr, Error, Context); 918 assert(M && "Bad assembly?"); 919 920 auto *F = M->getFunction("f"); 921 assert(F && "Bad assembly?"); 922 923 auto &BB = F->getEntryBlock(); 924 925 int Index = 0; 926 for (auto &I : BB) { 927 if (isa<ReturnInst>(&I)) 928 break; 929 bool Poison = Data[Index].first.first; 930 bool Undef = Data[Index].first.second; 931 EXPECT_EQ(canCreatePoison(cast<Operator>(&I)), Poison) 932 << "Incorrect answer of canCreatePoison at instruction " << Index 933 << " = " << I; 934 EXPECT_EQ(canCreateUndefOrPoison(cast<Operator>(&I)), Undef || Poison) 935 << "Incorrect answer of canCreateUndef at instruction " << Index 936 << " = " << I; 937 Index++; 938 } 939 } 940 941 TEST_F(ComputeKnownBitsTest, ComputeKnownBits) { 942 parseAssembly( 943 "define i32 @test(i32 %a, i32 %b) {\n" 944 " %ash = mul i32 %a, 8\n" 945 " %aad = add i32 %ash, 7\n" 946 " %aan = and i32 %aad, 4095\n" 947 " %bsh = shl i32 %b, 4\n" 948 " %bad = or i32 %bsh, 6\n" 949 " %ban = and i32 %bad, 4095\n" 950 " %A = mul i32 %aan, %ban\n" 951 " ret i32 %A\n" 952 "}\n"); 953 expectKnownBits(/*zero*/ 4278190085u, /*one*/ 10u); 954 } 955 956 TEST_F(ComputeKnownBitsTest, ComputeKnownMulBits) { 957 parseAssembly( 958 "define i32 @test(i32 %a, i32 %b) {\n" 959 " %aa = shl i32 %a, 5\n" 960 " %bb = shl i32 %b, 5\n" 961 " %aaa = or i32 %aa, 24\n" 962 " %bbb = or i32 %bb, 28\n" 963 " %A = mul i32 %aaa, %bbb\n" 964 " ret i32 %A\n" 965 "}\n"); 966 expectKnownBits(/*zero*/ 95u, /*one*/ 32u); 967 } 968 969 TEST_F(ComputeKnownBitsTest, KnownNonZeroShift) { 970 // %q is known nonzero without known bits. 971 // Because %q is nonzero, %A[0] is known to be zero. 972 parseAssembly( 973 "define i8 @test(i8 %p, i8* %pq) {\n" 974 " %q = load i8, i8* %pq, !range !0\n" 975 " %A = shl i8 %p, %q\n" 976 " ret i8 %A\n" 977 "}\n" 978 "!0 = !{ i8 1, i8 5 }\n"); 979 expectKnownBits(/*zero*/ 1u, /*one*/ 0u); 980 } 981 982 TEST_F(ComputeKnownBitsTest, ComputeKnownFshl) { 983 // fshl(....1111....0000, 00..1111........, 6) 984 // = 11....000000..11 985 parseAssembly( 986 "define i16 @test(i16 %a, i16 %b) {\n" 987 " %aa = shl i16 %a, 4\n" 988 " %bb = lshr i16 %b, 2\n" 989 " %aaa = or i16 %aa, 3840\n" 990 " %bbb = or i16 %bb, 3840\n" 991 " %A = call i16 @llvm.fshl.i16(i16 %aaa, i16 %bbb, i16 6)\n" 992 " ret i16 %A\n" 993 "}\n" 994 "declare i16 @llvm.fshl.i16(i16, i16, i16)\n"); 995 expectKnownBits(/*zero*/ 1008u, /*one*/ 49155u); 996 } 997 998 TEST_F(ComputeKnownBitsTest, ComputeKnownFshr) { 999 // fshr(....1111....0000, 00..1111........, 26) 1000 // = 11....000000..11 1001 parseAssembly( 1002 "define i16 @test(i16 %a, i16 %b) {\n" 1003 " %aa = shl i16 %a, 4\n" 1004 " %bb = lshr i16 %b, 2\n" 1005 " %aaa = or i16 %aa, 3840\n" 1006 " %bbb = or i16 %bb, 3840\n" 1007 " %A = call i16 @llvm.fshr.i16(i16 %aaa, i16 %bbb, i16 26)\n" 1008 " ret i16 %A\n" 1009 "}\n" 1010 "declare i16 @llvm.fshr.i16(i16, i16, i16)\n"); 1011 expectKnownBits(/*zero*/ 1008u, /*one*/ 49155u); 1012 } 1013 1014 TEST_F(ComputeKnownBitsTest, ComputeKnownFshlZero) { 1015 // fshl(....1111....0000, 00..1111........, 0) 1016 // = ....1111....0000 1017 parseAssembly( 1018 "define i16 @test(i16 %a, i16 %b) {\n" 1019 " %aa = shl i16 %a, 4\n" 1020 " %bb = lshr i16 %b, 2\n" 1021 " %aaa = or i16 %aa, 3840\n" 1022 " %bbb = or i16 %bb, 3840\n" 1023 " %A = call i16 @llvm.fshl.i16(i16 %aaa, i16 %bbb, i16 0)\n" 1024 " ret i16 %A\n" 1025 "}\n" 1026 "declare i16 @llvm.fshl.i16(i16, i16, i16)\n"); 1027 expectKnownBits(/*zero*/ 15u, /*one*/ 3840u); 1028 } 1029 1030 TEST_F(ComputeKnownBitsTest, ComputeKnownUAddSatLeadingOnes) { 1031 // uadd.sat(1111...1, ........) 1032 // = 1111.... 1033 parseAssembly( 1034 "define i8 @test(i8 %a, i8 %b) {\n" 1035 " %aa = or i8 %a, 241\n" 1036 " %A = call i8 @llvm.uadd.sat.i8(i8 %aa, i8 %b)\n" 1037 " ret i8 %A\n" 1038 "}\n" 1039 "declare i8 @llvm.uadd.sat.i8(i8, i8)\n"); 1040 expectKnownBits(/*zero*/ 0u, /*one*/ 240u); 1041 } 1042 1043 TEST_F(ComputeKnownBitsTest, ComputeKnownUAddSatOnesPreserved) { 1044 // uadd.sat(00...011, .1...110) 1045 // = .......1 1046 parseAssembly( 1047 "define i8 @test(i8 %a, i8 %b) {\n" 1048 " %aa = or i8 %a, 3\n" 1049 " %aaa = and i8 %aa, 59\n" 1050 " %bb = or i8 %b, 70\n" 1051 " %bbb = and i8 %bb, 254\n" 1052 " %A = call i8 @llvm.uadd.sat.i8(i8 %aaa, i8 %bbb)\n" 1053 " ret i8 %A\n" 1054 "}\n" 1055 "declare i8 @llvm.uadd.sat.i8(i8, i8)\n"); 1056 expectKnownBits(/*zero*/ 0u, /*one*/ 1u); 1057 } 1058 1059 TEST_F(ComputeKnownBitsTest, ComputeKnownUSubSatLHSLeadingZeros) { 1060 // usub.sat(0000...0, ........) 1061 // = 0000.... 1062 parseAssembly( 1063 "define i8 @test(i8 %a, i8 %b) {\n" 1064 " %aa = and i8 %a, 14\n" 1065 " %A = call i8 @llvm.usub.sat.i8(i8 %aa, i8 %b)\n" 1066 " ret i8 %A\n" 1067 "}\n" 1068 "declare i8 @llvm.usub.sat.i8(i8, i8)\n"); 1069 expectKnownBits(/*zero*/ 240u, /*one*/ 0u); 1070 } 1071 1072 TEST_F(ComputeKnownBitsTest, ComputeKnownUSubSatRHSLeadingOnes) { 1073 // usub.sat(........, 1111...1) 1074 // = 0000.... 1075 parseAssembly( 1076 "define i8 @test(i8 %a, i8 %b) {\n" 1077 " %bb = or i8 %a, 241\n" 1078 " %A = call i8 @llvm.usub.sat.i8(i8 %a, i8 %bb)\n" 1079 " ret i8 %A\n" 1080 "}\n" 1081 "declare i8 @llvm.usub.sat.i8(i8, i8)\n"); 1082 expectKnownBits(/*zero*/ 240u, /*one*/ 0u); 1083 } 1084 1085 TEST_F(ComputeKnownBitsTest, ComputeKnownUSubSatZerosPreserved) { 1086 // usub.sat(11...011, .1...110) 1087 // = ......0. 1088 parseAssembly( 1089 "define i8 @test(i8 %a, i8 %b) {\n" 1090 " %aa = or i8 %a, 195\n" 1091 " %aaa = and i8 %aa, 251\n" 1092 " %bb = or i8 %b, 70\n" 1093 " %bbb = and i8 %bb, 254\n" 1094 " %A = call i8 @llvm.usub.sat.i8(i8 %aaa, i8 %bbb)\n" 1095 " ret i8 %A\n" 1096 "}\n" 1097 "declare i8 @llvm.usub.sat.i8(i8, i8)\n"); 1098 expectKnownBits(/*zero*/ 2u, /*one*/ 0u); 1099 } 1100 1101 TEST_F(ComputeKnownBitsTest, ComputeKnownBitsPtrToIntTrunc) { 1102 // ptrtoint truncates the pointer type. 1103 parseAssembly( 1104 "define void @test(i8** %p) {\n" 1105 " %A = load i8*, i8** %p\n" 1106 " %i = ptrtoint i8* %A to i32\n" 1107 " %m = and i32 %i, 31\n" 1108 " %c = icmp eq i32 %m, 0\n" 1109 " call void @llvm.assume(i1 %c)\n" 1110 " ret void\n" 1111 "}\n" 1112 "declare void @llvm.assume(i1)\n"); 1113 AssumptionCache AC(*F); 1114 KnownBits Known = computeKnownBits( 1115 A, M->getDataLayout(), /* Depth */ 0, &AC, F->front().getTerminator()); 1116 EXPECT_EQ(Known.Zero.getZExtValue(), 31u); 1117 EXPECT_EQ(Known.One.getZExtValue(), 0u); 1118 } 1119 1120 TEST_F(ComputeKnownBitsTest, ComputeKnownBitsPtrToIntZext) { 1121 // ptrtoint zero extends the pointer type. 1122 parseAssembly( 1123 "define void @test(i8** %p) {\n" 1124 " %A = load i8*, i8** %p\n" 1125 " %i = ptrtoint i8* %A to i128\n" 1126 " %m = and i128 %i, 31\n" 1127 " %c = icmp eq i128 %m, 0\n" 1128 " call void @llvm.assume(i1 %c)\n" 1129 " ret void\n" 1130 "}\n" 1131 "declare void @llvm.assume(i1)\n"); 1132 AssumptionCache AC(*F); 1133 KnownBits Known = computeKnownBits( 1134 A, M->getDataLayout(), /* Depth */ 0, &AC, F->front().getTerminator()); 1135 EXPECT_EQ(Known.Zero.getZExtValue(), 31u); 1136 EXPECT_EQ(Known.One.getZExtValue(), 0u); 1137 } 1138 1139 TEST_F(ComputeKnownBitsTest, ComputeKnownBitsFreeze) { 1140 parseAssembly("define void @test() {\n" 1141 " %m = call i32 @any_num()\n" 1142 " %A = freeze i32 %m\n" 1143 " %n = and i32 %m, 31\n" 1144 " %c = icmp eq i32 %n, 0\n" 1145 " call void @llvm.assume(i1 %c)\n" 1146 " ret void\n" 1147 "}\n" 1148 "declare void @llvm.assume(i1)\n" 1149 "declare i32 @any_num()\n"); 1150 AssumptionCache AC(*F); 1151 KnownBits Known = computeKnownBits(A, M->getDataLayout(), /* Depth */ 0, &AC, 1152 F->front().getTerminator()); 1153 EXPECT_EQ(Known.Zero.getZExtValue(), 31u); 1154 EXPECT_EQ(Known.One.getZExtValue(), 0u); 1155 } 1156 1157 TEST_F(ComputeKnownBitsTest, ComputeKnownBitsAddWithRange) { 1158 parseAssembly("define void @test(i64* %p) {\n" 1159 " %A = load i64, i64* %p, !range !{i64 64, i64 65536}\n" 1160 " %APlus512 = add i64 %A, 512\n" 1161 " %c = icmp ugt i64 %APlus512, 523\n" 1162 " call void @llvm.assume(i1 %c)\n" 1163 " ret void\n" 1164 "}\n" 1165 "declare void @llvm.assume(i1)\n"); 1166 AssumptionCache AC(*F); 1167 KnownBits Known = computeKnownBits(A, M->getDataLayout(), /* Depth */ 0, &AC, 1168 F->front().getTerminator()); 1169 EXPECT_EQ(Known.Zero.getZExtValue(), ~(65536llu - 1)); 1170 EXPECT_EQ(Known.One.getZExtValue(), 0u); 1171 Instruction &APlus512 = findInstructionByName(F, "APlus512"); 1172 Known = computeKnownBits(&APlus512, M->getDataLayout(), /* Depth */ 0, &AC, 1173 F->front().getTerminator()); 1174 // We know of one less zero because 512 may have produced a 1 that 1175 // got carried all the way to the first trailing zero. 1176 EXPECT_EQ(Known.Zero.getZExtValue(), (~(65536llu - 1)) << 1); 1177 EXPECT_EQ(Known.One.getZExtValue(), 0u); 1178 // The known range is not precise given computeKnownBits works 1179 // with the masks of zeros and ones, not the ranges. 1180 EXPECT_EQ(Known.getMinValue(), 0u); 1181 EXPECT_EQ(Known.getMaxValue(), 131071); 1182 } 1183 1184 // 512 + [32, 64) doesn't produce overlapping bits. 1185 // Make sure we get all the individual bits properly. 1186 TEST_F(ComputeKnownBitsTest, ComputeKnownBitsAddWithRangeNoOverlap) { 1187 parseAssembly("define void @test(i64* %p) {\n" 1188 " %A = load i64, i64* %p, !range !{i64 32, i64 64}\n" 1189 " %APlus512 = add i64 %A, 512\n" 1190 " %c = icmp ugt i64 %APlus512, 523\n" 1191 " call void @llvm.assume(i1 %c)\n" 1192 " ret void\n" 1193 "}\n" 1194 "declare void @llvm.assume(i1)\n"); 1195 AssumptionCache AC(*F); 1196 KnownBits Known = computeKnownBits(A, M->getDataLayout(), /* Depth */ 0, &AC, 1197 F->front().getTerminator()); 1198 EXPECT_EQ(Known.Zero.getZExtValue(), ~(64llu - 1)); 1199 EXPECT_EQ(Known.One.getZExtValue(), 32u); 1200 Instruction &APlus512 = findInstructionByName(F, "APlus512"); 1201 Known = computeKnownBits(&APlus512, M->getDataLayout(), /* Depth */ 0, &AC, 1202 F->front().getTerminator()); 1203 EXPECT_EQ(Known.Zero.getZExtValue(), ~512llu & ~(64llu - 1)); 1204 EXPECT_EQ(Known.One.getZExtValue(), 512u | 32u); 1205 // The known range is not precise given computeKnownBits works 1206 // with the masks of zeros and ones, not the ranges. 1207 EXPECT_EQ(Known.getMinValue(), 544); 1208 EXPECT_EQ(Known.getMaxValue(), 575); 1209 } 1210 1211 class IsBytewiseValueTest : public ValueTrackingTest, 1212 public ::testing::WithParamInterface< 1213 std::pair<const char *, const char *>> { 1214 protected: 1215 }; 1216 1217 const std::pair<const char *, const char *> IsBytewiseValueTests[] = { 1218 { 1219 "i8 0", 1220 "i48* null", 1221 }, 1222 { 1223 "i8 undef", 1224 "i48* undef", 1225 }, 1226 { 1227 "i8 0", 1228 "i8 zeroinitializer", 1229 }, 1230 { 1231 "i8 0", 1232 "i8 0", 1233 }, 1234 { 1235 "i8 -86", 1236 "i8 -86", 1237 }, 1238 { 1239 "i8 -1", 1240 "i8 -1", 1241 }, 1242 { 1243 "i8 undef", 1244 "i16 undef", 1245 }, 1246 { 1247 "i8 0", 1248 "i16 0", 1249 }, 1250 { 1251 "", 1252 "i16 7", 1253 }, 1254 { 1255 "i8 -86", 1256 "i16 -21846", 1257 }, 1258 { 1259 "i8 -1", 1260 "i16 -1", 1261 }, 1262 { 1263 "i8 0", 1264 "i48 0", 1265 }, 1266 { 1267 "i8 -1", 1268 "i48 -1", 1269 }, 1270 { 1271 "i8 0", 1272 "i49 0", 1273 }, 1274 { 1275 "", 1276 "i49 -1", 1277 }, 1278 { 1279 "i8 0", 1280 "half 0xH0000", 1281 }, 1282 { 1283 "i8 -85", 1284 "half 0xHABAB", 1285 }, 1286 { 1287 "i8 0", 1288 "float 0.0", 1289 }, 1290 { 1291 "i8 -1", 1292 "float 0xFFFFFFFFE0000000", 1293 }, 1294 { 1295 "i8 0", 1296 "double 0.0", 1297 }, 1298 { 1299 "i8 -15", 1300 "double 0xF1F1F1F1F1F1F1F1", 1301 }, 1302 { 1303 "i8 undef", 1304 "i16* undef", 1305 }, 1306 { 1307 "i8 0", 1308 "i16* inttoptr (i64 0 to i16*)", 1309 }, 1310 { 1311 "i8 -1", 1312 "i16* inttoptr (i64 -1 to i16*)", 1313 }, 1314 { 1315 "i8 -86", 1316 "i16* inttoptr (i64 -6148914691236517206 to i16*)", 1317 }, 1318 { 1319 "", 1320 "i16* inttoptr (i48 -1 to i16*)", 1321 }, 1322 { 1323 "i8 -1", 1324 "i16* inttoptr (i96 -1 to i16*)", 1325 }, 1326 { 1327 "i8 undef", 1328 "[0 x i8] zeroinitializer", 1329 }, 1330 { 1331 "i8 undef", 1332 "[0 x i8] undef", 1333 }, 1334 { 1335 "i8 undef", 1336 "[5 x [0 x i8]] zeroinitializer", 1337 }, 1338 { 1339 "i8 undef", 1340 "[5 x [0 x i8]] undef", 1341 }, 1342 { 1343 "i8 0", 1344 "[6 x i8] zeroinitializer", 1345 }, 1346 { 1347 "i8 undef", 1348 "[6 x i8] undef", 1349 }, 1350 { 1351 "i8 1", 1352 "[5 x i8] [i8 1, i8 1, i8 1, i8 1, i8 1]", 1353 }, 1354 { 1355 "", 1356 "[5 x i64] [i64 1, i64 1, i64 1, i64 1, i64 1]", 1357 }, 1358 { 1359 "i8 -1", 1360 "[5 x i64] [i64 -1, i64 -1, i64 -1, i64 -1, i64 -1]", 1361 }, 1362 { 1363 "", 1364 "[4 x i8] [i8 1, i8 2, i8 1, i8 1]", 1365 }, 1366 { 1367 "i8 1", 1368 "[4 x i8] [i8 1, i8 undef, i8 1, i8 1]", 1369 }, 1370 { 1371 "i8 0", 1372 "<6 x i8> zeroinitializer", 1373 }, 1374 { 1375 "i8 undef", 1376 "<6 x i8> undef", 1377 }, 1378 { 1379 "i8 1", 1380 "<5 x i8> <i8 1, i8 1, i8 1, i8 1, i8 1>", 1381 }, 1382 { 1383 "", 1384 "<5 x i64> <i64 1, i64 1, i64 1, i64 1, i64 1>", 1385 }, 1386 { 1387 "i8 -1", 1388 "<5 x i64> <i64 -1, i64 -1, i64 -1, i64 -1, i64 -1>", 1389 }, 1390 { 1391 "", 1392 "<4 x i8> <i8 1, i8 1, i8 2, i8 1>", 1393 }, 1394 { 1395 "i8 5", 1396 "<2 x i8> < i8 5, i8 undef >", 1397 }, 1398 { 1399 "i8 0", 1400 "[2 x [2 x i16]] zeroinitializer", 1401 }, 1402 { 1403 "i8 undef", 1404 "[2 x [2 x i16]] undef", 1405 }, 1406 { 1407 "i8 -86", 1408 "[2 x [2 x i16]] [[2 x i16] [i16 -21846, i16 -21846], " 1409 "[2 x i16] [i16 -21846, i16 -21846]]", 1410 }, 1411 { 1412 "", 1413 "[2 x [2 x i16]] [[2 x i16] [i16 -21846, i16 -21846], " 1414 "[2 x i16] [i16 -21836, i16 -21846]]", 1415 }, 1416 { 1417 "i8 undef", 1418 "{ } zeroinitializer", 1419 }, 1420 { 1421 "i8 undef", 1422 "{ } undef", 1423 }, 1424 { 1425 "i8 undef", 1426 "{ {}, {} } zeroinitializer", 1427 }, 1428 { 1429 "i8 undef", 1430 "{ {}, {} } undef", 1431 }, 1432 { 1433 "i8 0", 1434 "{i8, i64, i16*} zeroinitializer", 1435 }, 1436 { 1437 "i8 undef", 1438 "{i8, i64, i16*} undef", 1439 }, 1440 { 1441 "i8 -86", 1442 "{i8, i64, i16*} {i8 -86, i64 -6148914691236517206, i16* undef}", 1443 }, 1444 { 1445 "", 1446 "{i8, i64, i16*} {i8 86, i64 -6148914691236517206, i16* undef}", 1447 }, 1448 }; 1449 1450 INSTANTIATE_TEST_CASE_P(IsBytewiseValueParamTests, IsBytewiseValueTest, 1451 ::testing::ValuesIn(IsBytewiseValueTests),); 1452 1453 TEST_P(IsBytewiseValueTest, IsBytewiseValue) { 1454 auto M = parseModule(std::string("@test = global ") + GetParam().second); 1455 GlobalVariable *GV = dyn_cast<GlobalVariable>(M->getNamedValue("test")); 1456 Value *Actual = isBytewiseValue(GV->getInitializer(), M->getDataLayout()); 1457 std::string Buff; 1458 raw_string_ostream S(Buff); 1459 if (Actual) 1460 S << *Actual; 1461 EXPECT_EQ(GetParam().first, S.str()); 1462 } 1463 1464 TEST_F(ValueTrackingTest, ComputeConstantRange) { 1465 { 1466 // Assumptions: 1467 // * stride >= 5 1468 // * stride < 10 1469 // 1470 // stride = [5, 10) 1471 auto M = parseModule(R"( 1472 declare void @llvm.assume(i1) 1473 1474 define i32 @test(i32 %stride) { 1475 %gt = icmp uge i32 %stride, 5 1476 call void @llvm.assume(i1 %gt) 1477 %lt = icmp ult i32 %stride, 10 1478 call void @llvm.assume(i1 %lt) 1479 %stride.plus.one = add nsw nuw i32 %stride, 1 1480 ret i32 %stride.plus.one 1481 })"); 1482 Function *F = M->getFunction("test"); 1483 1484 AssumptionCache AC(*F); 1485 Value *Stride = &*F->arg_begin(); 1486 ConstantRange CR1 = computeConstantRange(Stride, true, &AC, nullptr); 1487 EXPECT_TRUE(CR1.isFullSet()); 1488 1489 Instruction *I = &findInstructionByName(F, "stride.plus.one"); 1490 ConstantRange CR2 = computeConstantRange(Stride, true, &AC, I); 1491 EXPECT_EQ(5, CR2.getLower()); 1492 EXPECT_EQ(10, CR2.getUpper()); 1493 } 1494 1495 { 1496 // Assumptions: 1497 // * stride >= 5 1498 // * stride < 200 1499 // * stride == 99 1500 // 1501 // stride = [99, 100) 1502 auto M = parseModule(R"( 1503 declare void @llvm.assume(i1) 1504 1505 define i32 @test(i32 %stride) { 1506 %gt = icmp uge i32 %stride, 5 1507 call void @llvm.assume(i1 %gt) 1508 %lt = icmp ult i32 %stride, 200 1509 call void @llvm.assume(i1 %lt) 1510 %eq = icmp eq i32 %stride, 99 1511 call void @llvm.assume(i1 %eq) 1512 %stride.plus.one = add nsw nuw i32 %stride, 1 1513 ret i32 %stride.plus.one 1514 })"); 1515 Function *F = M->getFunction("test"); 1516 1517 AssumptionCache AC(*F); 1518 Value *Stride = &*F->arg_begin(); 1519 Instruction *I = &findInstructionByName(F, "stride.plus.one"); 1520 ConstantRange CR = computeConstantRange(Stride, true, &AC, I); 1521 EXPECT_EQ(99, *CR.getSingleElement()); 1522 } 1523 1524 { 1525 // Assumptions: 1526 // * stride >= 5 1527 // * stride >= 50 1528 // * stride < 100 1529 // * stride < 200 1530 // 1531 // stride = [50, 100) 1532 auto M = parseModule(R"( 1533 declare void @llvm.assume(i1) 1534 1535 define i32 @test(i32 %stride, i1 %cond) { 1536 %gt = icmp uge i32 %stride, 5 1537 call void @llvm.assume(i1 %gt) 1538 %gt.2 = icmp uge i32 %stride, 50 1539 call void @llvm.assume(i1 %gt.2) 1540 br i1 %cond, label %bb1, label %bb2 1541 1542 bb1: 1543 %lt = icmp ult i32 %stride, 200 1544 call void @llvm.assume(i1 %lt) 1545 %lt.2 = icmp ult i32 %stride, 100 1546 call void @llvm.assume(i1 %lt.2) 1547 %stride.plus.one = add nsw nuw i32 %stride, 1 1548 ret i32 %stride.plus.one 1549 1550 bb2: 1551 ret i32 0 1552 })"); 1553 Function *F = M->getFunction("test"); 1554 1555 AssumptionCache AC(*F); 1556 Value *Stride = &*F->arg_begin(); 1557 Instruction *GT2 = &findInstructionByName(F, "gt.2"); 1558 ConstantRange CR = computeConstantRange(Stride, true, &AC, GT2); 1559 EXPECT_EQ(5, CR.getLower()); 1560 EXPECT_EQ(0, CR.getUpper()); 1561 1562 Instruction *I = &findInstructionByName(F, "stride.plus.one"); 1563 ConstantRange CR2 = computeConstantRange(Stride, true, &AC, I); 1564 EXPECT_EQ(50, CR2.getLower()); 1565 EXPECT_EQ(100, CR2.getUpper()); 1566 } 1567 1568 { 1569 // Assumptions: 1570 // * stride > 5 1571 // * stride < 5 1572 // 1573 // stride = empty range, as the assumptions contradict each other. 1574 auto M = parseModule(R"( 1575 declare void @llvm.assume(i1) 1576 1577 define i32 @test(i32 %stride, i1 %cond) { 1578 %gt = icmp ugt i32 %stride, 5 1579 call void @llvm.assume(i1 %gt) 1580 %lt = icmp ult i32 %stride, 5 1581 call void @llvm.assume(i1 %lt) 1582 %stride.plus.one = add nsw nuw i32 %stride, 1 1583 ret i32 %stride.plus.one 1584 })"); 1585 Function *F = M->getFunction("test"); 1586 1587 AssumptionCache AC(*F); 1588 Value *Stride = &*F->arg_begin(); 1589 1590 Instruction *I = &findInstructionByName(F, "stride.plus.one"); 1591 ConstantRange CR = computeConstantRange(Stride, true, &AC, I); 1592 EXPECT_TRUE(CR.isEmptySet()); 1593 } 1594 1595 { 1596 // Assumptions: 1597 // * x.1 >= 5 1598 // * x.2 < x.1 1599 // 1600 // stride = [0, 5) 1601 auto M = parseModule(R"( 1602 declare void @llvm.assume(i1) 1603 1604 define i32 @test(i32 %x.1, i32 %x.2) { 1605 %gt = icmp uge i32 %x.1, 5 1606 call void @llvm.assume(i1 %gt) 1607 %lt = icmp ult i32 %x.2, %x.1 1608 call void @llvm.assume(i1 %lt) 1609 %stride.plus.one = add nsw nuw i32 %x.1, 1 1610 ret i32 %stride.plus.one 1611 })"); 1612 Function *F = M->getFunction("test"); 1613 1614 AssumptionCache AC(*F); 1615 Value *X2 = &*std::next(F->arg_begin()); 1616 1617 Instruction *I = &findInstructionByName(F, "stride.plus.one"); 1618 ConstantRange CR1 = computeConstantRange(X2, true, &AC, I); 1619 EXPECT_EQ(0, CR1.getLower()); 1620 EXPECT_EQ(5, CR1.getUpper()); 1621 1622 // Check the depth cutoff results in a conservative result (full set) by 1623 // passing Depth == MaxDepth == 6. 1624 ConstantRange CR2 = computeConstantRange(X2, true, &AC, I, 6); 1625 EXPECT_TRUE(CR2.isFullSet()); 1626 } 1627 } 1628 1629 struct FindAllocaForValueTestParams { 1630 const char *IR; 1631 bool AnyOffsetResult; 1632 bool ZeroOffsetResult; 1633 }; 1634 1635 class FindAllocaForValueTest 1636 : public ValueTrackingTest, 1637 public ::testing::WithParamInterface<FindAllocaForValueTestParams> { 1638 protected: 1639 }; 1640 1641 const FindAllocaForValueTestParams FindAllocaForValueTests[] = { 1642 {R"( 1643 define void @test() { 1644 %a = alloca i64 1645 %r = bitcast i64* %a to i32* 1646 ret void 1647 })", 1648 true, true}, 1649 1650 {R"( 1651 define void @test() { 1652 %a = alloca i32 1653 %r = getelementptr i32, i32* %a, i32 1 1654 ret void 1655 })", 1656 true, false}, 1657 1658 {R"( 1659 define void @test() { 1660 %a = alloca i32 1661 %r = getelementptr i32, i32* %a, i32 0 1662 ret void 1663 })", 1664 true, true}, 1665 1666 {R"( 1667 define void @test(i1 %cond) { 1668 entry: 1669 %a = alloca i32 1670 br label %bb1 1671 1672 bb1: 1673 %r = phi i32* [ %a, %entry ], [ %r, %bb1 ] 1674 br i1 %cond, label %bb1, label %exit 1675 1676 exit: 1677 ret void 1678 })", 1679 true, true}, 1680 1681 {R"( 1682 define void @test(i1 %cond) { 1683 %a = alloca i32 1684 %r = select i1 %cond, i32* %a, i32* %a 1685 ret void 1686 })", 1687 true, true}, 1688 1689 {R"( 1690 define void @test(i1 %cond) { 1691 %a = alloca i32 1692 %b = alloca i32 1693 %r = select i1 %cond, i32* %a, i32* %b 1694 ret void 1695 })", 1696 false, false}, 1697 1698 {R"( 1699 define void @test(i1 %cond) { 1700 entry: 1701 %a = alloca i64 1702 %a32 = bitcast i64* %a to i32* 1703 br label %bb1 1704 1705 bb1: 1706 %x = phi i32* [ %a32, %entry ], [ %x, %bb1 ] 1707 %r = getelementptr i32, i32* %x, i32 1 1708 br i1 %cond, label %bb1, label %exit 1709 1710 exit: 1711 ret void 1712 })", 1713 true, false}, 1714 1715 {R"( 1716 define void @test(i1 %cond) { 1717 entry: 1718 %a = alloca i64 1719 %a32 = bitcast i64* %a to i32* 1720 br label %bb1 1721 1722 bb1: 1723 %x = phi i32* [ %a32, %entry ], [ %r, %bb1 ] 1724 %r = getelementptr i32, i32* %x, i32 1 1725 br i1 %cond, label %bb1, label %exit 1726 1727 exit: 1728 ret void 1729 })", 1730 true, false}, 1731 1732 {R"( 1733 define void @test(i1 %cond, i64* %a) { 1734 entry: 1735 %r = bitcast i64* %a to i32* 1736 ret void 1737 })", 1738 false, false}, 1739 1740 {R"( 1741 define void @test(i1 %cond) { 1742 entry: 1743 %a = alloca i32 1744 %b = alloca i32 1745 br label %bb1 1746 1747 bb1: 1748 %r = phi i32* [ %a, %entry ], [ %b, %bb1 ] 1749 br i1 %cond, label %bb1, label %exit 1750 1751 exit: 1752 ret void 1753 })", 1754 false, false}, 1755 }; 1756 1757 TEST_P(FindAllocaForValueTest, findAllocaForValue) { 1758 auto M = parseModule(GetParam().IR); 1759 Function *F = M->getFunction("test"); 1760 Instruction *I = &findInstructionByName(F, "r"); 1761 const AllocaInst *AI = findAllocaForValue(I); 1762 EXPECT_EQ(!!AI, GetParam().AnyOffsetResult); 1763 } 1764 1765 TEST_P(FindAllocaForValueTest, findAllocaForValueZeroOffset) { 1766 auto M = parseModule(GetParam().IR); 1767 Function *F = M->getFunction("test"); 1768 Instruction *I = &findInstructionByName(F, "r"); 1769 const AllocaInst *AI = findAllocaForValue(I, true); 1770 EXPECT_EQ(!!AI, GetParam().ZeroOffsetResult); 1771 } 1772 1773 INSTANTIATE_TEST_CASE_P(FindAllocaForValueTest, FindAllocaForValueTest, 1774 ::testing::ValuesIn(FindAllocaForValueTests), ); 1775