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, propagatesPoison) { 672 std::string AsmHead = "declare i32 @g(i32)\n" 673 "define void @f(i32 %x, i32 %y, float %fx, float %fy, " 674 "i1 %cond, i8* %p) {\n"; 675 std::string AsmTail = " ret void\n}"; 676 // (propagates poison?, IR instruction) 677 SmallVector<std::pair<bool, std::string>, 32> Data = { 678 {true, "add i32 %x, %y"}, 679 {true, "add nsw nuw i32 %x, %y"}, 680 {true, "ashr i32 %x, %y"}, 681 {true, "lshr exact i32 %x, 31"}, 682 {true, "fcmp oeq float %fx, %fy"}, 683 {true, "icmp eq i32 %x, %y"}, 684 {true, "getelementptr i8, i8* %p, i32 %x"}, 685 {true, "getelementptr inbounds i8, i8* %p, i32 %x"}, 686 {true, "bitcast float %fx to i32"}, 687 {false, "select i1 %cond, i32 %x, i32 %y"}, 688 {false, "freeze i32 %x"}, 689 {true, "udiv i32 %x, %y"}, 690 {true, "urem i32 %x, %y"}, 691 {true, "sdiv exact i32 %x, %y"}, 692 {true, "srem i32 %x, %y"}, 693 {false, "call i32 @g(i32 %x)"}}; 694 695 std::string AssemblyStr = AsmHead; 696 for (auto &Itm : Data) 697 AssemblyStr += Itm.second + "\n"; 698 AssemblyStr += AsmTail; 699 700 LLVMContext Context; 701 SMDiagnostic Error; 702 auto M = parseAssemblyString(AssemblyStr, Error, Context); 703 assert(M && "Bad assembly?"); 704 705 auto *F = M->getFunction("f"); 706 assert(F && "Bad assembly?"); 707 708 auto &BB = F->getEntryBlock(); 709 710 int Index = 0; 711 for (auto &I : BB) { 712 if (isa<ReturnInst>(&I)) 713 break; 714 EXPECT_EQ(propagatesPoison(&I), Data[Index].first) 715 << "Incorrect answer at instruction " << Index << " = " << I; 716 Index++; 717 } 718 } 719 720 TEST(ValueTracking, canCreatePoison) { 721 std::string AsmHead = 722 "declare i32 @g(i32)\n" 723 "define void @f(i32 %x, i32 %y, float %fx, float %fy, i1 %cond, " 724 "<4 x i32> %vx, <4 x i32> %vx2, <vscale x 4 x i32> %svx, i8* %p) {\n"; 725 std::string AsmTail = " ret void\n}"; 726 // (can create poison?, IR instruction) 727 SmallVector<std::pair<bool, std::string>, 32> Data = { 728 {false, "add i32 %x, %y"}, 729 {true, "add nsw nuw i32 %x, %y"}, 730 {true, "shl i32 %x, %y"}, 731 {true, "shl <4 x i32> %vx, %vx2"}, 732 {true, "shl nsw i32 %x, %y"}, 733 {true, "shl nsw <4 x i32> %vx, <i32 0, i32 1, i32 2, i32 3>"}, 734 {false, "shl i32 %x, 31"}, 735 {true, "shl i32 %x, 32"}, 736 {false, "shl <4 x i32> %vx, <i32 0, i32 1, i32 2, i32 3>"}, 737 {true, "shl <4 x i32> %vx, <i32 0, i32 1, i32 2, i32 32>"}, 738 {true, "ashr i32 %x, %y"}, 739 {true, "ashr exact i32 %x, %y"}, 740 {false, "ashr i32 %x, 31"}, 741 {true, "ashr exact i32 %x, 31"}, 742 {false, "ashr <4 x i32> %vx, <i32 0, i32 1, i32 2, i32 3>"}, 743 {true, "ashr <4 x i32> %vx, <i32 0, i32 1, i32 2, i32 32>"}, 744 {true, "ashr exact <4 x i32> %vx, <i32 0, i32 1, i32 2, i32 3>"}, 745 {true, "lshr i32 %x, %y"}, 746 {true, "lshr exact i32 %x, 31"}, 747 {false, "udiv i32 %x, %y"}, 748 {true, "udiv exact i32 %x, %y"}, 749 {false, "getelementptr i8, i8* %p, i32 %x"}, 750 {true, "getelementptr inbounds i8, i8* %p, i32 %x"}, 751 {true, "fneg nnan float %fx"}, 752 {false, "fneg float %fx"}, 753 {false, "fadd float %fx, %fy"}, 754 {true, "fadd nnan float %fx, %fy"}, 755 {false, "urem i32 %x, %y"}, 756 {true, "fptoui float %fx to i32"}, 757 {true, "fptosi float %fx to i32"}, 758 {false, "bitcast float %fx to i32"}, 759 {false, "select i1 %cond, i32 %x, i32 %y"}, 760 {true, "select nnan i1 %cond, float %fx, float %fy"}, 761 {true, "extractelement <4 x i32> %vx, i32 %x"}, 762 {false, "extractelement <4 x i32> %vx, i32 3"}, 763 {true, "extractelement <vscale x 4 x i32> %svx, i32 4"}, 764 {true, "insertelement <4 x i32> %vx, i32 %x, i32 %y"}, 765 {false, "insertelement <4 x i32> %vx, i32 %x, i32 3"}, 766 {true, "insertelement <vscale x 4 x i32> %svx, i32 %x, i32 4"}, 767 {false, "freeze i32 %x"}, 768 {true, "call i32 @g(i32 %x)"}, 769 {true, "fcmp nnan oeq float %fx, %fy"}, 770 {false, "fcmp oeq float %fx, %fy"}}; 771 772 std::string AssemblyStr = AsmHead; 773 for (auto &Itm : Data) 774 AssemblyStr += Itm.second + "\n"; 775 AssemblyStr += AsmTail; 776 777 LLVMContext Context; 778 SMDiagnostic Error; 779 auto M = parseAssemblyString(AssemblyStr, Error, Context); 780 assert(M && "Bad assembly?"); 781 782 auto *F = M->getFunction("f"); 783 assert(F && "Bad assembly?"); 784 785 auto &BB = F->getEntryBlock(); 786 787 int Index = 0; 788 for (auto &I : BB) { 789 if (isa<ReturnInst>(&I)) 790 break; 791 EXPECT_EQ(canCreatePoison(&I), Data[Index].first) 792 << "Incorrect answer at instruction " << Index << " = " << I; 793 Index++; 794 } 795 } 796 797 TEST_F(ComputeKnownBitsTest, ComputeKnownBits) { 798 parseAssembly( 799 "define i32 @test(i32 %a, i32 %b) {\n" 800 " %ash = mul i32 %a, 8\n" 801 " %aad = add i32 %ash, 7\n" 802 " %aan = and i32 %aad, 4095\n" 803 " %bsh = shl i32 %b, 4\n" 804 " %bad = or i32 %bsh, 6\n" 805 " %ban = and i32 %bad, 4095\n" 806 " %A = mul i32 %aan, %ban\n" 807 " ret i32 %A\n" 808 "}\n"); 809 expectKnownBits(/*zero*/ 4278190085u, /*one*/ 10u); 810 } 811 812 TEST_F(ComputeKnownBitsTest, ComputeKnownMulBits) { 813 parseAssembly( 814 "define i32 @test(i32 %a, i32 %b) {\n" 815 " %aa = shl i32 %a, 5\n" 816 " %bb = shl i32 %b, 5\n" 817 " %aaa = or i32 %aa, 24\n" 818 " %bbb = or i32 %bb, 28\n" 819 " %A = mul i32 %aaa, %bbb\n" 820 " ret i32 %A\n" 821 "}\n"); 822 expectKnownBits(/*zero*/ 95u, /*one*/ 32u); 823 } 824 825 TEST_F(ComputeKnownBitsTest, KnownNonZeroShift) { 826 // %q is known nonzero without known bits. 827 // Because %q is nonzero, %A[0] is known to be zero. 828 parseAssembly( 829 "define i8 @test(i8 %p, i8* %pq) {\n" 830 " %q = load i8, i8* %pq, !range !0\n" 831 " %A = shl i8 %p, %q\n" 832 " ret i8 %A\n" 833 "}\n" 834 "!0 = !{ i8 1, i8 5 }\n"); 835 expectKnownBits(/*zero*/ 1u, /*one*/ 0u); 836 } 837 838 TEST_F(ComputeKnownBitsTest, ComputeKnownFshl) { 839 // fshl(....1111....0000, 00..1111........, 6) 840 // = 11....000000..11 841 parseAssembly( 842 "define i16 @test(i16 %a, i16 %b) {\n" 843 " %aa = shl i16 %a, 4\n" 844 " %bb = lshr i16 %b, 2\n" 845 " %aaa = or i16 %aa, 3840\n" 846 " %bbb = or i16 %bb, 3840\n" 847 " %A = call i16 @llvm.fshl.i16(i16 %aaa, i16 %bbb, i16 6)\n" 848 " ret i16 %A\n" 849 "}\n" 850 "declare i16 @llvm.fshl.i16(i16, i16, i16)\n"); 851 expectKnownBits(/*zero*/ 1008u, /*one*/ 49155u); 852 } 853 854 TEST_F(ComputeKnownBitsTest, ComputeKnownFshr) { 855 // fshr(....1111....0000, 00..1111........, 26) 856 // = 11....000000..11 857 parseAssembly( 858 "define i16 @test(i16 %a, i16 %b) {\n" 859 " %aa = shl i16 %a, 4\n" 860 " %bb = lshr i16 %b, 2\n" 861 " %aaa = or i16 %aa, 3840\n" 862 " %bbb = or i16 %bb, 3840\n" 863 " %A = call i16 @llvm.fshr.i16(i16 %aaa, i16 %bbb, i16 26)\n" 864 " ret i16 %A\n" 865 "}\n" 866 "declare i16 @llvm.fshr.i16(i16, i16, i16)\n"); 867 expectKnownBits(/*zero*/ 1008u, /*one*/ 49155u); 868 } 869 870 TEST_F(ComputeKnownBitsTest, ComputeKnownFshlZero) { 871 // fshl(....1111....0000, 00..1111........, 0) 872 // = ....1111....0000 873 parseAssembly( 874 "define i16 @test(i16 %a, i16 %b) {\n" 875 " %aa = shl i16 %a, 4\n" 876 " %bb = lshr i16 %b, 2\n" 877 " %aaa = or i16 %aa, 3840\n" 878 " %bbb = or i16 %bb, 3840\n" 879 " %A = call i16 @llvm.fshl.i16(i16 %aaa, i16 %bbb, i16 0)\n" 880 " ret i16 %A\n" 881 "}\n" 882 "declare i16 @llvm.fshl.i16(i16, i16, i16)\n"); 883 expectKnownBits(/*zero*/ 15u, /*one*/ 3840u); 884 } 885 886 TEST_F(ComputeKnownBitsTest, ComputeKnownUAddSatLeadingOnes) { 887 // uadd.sat(1111...1, ........) 888 // = 1111.... 889 parseAssembly( 890 "define i8 @test(i8 %a, i8 %b) {\n" 891 " %aa = or i8 %a, 241\n" 892 " %A = call i8 @llvm.uadd.sat.i8(i8 %aa, i8 %b)\n" 893 " ret i8 %A\n" 894 "}\n" 895 "declare i8 @llvm.uadd.sat.i8(i8, i8)\n"); 896 expectKnownBits(/*zero*/ 0u, /*one*/ 240u); 897 } 898 899 TEST_F(ComputeKnownBitsTest, ComputeKnownUAddSatOnesPreserved) { 900 // uadd.sat(00...011, .1...110) 901 // = .......1 902 parseAssembly( 903 "define i8 @test(i8 %a, i8 %b) {\n" 904 " %aa = or i8 %a, 3\n" 905 " %aaa = and i8 %aa, 59\n" 906 " %bb = or i8 %b, 70\n" 907 " %bbb = and i8 %bb, 254\n" 908 " %A = call i8 @llvm.uadd.sat.i8(i8 %aaa, i8 %bbb)\n" 909 " ret i8 %A\n" 910 "}\n" 911 "declare i8 @llvm.uadd.sat.i8(i8, i8)\n"); 912 expectKnownBits(/*zero*/ 0u, /*one*/ 1u); 913 } 914 915 TEST_F(ComputeKnownBitsTest, ComputeKnownUSubSatLHSLeadingZeros) { 916 // usub.sat(0000...0, ........) 917 // = 0000.... 918 parseAssembly( 919 "define i8 @test(i8 %a, i8 %b) {\n" 920 " %aa = and i8 %a, 14\n" 921 " %A = call i8 @llvm.usub.sat.i8(i8 %aa, i8 %b)\n" 922 " ret i8 %A\n" 923 "}\n" 924 "declare i8 @llvm.usub.sat.i8(i8, i8)\n"); 925 expectKnownBits(/*zero*/ 240u, /*one*/ 0u); 926 } 927 928 TEST_F(ComputeKnownBitsTest, ComputeKnownUSubSatRHSLeadingOnes) { 929 // usub.sat(........, 1111...1) 930 // = 0000.... 931 parseAssembly( 932 "define i8 @test(i8 %a, i8 %b) {\n" 933 " %bb = or i8 %a, 241\n" 934 " %A = call i8 @llvm.usub.sat.i8(i8 %a, i8 %bb)\n" 935 " ret i8 %A\n" 936 "}\n" 937 "declare i8 @llvm.usub.sat.i8(i8, i8)\n"); 938 expectKnownBits(/*zero*/ 240u, /*one*/ 0u); 939 } 940 941 TEST_F(ComputeKnownBitsTest, ComputeKnownUSubSatZerosPreserved) { 942 // usub.sat(11...011, .1...110) 943 // = ......0. 944 parseAssembly( 945 "define i8 @test(i8 %a, i8 %b) {\n" 946 " %aa = or i8 %a, 195\n" 947 " %aaa = and i8 %aa, 251\n" 948 " %bb = or i8 %b, 70\n" 949 " %bbb = and i8 %bb, 254\n" 950 " %A = call i8 @llvm.usub.sat.i8(i8 %aaa, i8 %bbb)\n" 951 " ret i8 %A\n" 952 "}\n" 953 "declare i8 @llvm.usub.sat.i8(i8, i8)\n"); 954 expectKnownBits(/*zero*/ 2u, /*one*/ 0u); 955 } 956 957 class IsBytewiseValueTest : public ValueTrackingTest, 958 public ::testing::WithParamInterface< 959 std::pair<const char *, const char *>> { 960 protected: 961 }; 962 963 const std::pair<const char *, const char *> IsBytewiseValueTests[] = { 964 { 965 "i8 0", 966 "i48* null", 967 }, 968 { 969 "i8 undef", 970 "i48* undef", 971 }, 972 { 973 "i8 0", 974 "i8 zeroinitializer", 975 }, 976 { 977 "i8 0", 978 "i8 0", 979 }, 980 { 981 "i8 -86", 982 "i8 -86", 983 }, 984 { 985 "i8 -1", 986 "i8 -1", 987 }, 988 { 989 "i8 undef", 990 "i16 undef", 991 }, 992 { 993 "i8 0", 994 "i16 0", 995 }, 996 { 997 "", 998 "i16 7", 999 }, 1000 { 1001 "i8 -86", 1002 "i16 -21846", 1003 }, 1004 { 1005 "i8 -1", 1006 "i16 -1", 1007 }, 1008 { 1009 "i8 0", 1010 "i48 0", 1011 }, 1012 { 1013 "i8 -1", 1014 "i48 -1", 1015 }, 1016 { 1017 "i8 0", 1018 "i49 0", 1019 }, 1020 { 1021 "", 1022 "i49 -1", 1023 }, 1024 { 1025 "i8 0", 1026 "half 0xH0000", 1027 }, 1028 { 1029 "i8 -85", 1030 "half 0xHABAB", 1031 }, 1032 { 1033 "i8 0", 1034 "float 0.0", 1035 }, 1036 { 1037 "i8 -1", 1038 "float 0xFFFFFFFFE0000000", 1039 }, 1040 { 1041 "i8 0", 1042 "double 0.0", 1043 }, 1044 { 1045 "i8 -15", 1046 "double 0xF1F1F1F1F1F1F1F1", 1047 }, 1048 { 1049 "i8 undef", 1050 "i16* undef", 1051 }, 1052 { 1053 "i8 0", 1054 "i16* inttoptr (i64 0 to i16*)", 1055 }, 1056 { 1057 "i8 -1", 1058 "i16* inttoptr (i64 -1 to i16*)", 1059 }, 1060 { 1061 "i8 -86", 1062 "i16* inttoptr (i64 -6148914691236517206 to i16*)", 1063 }, 1064 { 1065 "", 1066 "i16* inttoptr (i48 -1 to i16*)", 1067 }, 1068 { 1069 "i8 -1", 1070 "i16* inttoptr (i96 -1 to i16*)", 1071 }, 1072 { 1073 "i8 undef", 1074 "[0 x i8] zeroinitializer", 1075 }, 1076 { 1077 "i8 undef", 1078 "[0 x i8] undef", 1079 }, 1080 { 1081 "i8 undef", 1082 "[5 x [0 x i8]] zeroinitializer", 1083 }, 1084 { 1085 "i8 undef", 1086 "[5 x [0 x i8]] undef", 1087 }, 1088 { 1089 "i8 0", 1090 "[6 x i8] zeroinitializer", 1091 }, 1092 { 1093 "i8 undef", 1094 "[6 x i8] undef", 1095 }, 1096 { 1097 "i8 1", 1098 "[5 x i8] [i8 1, i8 1, i8 1, i8 1, i8 1]", 1099 }, 1100 { 1101 "", 1102 "[5 x i64] [i64 1, i64 1, i64 1, i64 1, i64 1]", 1103 }, 1104 { 1105 "i8 -1", 1106 "[5 x i64] [i64 -1, i64 -1, i64 -1, i64 -1, i64 -1]", 1107 }, 1108 { 1109 "", 1110 "[4 x i8] [i8 1, i8 2, i8 1, i8 1]", 1111 }, 1112 { 1113 "i8 1", 1114 "[4 x i8] [i8 1, i8 undef, i8 1, i8 1]", 1115 }, 1116 { 1117 "i8 0", 1118 "<6 x i8> zeroinitializer", 1119 }, 1120 { 1121 "i8 undef", 1122 "<6 x i8> undef", 1123 }, 1124 { 1125 "i8 1", 1126 "<5 x i8> <i8 1, i8 1, i8 1, i8 1, i8 1>", 1127 }, 1128 { 1129 "", 1130 "<5 x i64> <i64 1, i64 1, i64 1, i64 1, i64 1>", 1131 }, 1132 { 1133 "i8 -1", 1134 "<5 x i64> <i64 -1, i64 -1, i64 -1, i64 -1, i64 -1>", 1135 }, 1136 { 1137 "", 1138 "<4 x i8> <i8 1, i8 1, i8 2, i8 1>", 1139 }, 1140 { 1141 "i8 5", 1142 "<2 x i8> < i8 5, i8 undef >", 1143 }, 1144 { 1145 "i8 0", 1146 "[2 x [2 x i16]] zeroinitializer", 1147 }, 1148 { 1149 "i8 undef", 1150 "[2 x [2 x i16]] undef", 1151 }, 1152 { 1153 "i8 -86", 1154 "[2 x [2 x i16]] [[2 x i16] [i16 -21846, i16 -21846], " 1155 "[2 x i16] [i16 -21846, i16 -21846]]", 1156 }, 1157 { 1158 "", 1159 "[2 x [2 x i16]] [[2 x i16] [i16 -21846, i16 -21846], " 1160 "[2 x i16] [i16 -21836, i16 -21846]]", 1161 }, 1162 { 1163 "i8 undef", 1164 "{ } zeroinitializer", 1165 }, 1166 { 1167 "i8 undef", 1168 "{ } undef", 1169 }, 1170 { 1171 "i8 undef", 1172 "{ {}, {} } zeroinitializer", 1173 }, 1174 { 1175 "i8 undef", 1176 "{ {}, {} } undef", 1177 }, 1178 { 1179 "i8 0", 1180 "{i8, i64, i16*} zeroinitializer", 1181 }, 1182 { 1183 "i8 undef", 1184 "{i8, i64, i16*} undef", 1185 }, 1186 { 1187 "i8 -86", 1188 "{i8, i64, i16*} {i8 -86, i64 -6148914691236517206, i16* undef}", 1189 }, 1190 { 1191 "", 1192 "{i8, i64, i16*} {i8 86, i64 -6148914691236517206, i16* undef}", 1193 }, 1194 }; 1195 1196 INSTANTIATE_TEST_CASE_P(IsBytewiseValueParamTests, IsBytewiseValueTest, 1197 ::testing::ValuesIn(IsBytewiseValueTests),); 1198 1199 TEST_P(IsBytewiseValueTest, IsBytewiseValue) { 1200 auto M = parseModule(std::string("@test = global ") + GetParam().second); 1201 GlobalVariable *GV = dyn_cast<GlobalVariable>(M->getNamedValue("test")); 1202 Value *Actual = isBytewiseValue(GV->getInitializer(), M->getDataLayout()); 1203 std::string Buff; 1204 raw_string_ostream S(Buff); 1205 if (Actual) 1206 S << *Actual; 1207 EXPECT_EQ(GetParam().first, S.str()); 1208 } 1209