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