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_F(ComputeKnownBitsTest, ComputeKnownBits) { 671 parseAssembly( 672 "define i32 @test(i32 %a, i32 %b) {\n" 673 " %ash = mul i32 %a, 8\n" 674 " %aad = add i32 %ash, 7\n" 675 " %aan = and i32 %aad, 4095\n" 676 " %bsh = shl i32 %b, 4\n" 677 " %bad = or i32 %bsh, 6\n" 678 " %ban = and i32 %bad, 4095\n" 679 " %A = mul i32 %aan, %ban\n" 680 " ret i32 %A\n" 681 "}\n"); 682 expectKnownBits(/*zero*/ 4278190085u, /*one*/ 10u); 683 } 684 685 TEST_F(ComputeKnownBitsTest, ComputeKnownMulBits) { 686 parseAssembly( 687 "define i32 @test(i32 %a, i32 %b) {\n" 688 " %aa = shl i32 %a, 5\n" 689 " %bb = shl i32 %b, 5\n" 690 " %aaa = or i32 %aa, 24\n" 691 " %bbb = or i32 %bb, 28\n" 692 " %A = mul i32 %aaa, %bbb\n" 693 " ret i32 %A\n" 694 "}\n"); 695 expectKnownBits(/*zero*/ 95u, /*one*/ 32u); 696 } 697 698 TEST_F(ComputeKnownBitsTest, ComputeKnownFshl) { 699 // fshl(....1111....0000, 00..1111........, 6) 700 // = 11....000000..11 701 parseAssembly( 702 "define i16 @test(i16 %a, i16 %b) {\n" 703 " %aa = shl i16 %a, 4\n" 704 " %bb = lshr i16 %b, 2\n" 705 " %aaa = or i16 %aa, 3840\n" 706 " %bbb = or i16 %bb, 3840\n" 707 " %A = call i16 @llvm.fshl.i16(i16 %aaa, i16 %bbb, i16 6)\n" 708 " ret i16 %A\n" 709 "}\n" 710 "declare i16 @llvm.fshl.i16(i16, i16, i16)\n"); 711 expectKnownBits(/*zero*/ 1008u, /*one*/ 49155u); 712 } 713 714 TEST_F(ComputeKnownBitsTest, ComputeKnownFshr) { 715 // fshr(....1111....0000, 00..1111........, 26) 716 // = 11....000000..11 717 parseAssembly( 718 "define i16 @test(i16 %a, i16 %b) {\n" 719 " %aa = shl i16 %a, 4\n" 720 " %bb = lshr i16 %b, 2\n" 721 " %aaa = or i16 %aa, 3840\n" 722 " %bbb = or i16 %bb, 3840\n" 723 " %A = call i16 @llvm.fshr.i16(i16 %aaa, i16 %bbb, i16 26)\n" 724 " ret i16 %A\n" 725 "}\n" 726 "declare i16 @llvm.fshr.i16(i16, i16, i16)\n"); 727 expectKnownBits(/*zero*/ 1008u, /*one*/ 49155u); 728 } 729 730 TEST_F(ComputeKnownBitsTest, ComputeKnownFshlZero) { 731 // fshl(....1111....0000, 00..1111........, 0) 732 // = ....1111....0000 733 parseAssembly( 734 "define i16 @test(i16 %a, i16 %b) {\n" 735 " %aa = shl i16 %a, 4\n" 736 " %bb = lshr i16 %b, 2\n" 737 " %aaa = or i16 %aa, 3840\n" 738 " %bbb = or i16 %bb, 3840\n" 739 " %A = call i16 @llvm.fshl.i16(i16 %aaa, i16 %bbb, i16 0)\n" 740 " ret i16 %A\n" 741 "}\n" 742 "declare i16 @llvm.fshl.i16(i16, i16, i16)\n"); 743 expectKnownBits(/*zero*/ 15u, /*one*/ 3840u); 744 } 745 746 TEST_F(ComputeKnownBitsTest, ComputeKnownUAddSatLeadingOnes) { 747 // uadd.sat(1111...1, ........) 748 // = 1111.... 749 parseAssembly( 750 "define i8 @test(i8 %a, i8 %b) {\n" 751 " %aa = or i8 %a, 241\n" 752 " %A = call i8 @llvm.uadd.sat.i8(i8 %aa, i8 %b)\n" 753 " ret i8 %A\n" 754 "}\n" 755 "declare i8 @llvm.uadd.sat.i8(i8, i8)\n"); 756 expectKnownBits(/*zero*/ 0u, /*one*/ 240u); 757 } 758 759 TEST_F(ComputeKnownBitsTest, ComputeKnownUAddSatOnesPreserved) { 760 // uadd.sat(00...011, .1...110) 761 // = .......1 762 parseAssembly( 763 "define i8 @test(i8 %a, i8 %b) {\n" 764 " %aa = or i8 %a, 3\n" 765 " %aaa = and i8 %aa, 59\n" 766 " %bb = or i8 %b, 70\n" 767 " %bbb = and i8 %bb, 254\n" 768 " %A = call i8 @llvm.uadd.sat.i8(i8 %aaa, i8 %bbb)\n" 769 " ret i8 %A\n" 770 "}\n" 771 "declare i8 @llvm.uadd.sat.i8(i8, i8)\n"); 772 expectKnownBits(/*zero*/ 0u, /*one*/ 1u); 773 } 774 775 TEST_F(ComputeKnownBitsTest, ComputeKnownUSubSatLHSLeadingZeros) { 776 // usub.sat(0000...0, ........) 777 // = 0000.... 778 parseAssembly( 779 "define i8 @test(i8 %a, i8 %b) {\n" 780 " %aa = and i8 %a, 14\n" 781 " %A = call i8 @llvm.usub.sat.i8(i8 %aa, i8 %b)\n" 782 " ret i8 %A\n" 783 "}\n" 784 "declare i8 @llvm.usub.sat.i8(i8, i8)\n"); 785 expectKnownBits(/*zero*/ 240u, /*one*/ 0u); 786 } 787 788 TEST_F(ComputeKnownBitsTest, ComputeKnownUSubSatRHSLeadingOnes) { 789 // usub.sat(........, 1111...1) 790 // = 0000.... 791 parseAssembly( 792 "define i8 @test(i8 %a, i8 %b) {\n" 793 " %bb = or i8 %a, 241\n" 794 " %A = call i8 @llvm.usub.sat.i8(i8 %a, i8 %bb)\n" 795 " ret i8 %A\n" 796 "}\n" 797 "declare i8 @llvm.usub.sat.i8(i8, i8)\n"); 798 expectKnownBits(/*zero*/ 240u, /*one*/ 0u); 799 } 800 801 TEST_F(ComputeKnownBitsTest, ComputeKnownUSubSatZerosPreserved) { 802 // usub.sat(11...011, .1...110) 803 // = ......0. 804 parseAssembly( 805 "define i8 @test(i8 %a, i8 %b) {\n" 806 " %aa = or i8 %a, 195\n" 807 " %aaa = and i8 %aa, 251\n" 808 " %bb = or i8 %b, 70\n" 809 " %bbb = and i8 %bb, 254\n" 810 " %A = call i8 @llvm.usub.sat.i8(i8 %aaa, i8 %bbb)\n" 811 " ret i8 %A\n" 812 "}\n" 813 "declare i8 @llvm.usub.sat.i8(i8, i8)\n"); 814 expectKnownBits(/*zero*/ 2u, /*one*/ 0u); 815 } 816 817 class IsBytewiseValueTest : public ValueTrackingTest, 818 public ::testing::WithParamInterface< 819 std::pair<const char *, const char *>> { 820 protected: 821 }; 822 823 const std::pair<const char *, const char *> IsBytewiseValueTests[] = { 824 { 825 "i8 0", 826 "i48* null", 827 }, 828 { 829 "i8 undef", 830 "i48* undef", 831 }, 832 { 833 "i8 0", 834 "i8 zeroinitializer", 835 }, 836 { 837 "i8 0", 838 "i8 0", 839 }, 840 { 841 "i8 -86", 842 "i8 -86", 843 }, 844 { 845 "i8 -1", 846 "i8 -1", 847 }, 848 { 849 "i8 undef", 850 "i16 undef", 851 }, 852 { 853 "i8 0", 854 "i16 0", 855 }, 856 { 857 "", 858 "i16 7", 859 }, 860 { 861 "i8 -86", 862 "i16 -21846", 863 }, 864 { 865 "i8 -1", 866 "i16 -1", 867 }, 868 { 869 "i8 0", 870 "i48 0", 871 }, 872 { 873 "i8 -1", 874 "i48 -1", 875 }, 876 { 877 "i8 0", 878 "i49 0", 879 }, 880 { 881 "", 882 "i49 -1", 883 }, 884 { 885 "i8 0", 886 "half 0xH0000", 887 }, 888 { 889 "i8 -85", 890 "half 0xHABAB", 891 }, 892 { 893 "i8 0", 894 "float 0.0", 895 }, 896 { 897 "i8 -1", 898 "float 0xFFFFFFFFE0000000", 899 }, 900 { 901 "i8 0", 902 "double 0.0", 903 }, 904 { 905 "i8 -15", 906 "double 0xF1F1F1F1F1F1F1F1", 907 }, 908 { 909 "i8 undef", 910 "i16* undef", 911 }, 912 { 913 "i8 0", 914 "i16* inttoptr (i64 0 to i16*)", 915 }, 916 { 917 "i8 -1", 918 "i16* inttoptr (i64 -1 to i16*)", 919 }, 920 { 921 "i8 -86", 922 "i16* inttoptr (i64 -6148914691236517206 to i16*)", 923 }, 924 { 925 "", 926 "i16* inttoptr (i48 -1 to i16*)", 927 }, 928 { 929 "i8 -1", 930 "i16* inttoptr (i96 -1 to i16*)", 931 }, 932 { 933 "i8 undef", 934 "[0 x i8] zeroinitializer", 935 }, 936 { 937 "i8 undef", 938 "[0 x i8] undef", 939 }, 940 { 941 "i8 undef", 942 "[5 x [0 x i8]] zeroinitializer", 943 }, 944 { 945 "i8 undef", 946 "[5 x [0 x i8]] undef", 947 }, 948 { 949 "i8 0", 950 "[6 x i8] zeroinitializer", 951 }, 952 { 953 "i8 undef", 954 "[6 x i8] undef", 955 }, 956 { 957 "i8 1", 958 "[5 x i8] [i8 1, i8 1, i8 1, i8 1, i8 1]", 959 }, 960 { 961 "", 962 "[5 x i64] [i64 1, i64 1, i64 1, i64 1, i64 1]", 963 }, 964 { 965 "i8 -1", 966 "[5 x i64] [i64 -1, i64 -1, i64 -1, i64 -1, i64 -1]", 967 }, 968 { 969 "", 970 "[4 x i8] [i8 1, i8 2, i8 1, i8 1]", 971 }, 972 { 973 "i8 1", 974 "[4 x i8] [i8 1, i8 undef, i8 1, i8 1]", 975 }, 976 { 977 "i8 0", 978 "<6 x i8> zeroinitializer", 979 }, 980 { 981 "i8 undef", 982 "<6 x i8> undef", 983 }, 984 { 985 "i8 1", 986 "<5 x i8> <i8 1, i8 1, i8 1, i8 1, i8 1>", 987 }, 988 { 989 "", 990 "<5 x i64> <i64 1, i64 1, i64 1, i64 1, i64 1>", 991 }, 992 { 993 "i8 -1", 994 "<5 x i64> <i64 -1, i64 -1, i64 -1, i64 -1, i64 -1>", 995 }, 996 { 997 "", 998 "<4 x i8> <i8 1, i8 1, i8 2, i8 1>", 999 }, 1000 { 1001 "i8 5", 1002 "<2 x i8> < i8 5, i8 undef >", 1003 }, 1004 { 1005 "i8 0", 1006 "[2 x [2 x i16]] zeroinitializer", 1007 }, 1008 { 1009 "i8 undef", 1010 "[2 x [2 x i16]] undef", 1011 }, 1012 { 1013 "i8 -86", 1014 "[2 x [2 x i16]] [[2 x i16] [i16 -21846, i16 -21846], " 1015 "[2 x i16] [i16 -21846, i16 -21846]]", 1016 }, 1017 { 1018 "", 1019 "[2 x [2 x i16]] [[2 x i16] [i16 -21846, i16 -21846], " 1020 "[2 x i16] [i16 -21836, i16 -21846]]", 1021 }, 1022 { 1023 "i8 undef", 1024 "{ } zeroinitializer", 1025 }, 1026 { 1027 "i8 undef", 1028 "{ } undef", 1029 }, 1030 { 1031 "i8 undef", 1032 "{ {}, {} } zeroinitializer", 1033 }, 1034 { 1035 "i8 undef", 1036 "{ {}, {} } undef", 1037 }, 1038 { 1039 "i8 0", 1040 "{i8, i64, i16*} zeroinitializer", 1041 }, 1042 { 1043 "i8 undef", 1044 "{i8, i64, i16*} undef", 1045 }, 1046 { 1047 "i8 -86", 1048 "{i8, i64, i16*} {i8 -86, i64 -6148914691236517206, i16* undef}", 1049 }, 1050 { 1051 "", 1052 "{i8, i64, i16*} {i8 86, i64 -6148914691236517206, i16* undef}", 1053 }, 1054 }; 1055 1056 INSTANTIATE_TEST_CASE_P(IsBytewiseValueParamTests, IsBytewiseValueTest, 1057 ::testing::ValuesIn(IsBytewiseValueTests),); 1058 1059 TEST_P(IsBytewiseValueTest, IsBytewiseValue) { 1060 auto M = parseModule(std::string("@test = global ") + GetParam().second); 1061 GlobalVariable *GV = dyn_cast<GlobalVariable>(M->getNamedValue("test")); 1062 Value *Actual = isBytewiseValue(GV->getInitializer(), M->getDataLayout()); 1063 std::string Buff; 1064 raw_string_ostream S(Buff); 1065 if (Actual) 1066 S << *Actual; 1067 EXPECT_EQ(GetParam().first, S.str()); 1068 } 1069