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/AsmParser/Parser.h" 11 #include "llvm/IR/Function.h" 12 #include "llvm/IR/InstIterator.h" 13 #include "llvm/IR/Instructions.h" 14 #include "llvm/IR/LLVMContext.h" 15 #include "llvm/IR/Module.h" 16 #include "llvm/Support/ErrorHandling.h" 17 #include "llvm/Support/KnownBits.h" 18 #include "llvm/Support/SourceMgr.h" 19 #include "gtest/gtest.h" 20 21 using namespace llvm; 22 23 namespace { 24 25 class ValueTrackingTest : public testing::Test { 26 protected: 27 std::unique_ptr<Module> parseModule(StringRef Assembly) { 28 SMDiagnostic Error; 29 std::unique_ptr<Module> M = parseAssemblyString(Assembly, Error, Context); 30 31 std::string errMsg; 32 raw_string_ostream os(errMsg); 33 Error.print("", os); 34 EXPECT_TRUE(M) << os.str(); 35 36 return M; 37 } 38 39 void parseAssembly(StringRef Assembly) { 40 M = parseModule(Assembly); 41 ASSERT_TRUE(M); 42 43 Function *F = M->getFunction("test"); 44 ASSERT_TRUE(F) << "Test must have a function @test"; 45 if (!F) 46 return; 47 48 A = nullptr; 49 for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) { 50 if (I->hasName()) { 51 if (I->getName() == "A") 52 A = &*I; 53 } 54 } 55 ASSERT_TRUE(A) << "@test must have an instruction %A"; 56 } 57 58 LLVMContext Context; 59 std::unique_ptr<Module> M; 60 Instruction *A = nullptr; 61 }; 62 63 class MatchSelectPatternTest : public ValueTrackingTest { 64 protected: 65 void expectPattern(const SelectPatternResult &P) { 66 Value *LHS, *RHS; 67 Instruction::CastOps CastOp; 68 SelectPatternResult R = matchSelectPattern(A, LHS, RHS, &CastOp); 69 EXPECT_EQ(P.Flavor, R.Flavor); 70 EXPECT_EQ(P.NaNBehavior, R.NaNBehavior); 71 EXPECT_EQ(P.Ordered, R.Ordered); 72 } 73 }; 74 75 class ComputeKnownBitsTest : public ValueTrackingTest { 76 protected: 77 void expectKnownBits(uint64_t Zero, uint64_t One) { 78 auto Known = computeKnownBits(A, M->getDataLayout()); 79 ASSERT_FALSE(Known.hasConflict()); 80 EXPECT_EQ(Known.One.getZExtValue(), One); 81 EXPECT_EQ(Known.Zero.getZExtValue(), Zero); 82 } 83 }; 84 85 } 86 87 TEST_F(MatchSelectPatternTest, SimpleFMin) { 88 parseAssembly( 89 "define float @test(float %a) {\n" 90 " %1 = fcmp ult float %a, 5.0\n" 91 " %A = select i1 %1, float %a, float 5.0\n" 92 " ret float %A\n" 93 "}\n"); 94 expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, false}); 95 } 96 97 TEST_F(MatchSelectPatternTest, SimpleFMax) { 98 parseAssembly( 99 "define float @test(float %a) {\n" 100 " %1 = fcmp ogt float %a, 5.0\n" 101 " %A = select i1 %1, float %a, float 5.0\n" 102 " ret float %A\n" 103 "}\n"); 104 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, true}); 105 } 106 107 TEST_F(MatchSelectPatternTest, SwappedFMax) { 108 parseAssembly( 109 "define float @test(float %a) {\n" 110 " %1 = fcmp olt float 5.0, %a\n" 111 " %A = select i1 %1, float %a, float 5.0\n" 112 " ret float %A\n" 113 "}\n"); 114 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, false}); 115 } 116 117 TEST_F(MatchSelectPatternTest, SwappedFMax2) { 118 parseAssembly( 119 "define float @test(float %a) {\n" 120 " %1 = fcmp olt float %a, 5.0\n" 121 " %A = select i1 %1, float 5.0, float %a\n" 122 " ret float %A\n" 123 "}\n"); 124 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_NAN, false}); 125 } 126 127 TEST_F(MatchSelectPatternTest, SwappedFMax3) { 128 parseAssembly( 129 "define float @test(float %a) {\n" 130 " %1 = fcmp ult float %a, 5.0\n" 131 " %A = select i1 %1, float 5.0, float %a\n" 132 " ret float %A\n" 133 "}\n"); 134 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, true}); 135 } 136 137 TEST_F(MatchSelectPatternTest, FastFMin) { 138 parseAssembly( 139 "define float @test(float %a) {\n" 140 " %1 = fcmp nnan olt 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_FMINNUM, SPNB_RETURNS_ANY, false}); 145 } 146 147 TEST_F(MatchSelectPatternTest, FMinConstantZero) { 148 parseAssembly( 149 "define float @test(float %a) {\n" 150 " %1 = fcmp ole float %a, 0.0\n" 151 " %A = select i1 %1, float %a, float 0.0\n" 152 " ret float %A\n" 153 "}\n"); 154 // This shouldn't be matched, as %a could be -0.0. 155 expectPattern({SPF_UNKNOWN, SPNB_NA, false}); 156 } 157 158 TEST_F(MatchSelectPatternTest, FMinConstantZeroNsz) { 159 parseAssembly( 160 "define float @test(float %a) {\n" 161 " %1 = fcmp nsz ole float %a, 0.0\n" 162 " %A = select i1 %1, float %a, float 0.0\n" 163 " ret float %A\n" 164 "}\n"); 165 // But this should be, because we've ignored signed zeroes. 166 expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, true}); 167 } 168 169 TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero1) { 170 parseAssembly( 171 "define float @test(float %a) {\n" 172 " %1 = fcmp olt float -0.0, %a\n" 173 " %A = select i1 %1, float 0.0, float %a\n" 174 " ret float %A\n" 175 "}\n"); 176 // The sign of zero doesn't matter in fcmp. 177 expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, true}); 178 } 179 180 TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero2) { 181 parseAssembly( 182 "define float @test(float %a) {\n" 183 " %1 = fcmp ogt float %a, -0.0\n" 184 " %A = select i1 %1, float 0.0, float %a\n" 185 " ret float %A\n" 186 "}\n"); 187 // The sign of zero doesn't matter in fcmp. 188 expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, false}); 189 } 190 191 TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero3) { 192 parseAssembly( 193 "define float @test(float %a) {\n" 194 " %1 = fcmp olt float 0.0, %a\n" 195 " %A = select i1 %1, float -0.0, float %a\n" 196 " ret float %A\n" 197 "}\n"); 198 // The sign of zero doesn't matter in fcmp. 199 expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, true}); 200 } 201 202 TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero4) { 203 parseAssembly( 204 "define float @test(float %a) {\n" 205 " %1 = fcmp ogt float %a, 0.0\n" 206 " %A = select i1 %1, float -0.0, float %a\n" 207 " ret float %A\n" 208 "}\n"); 209 // The sign of zero doesn't matter in fcmp. 210 expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, false}); 211 } 212 213 TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero5) { 214 parseAssembly( 215 "define float @test(float %a) {\n" 216 " %1 = fcmp ogt float -0.0, %a\n" 217 " %A = select i1 %1, float %a, float 0.0\n" 218 " ret float %A\n" 219 "}\n"); 220 // The sign of zero doesn't matter in fcmp. 221 expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, false}); 222 } 223 224 TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero6) { 225 parseAssembly( 226 "define float @test(float %a) {\n" 227 " %1 = fcmp olt float %a, -0.0\n" 228 " %A = select i1 %1, float %a, float 0.0\n" 229 " ret float %A\n" 230 "}\n"); 231 // The sign of zero doesn't matter in fcmp. 232 expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, true}); 233 } 234 235 TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero7) { 236 parseAssembly( 237 "define float @test(float %a) {\n" 238 " %1 = fcmp ogt float 0.0, %a\n" 239 " %A = select i1 %1, float %a, float -0.0\n" 240 " ret float %A\n" 241 "}\n"); 242 // The sign of zero doesn't matter in fcmp. 243 expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, false}); 244 } 245 246 TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero8) { 247 parseAssembly( 248 "define float @test(float %a) {\n" 249 " %1 = fcmp olt float %a, 0.0\n" 250 " %A = select i1 %1, float %a, float -0.0\n" 251 " ret float %A\n" 252 "}\n"); 253 // The sign of zero doesn't matter in fcmp. 254 expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, true}); 255 } 256 257 TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero1) { 258 parseAssembly( 259 "define float @test(float %a) {\n" 260 " %1 = fcmp ogt float -0.0, %a\n" 261 " %A = select i1 %1, float 0.0, float %a\n" 262 " ret float %A\n" 263 "}\n"); 264 // The sign of zero doesn't matter in fcmp. 265 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_NAN, true}); 266 } 267 268 TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero2) { 269 parseAssembly( 270 "define float @test(float %a) {\n" 271 " %1 = fcmp olt float %a, -0.0\n" 272 " %A = select i1 %1, float 0.0, float %a\n" 273 " ret float %A\n" 274 "}\n"); 275 // The sign of zero doesn't matter in fcmp. 276 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_NAN, false}); 277 } 278 279 TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero3) { 280 parseAssembly( 281 "define float @test(float %a) {\n" 282 " %1 = fcmp ogt float 0.0, %a\n" 283 " %A = select i1 %1, float -0.0, float %a\n" 284 " ret float %A\n" 285 "}\n"); 286 // The sign of zero doesn't matter in fcmp. 287 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_NAN, true}); 288 } 289 290 TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero4) { 291 parseAssembly( 292 "define float @test(float %a) {\n" 293 " %1 = fcmp olt float %a, 0.0\n" 294 " %A = select i1 %1, float -0.0, float %a\n" 295 " ret float %A\n" 296 "}\n"); 297 // The sign of zero doesn't matter in fcmp. 298 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_NAN, false}); 299 } 300 301 TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero5) { 302 parseAssembly( 303 "define float @test(float %a) {\n" 304 " %1 = fcmp olt float -0.0, %a\n" 305 " %A = select i1 %1, float %a, float 0.0\n" 306 " ret float %A\n" 307 "}\n"); 308 // The sign of zero doesn't matter in fcmp. 309 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, false}); 310 } 311 312 TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero6) { 313 parseAssembly( 314 "define float @test(float %a) {\n" 315 " %1 = fcmp ogt float %a, -0.0\n" 316 " %A = select i1 %1, float %a, float 0.0\n" 317 " ret float %A\n" 318 "}\n"); 319 // The sign of zero doesn't matter in fcmp. 320 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, true}); 321 } 322 323 TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero7) { 324 parseAssembly( 325 "define float @test(float %a) {\n" 326 " %1 = fcmp olt float 0.0, %a\n" 327 " %A = select i1 %1, float %a, float -0.0\n" 328 " ret float %A\n" 329 "}\n"); 330 // The sign of zero doesn't matter in fcmp. 331 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, false}); 332 } 333 334 TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero8) { 335 parseAssembly( 336 "define float @test(float %a) {\n" 337 " %1 = fcmp ogt float %a, 0.0\n" 338 " %A = select i1 %1, float %a, float -0.0\n" 339 " ret float %A\n" 340 "}\n"); 341 // The sign of zero doesn't matter in fcmp. 342 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, true}); 343 } 344 345 TEST_F(MatchSelectPatternTest, FMinMismatchConstantZeroVecUndef) { 346 parseAssembly( 347 "define <2 x float> @test(<2 x float> %a) {\n" 348 " %1 = fcmp ogt <2 x float> %a, <float -0.0, float -0.0>\n" 349 " %A = select <2 x i1> %1, <2 x float> <float undef, float 0.0>, <2 x float> %a\n" 350 " ret <2 x float> %A\n" 351 "}\n"); 352 // An undef in a vector constant can not be back-propagated for this analysis. 353 expectPattern({SPF_UNKNOWN, SPNB_NA, false}); 354 } 355 356 TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZeroVecUndef) { 357 parseAssembly( 358 "define <2 x float> @test(<2 x float> %a) {\n" 359 " %1 = fcmp ogt <2 x float> %a, zeroinitializer\n" 360 " %A = select <2 x i1> %1, <2 x float> %a, <2 x float> <float -0.0, float undef>\n" 361 " ret <2 x float> %A\n" 362 "}\n"); 363 // An undef in a vector constant can not be back-propagated for this analysis. 364 expectPattern({SPF_UNKNOWN, SPNB_NA, false}); 365 } 366 367 TEST_F(MatchSelectPatternTest, VectorFMinimum) { 368 parseAssembly( 369 "define <4 x float> @test(<4 x float> %a) {\n" 370 " %1 = fcmp ule <4 x float> %a, \n" 371 " <float 5.0, float 5.0, float 5.0, float 5.0>\n" 372 " %A = select <4 x i1> %1, <4 x float> %a,\n" 373 " <4 x float> <float 5.0, float 5.0, float 5.0, float 5.0>\n" 374 " ret <4 x float> %A\n" 375 "}\n"); 376 // Check that pattern matching works on vectors where each lane has the same 377 // unordered pattern. 378 expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, false}); 379 } 380 381 TEST_F(MatchSelectPatternTest, VectorFMinOtherOrdered) { 382 parseAssembly( 383 "define <4 x float> @test(<4 x float> %a) {\n" 384 " %1 = fcmp ole <4 x float> %a, \n" 385 " <float 5.0, float 5.0, float 5.0, float 5.0>\n" 386 " %A = select <4 x i1> %1, <4 x float> %a,\n" 387 " <4 x float> <float 5.0, float 5.0, float 5.0, float 5.0>\n" 388 " ret <4 x float> %A\n" 389 "}\n"); 390 // Check that pattern matching works on vectors where each lane has the same 391 // ordered pattern. 392 expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, true}); 393 } 394 395 TEST_F(MatchSelectPatternTest, VectorNotFMinimum) { 396 parseAssembly( 397 "define <4 x float> @test(<4 x float> %a) {\n" 398 " %1 = fcmp ule <4 x float> %a, \n" 399 " <float 5.0, float 0x7ff8000000000000, float 5.0, float 5.0>\n" 400 " %A = select <4 x i1> %1, <4 x float> %a,\n" 401 " <4 x float> <float 5.0, float 0x7ff8000000000000, float 5.0, float " 402 "5.0>\n" 403 " ret <4 x float> %A\n" 404 "}\n"); 405 // The lane that contains a NaN (0x7ff80...) behaves like a 406 // non-NaN-propagating min and the other lines behave like a NaN-propagating 407 // min, so check that neither is returned. 408 expectPattern({SPF_UNKNOWN, SPNB_NA, false}); 409 } 410 411 TEST_F(MatchSelectPatternTest, VectorNotFMinZero) { 412 parseAssembly( 413 "define <4 x float> @test(<4 x float> %a) {\n" 414 " %1 = fcmp ule <4 x float> %a, \n" 415 " <float 5.0, float -0.0, float 5.0, float 5.0>\n" 416 " %A = select <4 x i1> %1, <4 x float> %a,\n" 417 " <4 x float> <float 5.0, float 0.0, float 5.0, float 5.0>\n" 418 " ret <4 x float> %A\n" 419 "}\n"); 420 // Always selects the second lane of %a if it is positive or negative zero, so 421 // this is stricter than a min. 422 expectPattern({SPF_UNKNOWN, SPNB_NA, false}); 423 } 424 425 TEST_F(MatchSelectPatternTest, DoubleCastU) { 426 parseAssembly( 427 "define i32 @test(i8 %a, i8 %b) {\n" 428 " %1 = icmp ult i8 %a, %b\n" 429 " %2 = zext i8 %a to i32\n" 430 " %3 = zext i8 %b to i32\n" 431 " %A = select i1 %1, i32 %2, i32 %3\n" 432 " ret i32 %A\n" 433 "}\n"); 434 // We should be able to look through the situation where we cast both operands 435 // to the select. 436 expectPattern({SPF_UMIN, SPNB_NA, false}); 437 } 438 439 TEST_F(MatchSelectPatternTest, DoubleCastS) { 440 parseAssembly( 441 "define i32 @test(i8 %a, i8 %b) {\n" 442 " %1 = icmp slt i8 %a, %b\n" 443 " %2 = sext i8 %a to i32\n" 444 " %3 = sext i8 %b to i32\n" 445 " %A = select i1 %1, i32 %2, i32 %3\n" 446 " ret i32 %A\n" 447 "}\n"); 448 // We should be able to look through the situation where we cast both operands 449 // to the select. 450 expectPattern({SPF_SMIN, SPNB_NA, false}); 451 } 452 453 TEST_F(MatchSelectPatternTest, DoubleCastBad) { 454 parseAssembly( 455 "define i32 @test(i8 %a, i8 %b) {\n" 456 " %1 = icmp ult i8 %a, %b\n" 457 " %2 = zext i8 %a to i32\n" 458 " %3 = sext i8 %b to i32\n" 459 " %A = select i1 %1, i32 %2, i32 %3\n" 460 " ret i32 %A\n" 461 "}\n"); 462 // The cast types here aren't the same, so we cannot match an UMIN. 463 expectPattern({SPF_UNKNOWN, SPNB_NA, false}); 464 } 465 466 TEST_F(MatchSelectPatternTest, NotNotSMin) { 467 parseAssembly( 468 "define i8 @test(i8 %a, i8 %b) {\n" 469 " %cmp = icmp sgt i8 %a, %b\n" 470 " %an = xor i8 %a, -1\n" 471 " %bn = xor i8 %b, -1\n" 472 " %A = select i1 %cmp, i8 %an, i8 %bn\n" 473 " ret i8 %A\n" 474 "}\n"); 475 expectPattern({SPF_SMIN, SPNB_NA, false}); 476 } 477 478 TEST_F(MatchSelectPatternTest, NotNotSMinSwap) { 479 parseAssembly( 480 "define <2 x i8> @test(<2 x i8> %a, <2 x i8> %b) {\n" 481 " %cmp = icmp slt <2 x i8> %a, %b\n" 482 " %an = xor <2 x i8> %a, <i8 -1, i8-1>\n" 483 " %bn = xor <2 x i8> %b, <i8 -1, i8-1>\n" 484 " %A = select <2 x i1> %cmp, <2 x i8> %bn, <2 x i8> %an\n" 485 " ret <2 x i8> %A\n" 486 "}\n"); 487 expectPattern({SPF_SMIN, SPNB_NA, false}); 488 } 489 490 TEST_F(MatchSelectPatternTest, NotNotSMax) { 491 parseAssembly( 492 "define i8 @test(i8 %a, i8 %b) {\n" 493 " %cmp = icmp slt i8 %a, %b\n" 494 " %an = xor i8 %a, -1\n" 495 " %bn = xor i8 %b, -1\n" 496 " %A = select i1 %cmp, i8 %an, i8 %bn\n" 497 " ret i8 %A\n" 498 "}\n"); 499 expectPattern({SPF_SMAX, SPNB_NA, false}); 500 } 501 502 TEST_F(MatchSelectPatternTest, NotNotSMaxSwap) { 503 parseAssembly( 504 "define <2 x i8> @test(<2 x i8> %a, <2 x i8> %b) {\n" 505 " %cmp = icmp sgt <2 x i8> %a, %b\n" 506 " %an = xor <2 x i8> %a, <i8 -1, i8-1>\n" 507 " %bn = xor <2 x i8> %b, <i8 -1, i8-1>\n" 508 " %A = select <2 x i1> %cmp, <2 x i8> %bn, <2 x i8> %an\n" 509 " ret <2 x i8> %A\n" 510 "}\n"); 511 expectPattern({SPF_SMAX, SPNB_NA, false}); 512 } 513 514 TEST_F(MatchSelectPatternTest, NotNotUMin) { 515 parseAssembly( 516 "define <2 x i8> @test(<2 x i8> %a, <2 x i8> %b) {\n" 517 " %cmp = icmp ugt <2 x i8> %a, %b\n" 518 " %an = xor <2 x i8> %a, <i8 -1, i8-1>\n" 519 " %bn = xor <2 x i8> %b, <i8 -1, i8-1>\n" 520 " %A = select <2 x i1> %cmp, <2 x i8> %an, <2 x i8> %bn\n" 521 " ret <2 x i8> %A\n" 522 "}\n"); 523 expectPattern({SPF_UMIN, SPNB_NA, false}); 524 } 525 526 TEST_F(MatchSelectPatternTest, NotNotUMinSwap) { 527 parseAssembly( 528 "define i8 @test(i8 %a, i8 %b) {\n" 529 " %cmp = icmp ult i8 %a, %b\n" 530 " %an = xor i8 %a, -1\n" 531 " %bn = xor i8 %b, -1\n" 532 " %A = select i1 %cmp, i8 %bn, i8 %an\n" 533 " ret i8 %A\n" 534 "}\n"); 535 expectPattern({SPF_UMIN, SPNB_NA, false}); 536 } 537 538 TEST_F(MatchSelectPatternTest, NotNotUMax) { 539 parseAssembly( 540 "define <2 x i8> @test(<2 x i8> %a, <2 x i8> %b) {\n" 541 " %cmp = icmp ult <2 x i8> %a, %b\n" 542 " %an = xor <2 x i8> %a, <i8 -1, i8-1>\n" 543 " %bn = xor <2 x i8> %b, <i8 -1, i8-1>\n" 544 " %A = select <2 x i1> %cmp, <2 x i8> %an, <2 x i8> %bn\n" 545 " ret <2 x i8> %A\n" 546 "}\n"); 547 expectPattern({SPF_UMAX, SPNB_NA, false}); 548 } 549 550 TEST_F(MatchSelectPatternTest, NotNotUMaxSwap) { 551 parseAssembly( 552 "define i8 @test(i8 %a, i8 %b) {\n" 553 " %cmp = icmp ugt i8 %a, %b\n" 554 " %an = xor i8 %a, -1\n" 555 " %bn = xor i8 %b, -1\n" 556 " %A = select i1 %cmp, i8 %bn, i8 %an\n" 557 " ret i8 %A\n" 558 "}\n"); 559 expectPattern({SPF_UMAX, SPNB_NA, false}); 560 } 561 562 TEST_F(MatchSelectPatternTest, NotNotEq) { 563 parseAssembly( 564 "define i8 @test(i8 %a, i8 %b) {\n" 565 " %cmp = icmp eq i8 %a, %b\n" 566 " %an = xor i8 %a, -1\n" 567 " %bn = xor i8 %b, -1\n" 568 " %A = select i1 %cmp, i8 %bn, i8 %an\n" 569 " ret i8 %A\n" 570 "}\n"); 571 expectPattern({SPF_UNKNOWN, SPNB_NA, false}); 572 } 573 574 TEST_F(MatchSelectPatternTest, NotNotNe) { 575 parseAssembly( 576 "define i8 @test(i8 %a, i8 %b) {\n" 577 " %cmp = icmp ne i8 %a, %b\n" 578 " %an = xor i8 %a, -1\n" 579 " %bn = xor i8 %b, -1\n" 580 " %A = select i1 %cmp, i8 %bn, i8 %an\n" 581 " ret i8 %A\n" 582 "}\n"); 583 expectPattern({SPF_UNKNOWN, SPNB_NA, false}); 584 } 585 586 TEST(ValueTracking, GuaranteedToTransferExecutionToSuccessor) { 587 StringRef Assembly = 588 "declare void @nounwind_readonly(i32*) nounwind readonly " 589 "declare void @nounwind_argmemonly(i32*) nounwind argmemonly " 590 "declare void @throws_but_readonly(i32*) readonly " 591 "declare void @throws_but_argmemonly(i32*) argmemonly " 592 "declare void @nounwind_willreturn(i32*) nounwind willreturn" 593 " " 594 "declare void @unknown(i32*) " 595 " " 596 "define void @f(i32* %p) { " 597 " call void @nounwind_readonly(i32* %p) " 598 " call void @nounwind_argmemonly(i32* %p) " 599 " call void @throws_but_readonly(i32* %p) " 600 " call void @throws_but_argmemonly(i32* %p) " 601 " call void @unknown(i32* %p) nounwind readonly " 602 " call void @unknown(i32* %p) nounwind argmemonly " 603 " call void @unknown(i32* %p) readonly " 604 " call void @unknown(i32* %p) argmemonly " 605 " call void @nounwind_willreturn(i32* %p)" 606 " ret void " 607 "} "; 608 609 LLVMContext Context; 610 SMDiagnostic Error; 611 auto M = parseAssemblyString(Assembly, Error, Context); 612 assert(M && "Bad assembly?"); 613 614 auto *F = M->getFunction("f"); 615 assert(F && "Bad assembly?"); 616 617 auto &BB = F->getEntryBlock(); 618 bool ExpectedAnswers[] = { 619 true, // call void @nounwind_readonly(i32* %p) 620 true, // call void @nounwind_argmemonly(i32* %p) 621 false, // call void @throws_but_readonly(i32* %p) 622 false, // call void @throws_but_argmemonly(i32* %p) 623 true, // call void @unknown(i32* %p) nounwind readonly 624 true, // call void @unknown(i32* %p) nounwind argmemonly 625 false, // call void @unknown(i32* %p) readonly 626 false, // call void @unknown(i32* %p) argmemonly 627 true, // call void @nounwind_willreturn(i32* %p) 628 false, // ret void 629 }; 630 631 int Index = 0; 632 for (auto &I : BB) { 633 EXPECT_EQ(isGuaranteedToTransferExecutionToSuccessor(&I), 634 ExpectedAnswers[Index]) 635 << "Incorrect answer at instruction " << Index << " = " << I; 636 Index++; 637 } 638 } 639 640 TEST_F(ValueTrackingTest, ComputeNumSignBits_PR32045) { 641 parseAssembly( 642 "define i32 @test(i32 %a) {\n" 643 " %A = ashr i32 %a, -1\n" 644 " ret i32 %A\n" 645 "}\n"); 646 EXPECT_EQ(ComputeNumSignBits(A, M->getDataLayout()), 1u); 647 } 648 649 // No guarantees for canonical IR in this analysis, so this just bails out. 650 TEST_F(ValueTrackingTest, ComputeNumSignBits_Shuffle) { 651 parseAssembly( 652 "define <2 x i32> @test() {\n" 653 " %A = shufflevector <2 x i32> undef, <2 x i32> undef, <2 x i32> <i32 0, i32 0>\n" 654 " ret <2 x i32> %A\n" 655 "}\n"); 656 EXPECT_EQ(ComputeNumSignBits(A, M->getDataLayout()), 1u); 657 } 658 659 // No guarantees for canonical IR in this analysis, so a shuffle element that 660 // references an undef value means this can't return any extra information. 661 TEST_F(ValueTrackingTest, ComputeNumSignBits_Shuffle2) { 662 parseAssembly( 663 "define <2 x i32> @test(<2 x i1> %x) {\n" 664 " %sext = sext <2 x i1> %x to <2 x i32>\n" 665 " %A = shufflevector <2 x i32> %sext, <2 x i32> undef, <2 x i32> <i32 0, i32 2>\n" 666 " ret <2 x i32> %A\n" 667 "}\n"); 668 EXPECT_EQ(ComputeNumSignBits(A, M->getDataLayout()), 1u); 669 } 670 671 TEST(ValueTracking, canCreatePoison) { 672 std::string AsmHead = 673 "declare i32 @g(i32)\n" 674 "define void @f(i32 %x, i32 %y, float %fx, float %fy, i1 %cond, " 675 "<4 x i32> %vx, <4 x i32> %vx2, <vscale x 4 x i32> %svx, i8* %p) {\n"; 676 std::string AsmTail = " ret void\n}"; 677 // (can create poison?, IR instruction) 678 SmallVector<std::pair<bool, std::string>, 32> Data = { 679 {false, "add i32 %x, %y"}, 680 {true, "add nsw nuw i32 %x, %y"}, 681 {true, "shl i32 %x, %y"}, 682 {true, "shl <4 x i32> %vx, %vx2"}, 683 {true, "shl nsw i32 %x, %y"}, 684 {true, "shl nsw <4 x i32> %vx, <i32 0, i32 1, i32 2, i32 3>"}, 685 {false, "shl i32 %x, 31"}, 686 {true, "shl i32 %x, 32"}, 687 {false, "shl <4 x i32> %vx, <i32 0, i32 1, i32 2, i32 3>"}, 688 {true, "shl <4 x i32> %vx, <i32 0, i32 1, i32 2, i32 32>"}, 689 {true, "ashr i32 %x, %y"}, 690 {true, "ashr exact i32 %x, %y"}, 691 {false, "ashr i32 %x, 31"}, 692 {true, "ashr exact i32 %x, 31"}, 693 {false, "ashr <4 x i32> %vx, <i32 0, i32 1, i32 2, i32 3>"}, 694 {true, "ashr <4 x i32> %vx, <i32 0, i32 1, i32 2, i32 32>"}, 695 {true, "ashr exact <4 x i32> %vx, <i32 0, i32 1, i32 2, i32 3>"}, 696 {true, "lshr i32 %x, %y"}, 697 {true, "lshr exact i32 %x, 31"}, 698 {false, "udiv i32 %x, %y"}, 699 {true, "udiv exact i32 %x, %y"}, 700 {false, "getelementptr i8, i8* %p, i32 %x"}, 701 {true, "getelementptr inbounds i8, i8* %p, i32 %x"}, 702 {true, "fneg nnan float %fx"}, 703 {false, "fneg float %fx"}, 704 {false, "fadd float %fx, %fy"}, 705 {true, "fadd nnan float %fx, %fy"}, 706 {false, "urem i32 %x, %y"}, 707 {true, "fptoui float %fx to i32"}, 708 {true, "fptosi float %fx to i32"}, 709 {false, "bitcast float %fx to i32"}, 710 {false, "select i1 %cond, i32 %x, i32 %y"}, 711 {true, "select nnan i1 %cond, float %fx, float %fy"}, 712 {true, "extractelement <4 x i32> %vx, i32 %x"}, 713 {false, "extractelement <4 x i32> %vx, i32 3"}, 714 {true, "extractelement <vscale x 4 x i32> %svx, i32 4"}, 715 {true, "insertelement <4 x i32> %vx, i32 %x, i32 %y"}, 716 {false, "insertelement <4 x i32> %vx, i32 %x, i32 3"}, 717 {true, "insertelement <vscale x 4 x i32> %svx, i32 %x, i32 4"}, 718 {false, "freeze i32 %x"}, 719 {true, "call i32 @g(i32 %x)"}, 720 {true, "fcmp nnan oeq float %fx, %fy"}, 721 {false, "fcmp oeq float %fx, %fy"}}; 722 723 std::string AssemblyStr = AsmHead; 724 for (auto &Itm : Data) 725 AssemblyStr += Itm.second + "\n"; 726 AssemblyStr += AsmTail; 727 728 LLVMContext Context; 729 SMDiagnostic Error; 730 auto M = parseAssemblyString(AssemblyStr, Error, Context); 731 assert(M && "Bad assembly?"); 732 733 auto *F = M->getFunction("f"); 734 assert(F && "Bad assembly?"); 735 736 auto &BB = F->getEntryBlock(); 737 738 int Index = 0; 739 for (auto &I : BB) { 740 if (isa<ReturnInst>(&I)) 741 break; 742 EXPECT_EQ(canCreatePoison(&I), Data[Index].first) 743 << "Incorrect answer at instruction " << Index << " = " << I; 744 Index++; 745 } 746 } 747 748 TEST_F(ComputeKnownBitsTest, ComputeKnownBits) { 749 parseAssembly( 750 "define i32 @test(i32 %a, i32 %b) {\n" 751 " %ash = mul i32 %a, 8\n" 752 " %aad = add i32 %ash, 7\n" 753 " %aan = and i32 %aad, 4095\n" 754 " %bsh = shl i32 %b, 4\n" 755 " %bad = or i32 %bsh, 6\n" 756 " %ban = and i32 %bad, 4095\n" 757 " %A = mul i32 %aan, %ban\n" 758 " ret i32 %A\n" 759 "}\n"); 760 expectKnownBits(/*zero*/ 4278190085u, /*one*/ 10u); 761 } 762 763 TEST_F(ComputeKnownBitsTest, ComputeKnownMulBits) { 764 parseAssembly( 765 "define i32 @test(i32 %a, i32 %b) {\n" 766 " %aa = shl i32 %a, 5\n" 767 " %bb = shl i32 %b, 5\n" 768 " %aaa = or i32 %aa, 24\n" 769 " %bbb = or i32 %bb, 28\n" 770 " %A = mul i32 %aaa, %bbb\n" 771 " ret i32 %A\n" 772 "}\n"); 773 expectKnownBits(/*zero*/ 95u, /*one*/ 32u); 774 } 775 776 TEST_F(ComputeKnownBitsTest, ComputeKnownFshl) { 777 // fshl(....1111....0000, 00..1111........, 6) 778 // = 11....000000..11 779 parseAssembly( 780 "define i16 @test(i16 %a, i16 %b) {\n" 781 " %aa = shl i16 %a, 4\n" 782 " %bb = lshr i16 %b, 2\n" 783 " %aaa = or i16 %aa, 3840\n" 784 " %bbb = or i16 %bb, 3840\n" 785 " %A = call i16 @llvm.fshl.i16(i16 %aaa, i16 %bbb, i16 6)\n" 786 " ret i16 %A\n" 787 "}\n" 788 "declare i16 @llvm.fshl.i16(i16, i16, i16)\n"); 789 expectKnownBits(/*zero*/ 1008u, /*one*/ 49155u); 790 } 791 792 TEST_F(ComputeKnownBitsTest, ComputeKnownFshr) { 793 // fshr(....1111....0000, 00..1111........, 26) 794 // = 11....000000..11 795 parseAssembly( 796 "define i16 @test(i16 %a, i16 %b) {\n" 797 " %aa = shl i16 %a, 4\n" 798 " %bb = lshr i16 %b, 2\n" 799 " %aaa = or i16 %aa, 3840\n" 800 " %bbb = or i16 %bb, 3840\n" 801 " %A = call i16 @llvm.fshr.i16(i16 %aaa, i16 %bbb, i16 26)\n" 802 " ret i16 %A\n" 803 "}\n" 804 "declare i16 @llvm.fshr.i16(i16, i16, i16)\n"); 805 expectKnownBits(/*zero*/ 1008u, /*one*/ 49155u); 806 } 807 808 TEST_F(ComputeKnownBitsTest, ComputeKnownFshlZero) { 809 // fshl(....1111....0000, 00..1111........, 0) 810 // = ....1111....0000 811 parseAssembly( 812 "define i16 @test(i16 %a, i16 %b) {\n" 813 " %aa = shl i16 %a, 4\n" 814 " %bb = lshr i16 %b, 2\n" 815 " %aaa = or i16 %aa, 3840\n" 816 " %bbb = or i16 %bb, 3840\n" 817 " %A = call i16 @llvm.fshl.i16(i16 %aaa, i16 %bbb, i16 0)\n" 818 " ret i16 %A\n" 819 "}\n" 820 "declare i16 @llvm.fshl.i16(i16, i16, i16)\n"); 821 expectKnownBits(/*zero*/ 15u, /*one*/ 3840u); 822 } 823 824 TEST_F(ComputeKnownBitsTest, ComputeKnownUAddSatLeadingOnes) { 825 // uadd.sat(1111...1, ........) 826 // = 1111.... 827 parseAssembly( 828 "define i8 @test(i8 %a, i8 %b) {\n" 829 " %aa = or i8 %a, 241\n" 830 " %A = call i8 @llvm.uadd.sat.i8(i8 %aa, i8 %b)\n" 831 " ret i8 %A\n" 832 "}\n" 833 "declare i8 @llvm.uadd.sat.i8(i8, i8)\n"); 834 expectKnownBits(/*zero*/ 0u, /*one*/ 240u); 835 } 836 837 TEST_F(ComputeKnownBitsTest, ComputeKnownUAddSatOnesPreserved) { 838 // uadd.sat(00...011, .1...110) 839 // = .......1 840 parseAssembly( 841 "define i8 @test(i8 %a, i8 %b) {\n" 842 " %aa = or i8 %a, 3\n" 843 " %aaa = and i8 %aa, 59\n" 844 " %bb = or i8 %b, 70\n" 845 " %bbb = and i8 %bb, 254\n" 846 " %A = call i8 @llvm.uadd.sat.i8(i8 %aaa, i8 %bbb)\n" 847 " ret i8 %A\n" 848 "}\n" 849 "declare i8 @llvm.uadd.sat.i8(i8, i8)\n"); 850 expectKnownBits(/*zero*/ 0u, /*one*/ 1u); 851 } 852 853 TEST_F(ComputeKnownBitsTest, ComputeKnownUSubSatLHSLeadingZeros) { 854 // usub.sat(0000...0, ........) 855 // = 0000.... 856 parseAssembly( 857 "define i8 @test(i8 %a, i8 %b) {\n" 858 " %aa = and i8 %a, 14\n" 859 " %A = call i8 @llvm.usub.sat.i8(i8 %aa, i8 %b)\n" 860 " ret i8 %A\n" 861 "}\n" 862 "declare i8 @llvm.usub.sat.i8(i8, i8)\n"); 863 expectKnownBits(/*zero*/ 240u, /*one*/ 0u); 864 } 865 866 TEST_F(ComputeKnownBitsTest, ComputeKnownUSubSatRHSLeadingOnes) { 867 // usub.sat(........, 1111...1) 868 // = 0000.... 869 parseAssembly( 870 "define i8 @test(i8 %a, i8 %b) {\n" 871 " %bb = or i8 %a, 241\n" 872 " %A = call i8 @llvm.usub.sat.i8(i8 %a, i8 %bb)\n" 873 " ret i8 %A\n" 874 "}\n" 875 "declare i8 @llvm.usub.sat.i8(i8, i8)\n"); 876 expectKnownBits(/*zero*/ 240u, /*one*/ 0u); 877 } 878 879 TEST_F(ComputeKnownBitsTest, ComputeKnownUSubSatZerosPreserved) { 880 // usub.sat(11...011, .1...110) 881 // = ......0. 882 parseAssembly( 883 "define i8 @test(i8 %a, i8 %b) {\n" 884 " %aa = or i8 %a, 195\n" 885 " %aaa = and i8 %aa, 251\n" 886 " %bb = or i8 %b, 70\n" 887 " %bbb = and i8 %bb, 254\n" 888 " %A = call i8 @llvm.usub.sat.i8(i8 %aaa, i8 %bbb)\n" 889 " ret i8 %A\n" 890 "}\n" 891 "declare i8 @llvm.usub.sat.i8(i8, i8)\n"); 892 expectKnownBits(/*zero*/ 2u, /*one*/ 0u); 893 } 894 895 class IsBytewiseValueTest : public ValueTrackingTest, 896 public ::testing::WithParamInterface< 897 std::pair<const char *, const char *>> { 898 protected: 899 }; 900 901 const std::pair<const char *, const char *> IsBytewiseValueTests[] = { 902 { 903 "i8 0", 904 "i48* null", 905 }, 906 { 907 "i8 undef", 908 "i48* undef", 909 }, 910 { 911 "i8 0", 912 "i8 zeroinitializer", 913 }, 914 { 915 "i8 0", 916 "i8 0", 917 }, 918 { 919 "i8 -86", 920 "i8 -86", 921 }, 922 { 923 "i8 -1", 924 "i8 -1", 925 }, 926 { 927 "i8 undef", 928 "i16 undef", 929 }, 930 { 931 "i8 0", 932 "i16 0", 933 }, 934 { 935 "", 936 "i16 7", 937 }, 938 { 939 "i8 -86", 940 "i16 -21846", 941 }, 942 { 943 "i8 -1", 944 "i16 -1", 945 }, 946 { 947 "i8 0", 948 "i48 0", 949 }, 950 { 951 "i8 -1", 952 "i48 -1", 953 }, 954 { 955 "i8 0", 956 "i49 0", 957 }, 958 { 959 "", 960 "i49 -1", 961 }, 962 { 963 "i8 0", 964 "half 0xH0000", 965 }, 966 { 967 "i8 -85", 968 "half 0xHABAB", 969 }, 970 { 971 "i8 0", 972 "float 0.0", 973 }, 974 { 975 "i8 -1", 976 "float 0xFFFFFFFFE0000000", 977 }, 978 { 979 "i8 0", 980 "double 0.0", 981 }, 982 { 983 "i8 -15", 984 "double 0xF1F1F1F1F1F1F1F1", 985 }, 986 { 987 "i8 undef", 988 "i16* undef", 989 }, 990 { 991 "i8 0", 992 "i16* inttoptr (i64 0 to i16*)", 993 }, 994 { 995 "i8 -1", 996 "i16* inttoptr (i64 -1 to i16*)", 997 }, 998 { 999 "i8 -86", 1000 "i16* inttoptr (i64 -6148914691236517206 to i16*)", 1001 }, 1002 { 1003 "", 1004 "i16* inttoptr (i48 -1 to i16*)", 1005 }, 1006 { 1007 "i8 -1", 1008 "i16* inttoptr (i96 -1 to i16*)", 1009 }, 1010 { 1011 "i8 undef", 1012 "[0 x i8] zeroinitializer", 1013 }, 1014 { 1015 "i8 undef", 1016 "[0 x i8] undef", 1017 }, 1018 { 1019 "i8 undef", 1020 "[5 x [0 x i8]] zeroinitializer", 1021 }, 1022 { 1023 "i8 undef", 1024 "[5 x [0 x i8]] undef", 1025 }, 1026 { 1027 "i8 0", 1028 "[6 x i8] zeroinitializer", 1029 }, 1030 { 1031 "i8 undef", 1032 "[6 x i8] undef", 1033 }, 1034 { 1035 "i8 1", 1036 "[5 x i8] [i8 1, i8 1, i8 1, i8 1, i8 1]", 1037 }, 1038 { 1039 "", 1040 "[5 x i64] [i64 1, i64 1, i64 1, i64 1, i64 1]", 1041 }, 1042 { 1043 "i8 -1", 1044 "[5 x i64] [i64 -1, i64 -1, i64 -1, i64 -1, i64 -1]", 1045 }, 1046 { 1047 "", 1048 "[4 x i8] [i8 1, i8 2, i8 1, i8 1]", 1049 }, 1050 { 1051 "i8 1", 1052 "[4 x i8] [i8 1, i8 undef, i8 1, i8 1]", 1053 }, 1054 { 1055 "i8 0", 1056 "<6 x i8> zeroinitializer", 1057 }, 1058 { 1059 "i8 undef", 1060 "<6 x i8> undef", 1061 }, 1062 { 1063 "i8 1", 1064 "<5 x i8> <i8 1, i8 1, i8 1, i8 1, i8 1>", 1065 }, 1066 { 1067 "", 1068 "<5 x i64> <i64 1, i64 1, i64 1, i64 1, i64 1>", 1069 }, 1070 { 1071 "i8 -1", 1072 "<5 x i64> <i64 -1, i64 -1, i64 -1, i64 -1, i64 -1>", 1073 }, 1074 { 1075 "", 1076 "<4 x i8> <i8 1, i8 1, i8 2, i8 1>", 1077 }, 1078 { 1079 "i8 5", 1080 "<2 x i8> < i8 5, i8 undef >", 1081 }, 1082 { 1083 "i8 0", 1084 "[2 x [2 x i16]] zeroinitializer", 1085 }, 1086 { 1087 "i8 undef", 1088 "[2 x [2 x i16]] undef", 1089 }, 1090 { 1091 "i8 -86", 1092 "[2 x [2 x i16]] [[2 x i16] [i16 -21846, i16 -21846], " 1093 "[2 x i16] [i16 -21846, i16 -21846]]", 1094 }, 1095 { 1096 "", 1097 "[2 x [2 x i16]] [[2 x i16] [i16 -21846, i16 -21846], " 1098 "[2 x i16] [i16 -21836, i16 -21846]]", 1099 }, 1100 { 1101 "i8 undef", 1102 "{ } zeroinitializer", 1103 }, 1104 { 1105 "i8 undef", 1106 "{ } undef", 1107 }, 1108 { 1109 "i8 undef", 1110 "{ {}, {} } zeroinitializer", 1111 }, 1112 { 1113 "i8 undef", 1114 "{ {}, {} } undef", 1115 }, 1116 { 1117 "i8 0", 1118 "{i8, i64, i16*} zeroinitializer", 1119 }, 1120 { 1121 "i8 undef", 1122 "{i8, i64, i16*} undef", 1123 }, 1124 { 1125 "i8 -86", 1126 "{i8, i64, i16*} {i8 -86, i64 -6148914691236517206, i16* undef}", 1127 }, 1128 { 1129 "", 1130 "{i8, i64, i16*} {i8 86, i64 -6148914691236517206, i16* undef}", 1131 }, 1132 }; 1133 1134 INSTANTIATE_TEST_CASE_P(IsBytewiseValueParamTests, IsBytewiseValueTest, 1135 ::testing::ValuesIn(IsBytewiseValueTests),); 1136 1137 TEST_P(IsBytewiseValueTest, IsBytewiseValue) { 1138 auto M = parseModule(std::string("@test = global ") + GetParam().second); 1139 GlobalVariable *GV = dyn_cast<GlobalVariable>(M->getNamedValue("test")); 1140 Value *Actual = isBytewiseValue(GV->getInitializer(), M->getDataLayout()); 1141 std::string Buff; 1142 raw_string_ostream S(Buff); 1143 if (Actual) 1144 S << *Actual; 1145 EXPECT_EQ(GetParam().first, S.str()); 1146 } 1147