1 //===- SandboxIRTest.cpp --------------------------------------------------===// 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/AsmParser/Parser.h" 10 #include "llvm/IR/BasicBlock.h" 11 #include "llvm/IR/Constants.h" 12 #include "llvm/IR/DataLayout.h" 13 #include "llvm/IR/Function.h" 14 #include "llvm/IR/Instruction.h" 15 #include "llvm/IR/Module.h" 16 #include "llvm/SandboxIR/BasicBlock.h" 17 #include "llvm/SandboxIR/Constant.h" 18 #include "llvm/SandboxIR/Function.h" 19 #include "llvm/SandboxIR/Instruction.h" 20 #include "llvm/SandboxIR/Module.h" 21 #include "llvm/SandboxIR/Utils.h" 22 #include "llvm/SandboxIR/Value.h" 23 #include "llvm/Support/SourceMgr.h" 24 #include "gmock/gmock-matchers.h" 25 #include "gtest/gtest.h" 26 27 using namespace llvm; 28 29 struct SandboxIRTest : public testing::Test { 30 LLVMContext C; 31 std::unique_ptr<Module> M; 32 33 void parseIR(LLVMContext &C, const char *IR) { 34 SMDiagnostic Err; 35 M = parseAssemblyString(IR, Err, C); 36 if (!M) 37 Err.print("SandboxIRTest", errs()); 38 } 39 BasicBlock *getBasicBlockByName(Function &F, StringRef Name) { 40 for (BasicBlock &BB : F) 41 if (BB.getName() == Name) 42 return &BB; 43 llvm_unreachable("Expected to find basic block!"); 44 } 45 }; 46 47 TEST_F(SandboxIRTest, ClassID) { 48 parseIR(C, R"IR( 49 define void @foo(i32 %v1) { 50 %add = add i32 %v1, 42 51 ret void 52 } 53 )IR"); 54 llvm::Function *LLVMF = &*M->getFunction("foo"); 55 llvm::BasicBlock *LLVMBB = &*LLVMF->begin(); 56 llvm::Instruction *LLVMAdd = &*LLVMBB->begin(); 57 auto *LLVMC = cast<llvm::Constant>(LLVMAdd->getOperand(1)); 58 59 sandboxir::Context Ctx(C); 60 sandboxir::Function *F = Ctx.createFunction(LLVMF); 61 sandboxir::Argument *Arg0 = F->getArg(0); 62 sandboxir::BasicBlock *BB = &*F->begin(); 63 sandboxir::Instruction *AddI = &*BB->begin(); 64 sandboxir::Constant *Const0 = cast<sandboxir::Constant>(Ctx.getValue(LLVMC)); 65 66 EXPECT_TRUE(isa<sandboxir::Function>(F)); 67 EXPECT_FALSE(isa<sandboxir::Function>(Arg0)); 68 EXPECT_FALSE(isa<sandboxir::Function>(BB)); 69 EXPECT_FALSE(isa<sandboxir::Function>(AddI)); 70 EXPECT_FALSE(isa<sandboxir::Function>(Const0)); 71 72 EXPECT_FALSE(isa<sandboxir::Argument>(F)); 73 EXPECT_TRUE(isa<sandboxir::Argument>(Arg0)); 74 EXPECT_FALSE(isa<sandboxir::Argument>(BB)); 75 EXPECT_FALSE(isa<sandboxir::Argument>(AddI)); 76 EXPECT_FALSE(isa<sandboxir::Argument>(Const0)); 77 78 EXPECT_TRUE(isa<sandboxir::Constant>(F)); 79 EXPECT_FALSE(isa<sandboxir::Constant>(Arg0)); 80 EXPECT_FALSE(isa<sandboxir::Constant>(BB)); 81 EXPECT_FALSE(isa<sandboxir::Constant>(AddI)); 82 EXPECT_TRUE(isa<sandboxir::Constant>(Const0)); 83 84 EXPECT_FALSE(isa<sandboxir::OpaqueInst>(F)); 85 EXPECT_FALSE(isa<sandboxir::OpaqueInst>(Arg0)); 86 EXPECT_FALSE(isa<sandboxir::OpaqueInst>(BB)); 87 EXPECT_FALSE(isa<sandboxir::OpaqueInst>(AddI)); 88 EXPECT_FALSE(isa<sandboxir::OpaqueInst>(Const0)); 89 90 EXPECT_FALSE(isa<sandboxir::Instruction>(F)); 91 EXPECT_FALSE(isa<sandboxir::Instruction>(Arg0)); 92 EXPECT_FALSE(isa<sandboxir::Instruction>(BB)); 93 EXPECT_TRUE(isa<sandboxir::Instruction>(AddI)); 94 EXPECT_FALSE(isa<sandboxir::Instruction>(Const0)); 95 96 EXPECT_TRUE(isa<sandboxir::User>(F)); 97 EXPECT_FALSE(isa<sandboxir::User>(Arg0)); 98 EXPECT_FALSE(isa<sandboxir::User>(BB)); 99 EXPECT_TRUE(isa<sandboxir::User>(AddI)); 100 EXPECT_TRUE(isa<sandboxir::User>(Const0)); 101 102 #ifndef NDEBUG 103 std::string Buff; 104 raw_string_ostream BS(Buff); 105 F->dumpOS(BS); 106 Arg0->dumpOS(BS); 107 BB->dumpOS(BS); 108 AddI->dumpOS(BS); 109 Const0->dumpOS(BS); 110 #endif 111 } 112 113 TEST_F(SandboxIRTest, ConstantInt) { 114 parseIR(C, R"IR( 115 define void @foo(i32 %v0) { 116 %add0 = add i32 %v0, 42 117 ret void 118 } 119 )IR"); 120 Function &LLVMF = *M->getFunction("foo"); 121 auto *LLVMBB = &*LLVMF.begin(); 122 auto *LLVMAdd0 = &*LLVMBB->begin(); 123 auto *LLVMFortyTwo = cast<llvm::ConstantInt>(LLVMAdd0->getOperand(1)); 124 sandboxir::Context Ctx(C); 125 126 auto &F = *Ctx.createFunction(&LLVMF); 127 auto &BB = *F.begin(); 128 auto It = BB.begin(); 129 auto *Add0 = cast<sandboxir::BinaryOperator>(&*It++); 130 auto *FortyTwo = cast<sandboxir::ConstantInt>(Add0->getOperand(1)); 131 132 // Check that creating an identical constant gives us the same object. 133 auto *NewCI = 134 sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 42); 135 EXPECT_EQ(NewCI, FortyTwo); 136 { 137 // Check getTrue(Ctx). 138 auto *True = sandboxir::ConstantInt::getTrue(Ctx); 139 EXPECT_EQ(True, Ctx.getValue(llvm::ConstantInt::getTrue(C))); 140 // Check getFalse(Ctx). 141 auto *False = sandboxir::ConstantInt::getFalse(Ctx); 142 EXPECT_EQ(False, Ctx.getValue(llvm::ConstantInt::getFalse(C))); 143 // Check getBool(Ctx). 144 auto *Bool = sandboxir::ConstantInt::getBool(Ctx, true); 145 EXPECT_EQ(Bool, Ctx.getValue(llvm::ConstantInt::getBool(C, true))); 146 } 147 { 148 auto *Int1Ty = sandboxir::Type::getInt1Ty(Ctx); 149 auto *LLVMInt1Ty = llvm::Type::getInt1Ty(C); 150 // Check getTrue(Ty). 151 auto *True = sandboxir::ConstantInt::getTrue(Int1Ty); 152 EXPECT_EQ(True, Ctx.getValue(llvm::ConstantInt::getTrue(LLVMInt1Ty))); 153 // Check getFalse(Ty). 154 auto *False = sandboxir::ConstantInt::getFalse(Int1Ty); 155 EXPECT_EQ(False, Ctx.getValue(llvm::ConstantInt::getFalse(LLVMInt1Ty))); 156 // Check getBool(Ty). 157 auto *Bool = sandboxir::ConstantInt::getBool(Int1Ty, true); 158 EXPECT_EQ(Bool, Ctx.getValue(llvm::ConstantInt::getBool(LLVMInt1Ty, true))); 159 } 160 161 auto *Int32Ty = sandboxir::Type::getInt32Ty(Ctx); 162 auto *LLVMInt32Ty = llvm::Type::getInt32Ty(C); 163 { 164 // Check get(Type, V). 165 auto *FortyThree = sandboxir::ConstantInt::get(Int32Ty, 43); 166 auto *LLVMFortyThree = llvm::ConstantInt::get(LLVMInt32Ty, 43); 167 EXPECT_NE(FortyThree, FortyTwo); 168 EXPECT_EQ(FortyThree, Ctx.getValue(LLVMFortyThree)); 169 } 170 { 171 // Check get(Type, V, IsSigned). 172 auto *FortyThree = 173 sandboxir::ConstantInt::get(Int32Ty, 43, /*IsSigned=*/true); 174 auto *LLVMFortyThree = 175 llvm::ConstantInt::get(LLVMInt32Ty, 43, /*IsSigned=*/true); 176 EXPECT_NE(FortyThree, FortyTwo); 177 EXPECT_EQ(FortyThree, Ctx.getValue(LLVMFortyThree)); 178 } 179 180 { 181 // Check get(IntegerType, V). 182 auto *FortyThree = 183 sandboxir::ConstantInt::get(sandboxir::IntegerType::get(Ctx, 32), 43); 184 auto *LLVMFortyThree = 185 llvm::ConstantInt::get(llvm::IntegerType::get(C, 32), 43); 186 EXPECT_NE(FortyThree, FortyTwo); 187 EXPECT_EQ(FortyThree, Ctx.getValue(LLVMFortyThree)); 188 } 189 { 190 // Check get(IntegerType, V, IsSigned). 191 auto *FortyThree = sandboxir::ConstantInt::get( 192 sandboxir::IntegerType::get(Ctx, 32), 43, /*IsSigned=*/true); 193 auto *LLVMFortyThree = llvm::ConstantInt::get(llvm::IntegerType::get(C, 32), 194 43, /*IsSigned=*/true); 195 EXPECT_NE(FortyThree, FortyTwo); 196 EXPECT_EQ(FortyThree, Ctx.getValue(LLVMFortyThree)); 197 } 198 199 { 200 // Check getSigned(IntegerType, V). 201 auto *FortyThree = sandboxir::ConstantInt::getSigned( 202 sandboxir::IntegerType::get(Ctx, 32), 43); 203 auto *LLVMFortyThree = 204 llvm::ConstantInt::getSigned(llvm::IntegerType::get(C, 32), 43); 205 EXPECT_NE(FortyThree, FortyTwo); 206 EXPECT_EQ(FortyThree, Ctx.getValue(LLVMFortyThree)); 207 } 208 { 209 // Check getSigned(Type, V). 210 auto *FortyThree = sandboxir::ConstantInt::getSigned(Int32Ty, 43); 211 auto *LLVMFortyThree = llvm::ConstantInt::getSigned(LLVMInt32Ty, 43); 212 EXPECT_NE(FortyThree, FortyTwo); 213 EXPECT_EQ(FortyThree, Ctx.getValue(LLVMFortyThree)); 214 } 215 { 216 // Check get(Ctx, APInt). 217 APInt APInt43(32, 43); 218 auto *FortyThree = sandboxir::ConstantInt::get(Ctx, APInt43); 219 auto *LLVMFortyThree = llvm::ConstantInt::get(C, APInt43); 220 EXPECT_NE(FortyThree, FortyTwo); 221 EXPECT_EQ(FortyThree, Ctx.getValue(LLVMFortyThree)); 222 } 223 { 224 // Check get(Ty, Str, Radix). 225 StringRef Str("43"); 226 uint8_t Radix(10); 227 auto *FortyThree = sandboxir::ConstantInt::get( 228 sandboxir::IntegerType::get(Ctx, 32), Str, Radix); 229 auto *LLVMFortyThree = 230 llvm::ConstantInt::get(llvm::IntegerType::get(C, 32), Str, Radix); 231 EXPECT_NE(FortyThree, FortyTwo); 232 EXPECT_EQ(FortyThree, Ctx.getValue(LLVMFortyThree)); 233 } 234 { 235 // Check get(Ty, APInt). 236 APInt APInt43(32, 43); 237 auto *FortyThree = sandboxir::ConstantInt::get(Int32Ty, APInt43); 238 auto *LLVMFortyThree = llvm::ConstantInt::get(LLVMInt32Ty, APInt43); 239 EXPECT_NE(FortyThree, FortyTwo); 240 EXPECT_EQ(FortyThree, Ctx.getValue(LLVMFortyThree)); 241 } 242 // Check getValue(). 243 EXPECT_EQ(FortyTwo->getValue(), LLVMFortyTwo->getValue()); 244 // Check getBitWidth(). 245 EXPECT_EQ(FortyTwo->getBitWidth(), LLVMFortyTwo->getBitWidth()); 246 // Check getZExtValue(). 247 EXPECT_EQ(FortyTwo->getZExtValue(), LLVMFortyTwo->getZExtValue()); 248 // Check getSExtValue(). 249 EXPECT_EQ(FortyTwo->getSExtValue(), LLVMFortyTwo->getSExtValue()); 250 // Check getMaybeAlignValue(). 251 auto *SixtyFour = 252 cast<sandboxir::ConstantInt>(sandboxir::ConstantInt::get(Int32Ty, 64)); 253 auto *LLVMSixtyFour = 254 cast<llvm::ConstantInt>(llvm::ConstantInt::get(LLVMInt32Ty, 64)); 255 EXPECT_EQ(SixtyFour->getMaybeAlignValue(), 256 LLVMSixtyFour->getMaybeAlignValue()); 257 // Check getAlignValue(). 258 EXPECT_EQ(SixtyFour->getAlignValue(), LLVMSixtyFour->getAlignValue()); 259 // Check equalsInt(). 260 EXPECT_TRUE(FortyTwo->equalsInt(42)); 261 EXPECT_FALSE(FortyTwo->equalsInt(43)); 262 // Check getIntegerType(). 263 EXPECT_EQ(FortyTwo->getIntegerType(), sandboxir::IntegerType::get(Ctx, 32)); 264 // Check isValueValidForType(). 265 EXPECT_TRUE( 266 sandboxir::ConstantInt::isValueValidForType(Int32Ty, (uint64_t)42)); 267 EXPECT_TRUE( 268 sandboxir::ConstantInt::isValueValidForType(Int32Ty, (int64_t)42)); 269 // Check isNegative(). 270 EXPECT_FALSE(FortyTwo->isNegative()); 271 EXPECT_TRUE(sandboxir::ConstantInt::get(Int32Ty, -42)); 272 // Check isZero(). 273 EXPECT_FALSE(FortyTwo->isZero()); 274 EXPECT_TRUE(sandboxir::ConstantInt::get(Int32Ty, 0)->isZero()); 275 // Check isOne(). 276 EXPECT_FALSE(FortyTwo->isOne()); 277 EXPECT_TRUE(sandboxir::ConstantInt::get(Int32Ty, 1)->isOne()); 278 // Check isMinusOne(). 279 EXPECT_FALSE(FortyTwo->isMinusOne()); 280 EXPECT_TRUE(sandboxir::ConstantInt::get(Int32Ty, -1)->isMinusOne()); 281 // Check isMaxValue(). 282 EXPECT_FALSE(FortyTwo->isMaxValue(/*Signed=*/true)); 283 EXPECT_TRUE( 284 sandboxir::ConstantInt::get(Int32Ty, std::numeric_limits<int32_t>::max()) 285 ->isMaxValue(/*Signed=*/true)); 286 // Check isMinValue(). 287 EXPECT_FALSE(FortyTwo->isMinValue(/*Signed=*/true)); 288 EXPECT_TRUE( 289 sandboxir::ConstantInt::get(Int32Ty, std::numeric_limits<int32_t>::min()) 290 ->isMinValue(/*Signed=*/true)); 291 // Check uge(). 292 EXPECT_TRUE(FortyTwo->uge(41)); 293 EXPECT_FALSE(FortyTwo->uge(43)); 294 // Check getLimitedValue(). 295 EXPECT_EQ(FortyTwo->getLimitedValue(40u), 40u); 296 EXPECT_EQ(FortyTwo->getLimitedValue(50u), 42u); 297 } 298 299 TEST_F(SandboxIRTest, ConstantFP) { 300 parseIR(C, R"IR( 301 define void @foo(float %v0, double %v1) { 302 %fadd0 = fadd float %v0, 42.0 303 %fadd1 = fadd double %v1, 43.0 304 ret void 305 } 306 )IR"); 307 Function &LLVMF = *M->getFunction("foo"); 308 sandboxir::Context Ctx(C); 309 310 auto &F = *Ctx.createFunction(&LLVMF); 311 auto &BB = *F.begin(); 312 auto It = BB.begin(); 313 auto *FAdd0 = cast<sandboxir::BinaryOperator>(&*It++); 314 auto *FAdd1 = cast<sandboxir::BinaryOperator>(&*It++); 315 auto *FortyTwo = cast<sandboxir::ConstantFP>(FAdd0->getOperand(1)); 316 [[maybe_unused]] auto *FortyThree = 317 cast<sandboxir::ConstantFP>(FAdd1->getOperand(1)); 318 319 auto *FloatTy = sandboxir::Type::getFloatTy(Ctx); 320 auto *DoubleTy = sandboxir::Type::getDoubleTy(Ctx); 321 auto *LLVMFloatTy = Type::getFloatTy(C); 322 auto *LLVMDoubleTy = Type::getDoubleTy(C); 323 // Check that creating an identical constant gives us the same object. 324 auto *NewFortyTwo = sandboxir::ConstantFP::get(FloatTy, 42.0); 325 EXPECT_EQ(NewFortyTwo, FortyTwo); 326 // Check get(Type, double). 327 auto *FortyFour = 328 cast<sandboxir::ConstantFP>(sandboxir::ConstantFP::get(FloatTy, 44.0)); 329 auto *LLVMFortyFour = 330 cast<llvm::ConstantFP>(llvm::ConstantFP::get(LLVMFloatTy, 44.0)); 331 EXPECT_NE(FortyFour, FortyTwo); 332 EXPECT_EQ(FortyFour, Ctx.getValue(LLVMFortyFour)); 333 // Check get(Type, APFloat). 334 auto *FortyFive = cast<sandboxir::ConstantFP>( 335 sandboxir::ConstantFP::get(DoubleTy, APFloat(45.0))); 336 auto *LLVMFortyFive = cast<llvm::ConstantFP>( 337 llvm::ConstantFP::get(LLVMDoubleTy, APFloat(45.0))); 338 EXPECT_EQ(FortyFive, Ctx.getValue(LLVMFortyFive)); 339 // Check get(Type, StringRef). 340 auto *FortySix = sandboxir::ConstantFP::get(FloatTy, "46.0"); 341 EXPECT_EQ(FortySix, Ctx.getValue(llvm::ConstantFP::get(LLVMFloatTy, "46.0"))); 342 // Check get(APFloat). 343 auto *FortySeven = sandboxir::ConstantFP::get(APFloat(47.0), Ctx); 344 EXPECT_EQ(FortySeven, Ctx.getValue(llvm::ConstantFP::get(C, APFloat(47.0)))); 345 // Check getNaN(). 346 { 347 auto *NaN = sandboxir::ConstantFP::getNaN(FloatTy); 348 EXPECT_EQ(NaN, Ctx.getValue(llvm::ConstantFP::getNaN(LLVMFloatTy))); 349 } 350 { 351 auto *NaN = sandboxir::ConstantFP::getNaN(FloatTy, /*Negative=*/true); 352 EXPECT_EQ(NaN, Ctx.getValue(llvm::ConstantFP::getNaN(LLVMFloatTy, 353 /*Negative=*/true))); 354 } 355 { 356 auto *NaN = sandboxir::ConstantFP::getNaN(FloatTy, /*Negative=*/true, 357 /*Payload=*/1); 358 EXPECT_EQ(NaN, Ctx.getValue(llvm::ConstantFP::getNaN( 359 LLVMFloatTy, /*Negative=*/true, /*Payload=*/1))); 360 } 361 // Check getQNaN(). 362 { 363 auto *QNaN = sandboxir::ConstantFP::getQNaN(FloatTy); 364 EXPECT_EQ(QNaN, Ctx.getValue(llvm::ConstantFP::getQNaN(LLVMFloatTy))); 365 } 366 { 367 auto *QNaN = sandboxir::ConstantFP::getQNaN(FloatTy, /*Negative=*/true); 368 EXPECT_EQ(QNaN, Ctx.getValue(llvm::ConstantFP::getQNaN(LLVMFloatTy, 369 /*Negative=*/true))); 370 } 371 { 372 APInt Payload(1, 1); 373 auto *QNaN = 374 sandboxir::ConstantFP::getQNaN(FloatTy, /*Negative=*/true, &Payload); 375 EXPECT_EQ(QNaN, Ctx.getValue(llvm::ConstantFP::getQNaN( 376 LLVMFloatTy, /*Negative=*/true, &Payload))); 377 } 378 // Check getSNaN(). 379 { 380 auto *SNaN = sandboxir::ConstantFP::getSNaN(FloatTy); 381 EXPECT_EQ(SNaN, Ctx.getValue(llvm::ConstantFP::getSNaN(LLVMFloatTy))); 382 } 383 { 384 auto *SNaN = sandboxir::ConstantFP::getSNaN(FloatTy, /*Negative=*/true); 385 EXPECT_EQ(SNaN, Ctx.getValue(llvm::ConstantFP::getSNaN(LLVMFloatTy, 386 /*Negative=*/true))); 387 } 388 { 389 APInt Payload(1, 1); 390 auto *SNaN = 391 sandboxir::ConstantFP::getSNaN(FloatTy, /*Negative=*/true, &Payload); 392 EXPECT_EQ(SNaN, Ctx.getValue(llvm::ConstantFP::getSNaN( 393 LLVMFloatTy, /*Negative=*/true, &Payload))); 394 } 395 396 // Check getZero(). 397 { 398 auto *Zero = sandboxir::ConstantFP::getZero(FloatTy); 399 EXPECT_EQ(Zero, Ctx.getValue(llvm::ConstantFP::getZero(LLVMFloatTy))); 400 } 401 { 402 auto *Zero = sandboxir::ConstantFP::getZero(FloatTy, /*Negative=*/true); 403 EXPECT_EQ(Zero, Ctx.getValue(llvm::ConstantFP::getZero(LLVMFloatTy, 404 /*Negative=*/true))); 405 } 406 407 // Check getNegativeZero(). 408 auto *NegZero = cast<sandboxir::ConstantFP>( 409 sandboxir::ConstantFP::getNegativeZero(FloatTy)); 410 EXPECT_EQ(NegZero, 411 Ctx.getValue(llvm::ConstantFP::getNegativeZero(LLVMFloatTy))); 412 413 // Check getInfinity(). 414 { 415 auto *Inf = sandboxir::ConstantFP::getInfinity(FloatTy); 416 EXPECT_EQ(Inf, Ctx.getValue(llvm::ConstantFP::getInfinity(LLVMFloatTy))); 417 } 418 { 419 auto *Inf = sandboxir::ConstantFP::getInfinity(FloatTy, /*Negative=*/true); 420 EXPECT_EQ(Inf, Ctx.getValue(llvm::ConstantFP::getInfinity( 421 LLVMFloatTy, /*Negative=*/true))); 422 } 423 424 // Check isValueValidForType(). 425 APFloat V(1.1); 426 EXPECT_EQ(sandboxir::ConstantFP::isValueValidForType(FloatTy, V), 427 llvm::ConstantFP::isValueValidForType(LLVMFloatTy, V)); 428 // Check getValueAPF(). 429 EXPECT_EQ(FortyFour->getValueAPF(), LLVMFortyFour->getValueAPF()); 430 // Check getValue(). 431 EXPECT_EQ(FortyFour->getValue(), LLVMFortyFour->getValue()); 432 // Check isZero(). 433 EXPECT_EQ(FortyFour->isZero(), LLVMFortyFour->isZero()); 434 EXPECT_TRUE(sandboxir::ConstantFP::getZero(FloatTy)); 435 EXPECT_TRUE(sandboxir::ConstantFP::getZero(FloatTy, /*Negative=*/true)); 436 // Check isNegative(). 437 EXPECT_TRUE(cast<sandboxir::ConstantFP>( 438 sandboxir::ConstantFP::getZero(FloatTy, /*Negative=*/true)) 439 ->isNegative()); 440 // Check isInfinity(). 441 EXPECT_TRUE( 442 cast<sandboxir::ConstantFP>(sandboxir::ConstantFP::getInfinity(FloatTy)) 443 ->isInfinity()); 444 // Check isNaN(). 445 EXPECT_TRUE( 446 cast<sandboxir::ConstantFP>(sandboxir::ConstantFP::getNaN(FloatTy)) 447 ->isNaN()); 448 // Check isExactlyValue(APFloat). 449 EXPECT_TRUE(NegZero->isExactlyValue(NegZero->getValueAPF())); 450 // Check isExactlyValue(double). 451 EXPECT_TRUE(NegZero->isExactlyValue(-0.0)); 452 } 453 454 // Tests ConstantArray, ConstantStruct and ConstantVector. 455 TEST_F(SandboxIRTest, ConstantAggregate) { 456 // Note: we are using i42 to avoid the creation of ConstantDataVector or 457 // ConstantDataArray. 458 parseIR(C, R"IR( 459 define void @foo() { 460 %array = extractvalue [2 x i42] [i42 0, i42 1], 0 461 %struct = extractvalue {i42, i42} {i42 0, i42 1}, 0 462 %vector = extractelement <2 x i42> <i42 0, i42 1>, i32 0 463 ret void 464 } 465 )IR"); 466 Function &LLVMF = *M->getFunction("foo"); 467 sandboxir::Context Ctx(C); 468 469 auto &F = *Ctx.createFunction(&LLVMF); 470 auto &BB = *F.begin(); 471 auto It = BB.begin(); 472 auto *I0 = &*It++; 473 auto *I1 = &*It++; 474 auto *I2 = &*It++; 475 // Check classof() and creation. 476 auto *Array = cast<sandboxir::ConstantArray>(I0->getOperand(0)); 477 EXPECT_TRUE(isa<sandboxir::ConstantAggregate>(Array)); 478 auto *Struct = cast<sandboxir::ConstantStruct>(I1->getOperand(0)); 479 EXPECT_TRUE(isa<sandboxir::ConstantAggregate>(Struct)); 480 auto *Vector = cast<sandboxir::ConstantVector>(I2->getOperand(0)); 481 EXPECT_TRUE(isa<sandboxir::ConstantAggregate>(Vector)); 482 483 auto *ZeroI42 = cast<sandboxir::ConstantInt>(Array->getOperand(0)); 484 auto *OneI42 = cast<sandboxir::ConstantInt>(Array->getOperand(1)); 485 // Check ConstantArray::get(), getType(). 486 auto *NewCA = 487 sandboxir::ConstantArray::get(Array->getType(), {ZeroI42, OneI42}); 488 EXPECT_EQ(NewCA, Array); 489 490 // Check ConstantStruct::get(), getType(). 491 auto *NewCS = 492 sandboxir::ConstantStruct::get(Struct->getType(), {ZeroI42, OneI42}); 493 EXPECT_EQ(NewCS, Struct); 494 // Check ConstantStruct::get(...). 495 auto *NewCS2 = 496 sandboxir::ConstantStruct::get(Struct->getType(), ZeroI42, OneI42); 497 EXPECT_EQ(NewCS2, Struct); 498 // Check ConstantStruct::getAnon(ArayRef). 499 auto *AnonCS = sandboxir::ConstantStruct::getAnon({ZeroI42, OneI42}); 500 EXPECT_FALSE(cast<sandboxir::StructType>(AnonCS->getType())->isPacked()); 501 auto *AnonCSPacked = 502 sandboxir::ConstantStruct::getAnon({ZeroI42, OneI42}, /*Packed=*/true); 503 EXPECT_TRUE(cast<sandboxir::StructType>(AnonCSPacked->getType())->isPacked()); 504 // Check ConstantStruct::getAnon(Ctx, ArrayRef). 505 auto *AnonCS2 = sandboxir::ConstantStruct::getAnon(Ctx, {ZeroI42, OneI42}); 506 EXPECT_EQ(AnonCS2, AnonCS); 507 auto *AnonCS2Packed = sandboxir::ConstantStruct::getAnon( 508 Ctx, {ZeroI42, OneI42}, /*Packed=*/true); 509 EXPECT_EQ(AnonCS2Packed, AnonCSPacked); 510 // Check ConstantStruct::getTypeForElements(Ctx, ArrayRef). 511 auto *StructTy = 512 sandboxir::ConstantStruct::getTypeForElements(Ctx, {ZeroI42, OneI42}); 513 EXPECT_EQ(StructTy, Struct->getType()); 514 EXPECT_FALSE(StructTy->isPacked()); 515 // Check ConstantStruct::getTypeForElements(Ctx, ArrayRef, Packed). 516 auto *StructTyPacked = sandboxir::ConstantStruct::getTypeForElements( 517 Ctx, {ZeroI42, OneI42}, /*Packed=*/true); 518 EXPECT_TRUE(StructTyPacked->isPacked()); 519 // Check ConstantStruct::getTypeForElements(ArrayRef). 520 auto *StructTy2 = 521 sandboxir::ConstantStruct::getTypeForElements(Ctx, {ZeroI42, OneI42}); 522 EXPECT_EQ(StructTy2, Struct->getType()); 523 // Check ConstantStruct::getTypeForElements(ArrayRef, Packed). 524 auto *StructTy2Packed = sandboxir::ConstantStruct::getTypeForElements( 525 Ctx, {ZeroI42, OneI42}, /*Packed=*/true); 526 EXPECT_EQ(StructTy2Packed, StructTyPacked); 527 } 528 529 TEST_F(SandboxIRTest, ConstantAggregateZero) { 530 parseIR(C, R"IR( 531 define void @foo(ptr %ptr, {i32, i8} %v1, <2 x i8> %v2) { 532 %extr0 = extractvalue [2 x i8] zeroinitializer, 0 533 %extr1 = extractvalue {i32, i8} zeroinitializer, 0 534 %extr2 = extractelement <2 x i8> zeroinitializer, i32 0 535 ret void 536 } 537 )IR"); 538 Function &LLVMF = *M->getFunction("foo"); 539 sandboxir::Context Ctx(C); 540 541 auto &F = *Ctx.createFunction(&LLVMF); 542 auto &BB = *F.begin(); 543 auto It = BB.begin(); 544 auto *Extr0 = &*It++; 545 auto *Extr1 = &*It++; 546 auto *Extr2 = &*It++; 547 [[maybe_unused]] auto *Ret = cast<sandboxir::ReturnInst>(&*It++); 548 auto *Zero32 = 549 sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 0); 550 auto *Zero8 = sandboxir::ConstantInt::get(sandboxir::Type::getInt8Ty(Ctx), 0); 551 auto *Int8Ty = sandboxir::Type::getInt8Ty(Ctx); 552 auto *Int32Ty = sandboxir::Type::getInt32Ty(Ctx); 553 auto *ArrayTy = sandboxir::ArrayType::get(Int8Ty, 2u); 554 auto *StructTy = sandboxir::StructType::get(Ctx, {Int32Ty, Int8Ty}); 555 auto *VectorTy = 556 sandboxir::VectorType::get(Int8Ty, ElementCount::getFixed(2u)); 557 558 // Check creation and classof(). 559 auto *ArrayCAZ = cast<sandboxir::ConstantAggregateZero>(Extr0->getOperand(0)); 560 EXPECT_EQ(ArrayCAZ->getType(), ArrayTy); 561 auto *StructCAZ = 562 cast<sandboxir::ConstantAggregateZero>(Extr1->getOperand(0)); 563 EXPECT_EQ(StructCAZ->getType(), StructTy); 564 auto *VectorCAZ = 565 cast<sandboxir::ConstantAggregateZero>(Extr2->getOperand(0)); 566 EXPECT_EQ(VectorCAZ->getType(), VectorTy); 567 // Check get(). 568 auto *SameVectorCAZ = 569 sandboxir::ConstantAggregateZero::get(sandboxir::VectorType::get( 570 sandboxir::Type::getInt8Ty(Ctx), ElementCount::getFixed(2))); 571 EXPECT_EQ(SameVectorCAZ, VectorCAZ); // Should be uniqued. 572 auto *NewVectorCAZ = 573 sandboxir::ConstantAggregateZero::get(sandboxir::VectorType::get( 574 sandboxir::Type::getInt8Ty(Ctx), ElementCount::getFixed(4))); 575 EXPECT_NE(NewVectorCAZ, VectorCAZ); 576 // Check getSequentialElement(). 577 auto *SeqElm = VectorCAZ->getSequentialElement(); 578 EXPECT_EQ(SeqElm, 579 sandboxir::ConstantInt::get(sandboxir::Type::getInt8Ty(Ctx), 0)); 580 // Check getStructElement(). 581 auto *StructElm0 = StructCAZ->getStructElement(0); 582 auto *StructElm1 = StructCAZ->getStructElement(1); 583 EXPECT_EQ(StructElm0, Zero32); 584 EXPECT_EQ(StructElm1, Zero8); 585 // Check getElementValue(Constant). 586 EXPECT_EQ(ArrayCAZ->getElementValue(Zero32), Zero8); 587 EXPECT_EQ(StructCAZ->getElementValue(Zero32), Zero32); 588 EXPECT_EQ(VectorCAZ->getElementValue(Zero32), Zero8); 589 // Check getElementValue(unsigned). 590 EXPECT_EQ(ArrayCAZ->getElementValue(0u), Zero8); 591 EXPECT_EQ(StructCAZ->getElementValue(0u), Zero32); 592 EXPECT_EQ(VectorCAZ->getElementValue(0u), Zero8); 593 // Check getElementCount(). 594 EXPECT_EQ(ArrayCAZ->getElementCount(), ElementCount::getFixed(2)); 595 EXPECT_EQ(NewVectorCAZ->getElementCount(), ElementCount::getFixed(4)); 596 } 597 598 TEST_F(SandboxIRTest, ConstantPointerNull) { 599 parseIR(C, R"IR( 600 define ptr @foo() { 601 ret ptr null 602 } 603 )IR"); 604 Function &LLVMF = *M->getFunction("foo"); 605 sandboxir::Context Ctx(C); 606 607 auto &F = *Ctx.createFunction(&LLVMF); 608 auto &BB = *F.begin(); 609 auto It = BB.begin(); 610 auto *Ret = cast<sandboxir::ReturnInst>(&*It++); 611 // Check classof() and creation. 612 auto *CPNull = cast<sandboxir::ConstantPointerNull>(Ret->getReturnValue()); 613 // Check get(). 614 auto *NewCPNull = 615 sandboxir::ConstantPointerNull::get(sandboxir::PointerType::get(Ctx, 0u)); 616 EXPECT_EQ(NewCPNull, CPNull); 617 auto *NewCPNull2 = 618 sandboxir::ConstantPointerNull::get(sandboxir::PointerType::get(Ctx, 1u)); 619 EXPECT_NE(NewCPNull2, CPNull); 620 // Check getType(). 621 EXPECT_EQ(CPNull->getType(), sandboxir::PointerType::get(Ctx, 0u)); 622 EXPECT_EQ(NewCPNull2->getType(), sandboxir::PointerType::get(Ctx, 1u)); 623 } 624 625 TEST_F(SandboxIRTest, PoisonValue) { 626 parseIR(C, R"IR( 627 define void @foo() { 628 %i0 = add i32 poison, poison 629 %i1 = add <2 x i32> poison, poison 630 %i2 = extractvalue {i32, i8} poison, 0 631 ret void 632 } 633 )IR"); 634 Function &LLVMF = *M->getFunction("foo"); 635 sandboxir::Context Ctx(C); 636 637 auto &F = *Ctx.createFunction(&LLVMF); 638 auto &BB = *F.begin(); 639 auto It = BB.begin(); 640 auto *I0 = &*It++; 641 auto *I1 = &*It++; 642 auto *I2 = &*It++; 643 auto *Int32Ty = sandboxir::Type::getInt32Ty(Ctx); 644 auto *Int8Ty = sandboxir::Type::getInt8Ty(Ctx); 645 auto *Zero32 = sandboxir::ConstantInt::get(Int32Ty, 0u); 646 auto *One32 = sandboxir::ConstantInt::get(Int32Ty, 1u); 647 648 // Check classof() and creation. 649 auto *Poison = cast<sandboxir::PoisonValue>(I0->getOperand(0)); 650 EXPECT_EQ(Poison->getType(), Int32Ty); 651 EXPECT_TRUE(isa<sandboxir::UndefValue>(Poison)); // Poison is Undef 652 // Check get(). 653 auto *NewPoison = sandboxir::PoisonValue::get(Int32Ty); 654 EXPECT_EQ(NewPoison, Poison); 655 auto *NewPoison2 = 656 sandboxir::PoisonValue::get(sandboxir::PointerType::get(Ctx, 0u)); 657 EXPECT_NE(NewPoison2, Poison); 658 // Check getSequentialElement(). 659 auto *PoisonVector = cast<sandboxir::PoisonValue>(I1->getOperand(0)); 660 auto *SeqElm = PoisonVector->getSequentialElement(); 661 EXPECT_EQ(SeqElm->getType(), Int32Ty); 662 // Check getStructElement(). 663 auto *PoisonStruct = cast<sandboxir::PoisonValue>(I2->getOperand(0)); 664 auto *StrElm0 = PoisonStruct->getStructElement(0); 665 auto *StrElm1 = PoisonStruct->getStructElement(1); 666 EXPECT_EQ(StrElm0->getType(), Int32Ty); 667 EXPECT_EQ(StrElm1->getType(), Int8Ty); 668 // Check getElementValue(Constant) 669 EXPECT_EQ(PoisonStruct->getElementValue(Zero32), 670 sandboxir::PoisonValue::get(Int32Ty)); 671 EXPECT_EQ(PoisonStruct->getElementValue(One32), 672 sandboxir::PoisonValue::get(Int8Ty)); 673 // Check getElementValue(unsigned) 674 EXPECT_EQ(PoisonStruct->getElementValue(0u), 675 sandboxir::PoisonValue::get(Int32Ty)); 676 EXPECT_EQ(PoisonStruct->getElementValue(1u), 677 sandboxir::PoisonValue::get(Int8Ty)); 678 } 679 680 TEST_F(SandboxIRTest, UndefValue) { 681 parseIR(C, R"IR( 682 define void @foo() { 683 %i0 = add i32 undef, undef 684 %i1 = add <2 x i32> undef, undef 685 %i2 = extractvalue {i32, i8} undef, 0 686 ret void 687 } 688 )IR"); 689 Function &LLVMF = *M->getFunction("foo"); 690 sandboxir::Context Ctx(C); 691 692 auto &F = *Ctx.createFunction(&LLVMF); 693 auto &BB = *F.begin(); 694 auto It = BB.begin(); 695 auto *I0 = &*It++; 696 auto *I1 = &*It++; 697 auto *I2 = &*It++; 698 auto *Int32Ty = sandboxir::Type::getInt32Ty(Ctx); 699 auto *Int8Ty = sandboxir::Type::getInt8Ty(Ctx); 700 auto *Zero32 = sandboxir::ConstantInt::get(Int32Ty, 0u); 701 auto *One32 = sandboxir::ConstantInt::get(Int32Ty, 1u); 702 703 // Check classof() and creation. 704 auto *Undef = cast<sandboxir::UndefValue>(I0->getOperand(0)); 705 EXPECT_EQ(Undef->getType(), Int32Ty); 706 EXPECT_FALSE(isa<sandboxir::PoisonValue>(Undef)); // Undef is not Poison 707 // Check get(). 708 auto *NewUndef = sandboxir::UndefValue::get(Int32Ty); 709 EXPECT_EQ(NewUndef, Undef); 710 auto *NewUndef2 = 711 sandboxir::UndefValue::get(sandboxir::PointerType::get(Ctx, 0u)); 712 EXPECT_NE(NewUndef2, Undef); 713 // Check getSequentialElement(). 714 auto *UndefVector = cast<sandboxir::UndefValue>(I1->getOperand(0)); 715 auto *SeqElm = UndefVector->getSequentialElement(); 716 EXPECT_EQ(SeqElm->getType(), Int32Ty); 717 // Check getStructElement(). 718 auto *UndefStruct = cast<sandboxir::UndefValue>(I2->getOperand(0)); 719 auto *StrElm0 = UndefStruct->getStructElement(0); 720 auto *StrElm1 = UndefStruct->getStructElement(1); 721 EXPECT_EQ(StrElm0->getType(), Int32Ty); 722 EXPECT_EQ(StrElm1->getType(), Int8Ty); 723 // Check getElementValue(Constant) 724 EXPECT_EQ(UndefStruct->getElementValue(Zero32), 725 sandboxir::UndefValue::get(Int32Ty)); 726 EXPECT_EQ(UndefStruct->getElementValue(One32), 727 sandboxir::UndefValue::get(Int8Ty)); 728 // Check getElementValue(unsigned) 729 EXPECT_EQ(UndefStruct->getElementValue(0u), 730 sandboxir::UndefValue::get(Int32Ty)); 731 EXPECT_EQ(UndefStruct->getElementValue(1u), 732 sandboxir::UndefValue::get(Int8Ty)); 733 // Check getNumElements(). 734 EXPECT_EQ(UndefVector->getNumElements(), 2u); 735 EXPECT_EQ(UndefStruct->getNumElements(), 2u); 736 } 737 738 TEST_F(SandboxIRTest, GlobalValue) { 739 parseIR(C, R"IR( 740 declare external void @bar() 741 define void @foo() { 742 call void @bar() 743 ret void 744 } 745 )IR"); 746 Function &LLVMF = *M->getFunction("foo"); 747 auto *LLVMBB = &*LLVMF.begin(); 748 auto LLVMIt = LLVMBB->begin(); 749 auto *LLVMCall = cast<llvm::CallInst>(&*LLVMIt++); 750 auto *LLVMGV = cast<llvm::GlobalValue>(LLVMCall->getCalledOperand()); 751 sandboxir::Context Ctx(C); 752 753 auto &F = *Ctx.createFunction(&LLVMF); 754 auto *BB = &*F.begin(); 755 auto It = BB->begin(); 756 auto *Call = cast<sandboxir::CallInst>(&*It++); 757 [[maybe_unused]] auto *Ret = cast<sandboxir::ReturnInst>(&*It++); 758 759 // Check classof(), creation, getFunction(), getBasicBlock(). 760 auto *GV = cast<sandboxir::GlobalValue>(Call->getCalledOperand()); 761 // Check getAddressSpace(). 762 EXPECT_EQ(GV->getAddressSpace(), LLVMGV->getAddressSpace()); 763 // Check hasGlobalUnnamedAddr(). 764 EXPECT_EQ(GV->hasGlobalUnnamedAddr(), LLVMGV->hasGlobalUnnamedAddr()); 765 // Check hasAtLeastLocalUnnamedAddr(). 766 EXPECT_EQ(GV->hasAtLeastLocalUnnamedAddr(), 767 LLVMGV->hasAtLeastLocalUnnamedAddr()); 768 // Check getUnnamedAddr(). 769 EXPECT_EQ(GV->getUnnamedAddr(), LLVMGV->getUnnamedAddr()); 770 // Check setUnnamedAddr(). 771 auto OrigUnnamedAddr = GV->getUnnamedAddr(); 772 auto NewUnnamedAddr = sandboxir::GlobalValue::UnnamedAddr::Global; 773 EXPECT_NE(NewUnnamedAddr, OrigUnnamedAddr); 774 GV->setUnnamedAddr(NewUnnamedAddr); 775 EXPECT_EQ(GV->getUnnamedAddr(), NewUnnamedAddr); 776 GV->setUnnamedAddr(OrigUnnamedAddr); 777 EXPECT_EQ(GV->getUnnamedAddr(), OrigUnnamedAddr); 778 // Check getMinUnnamedAddr(). 779 EXPECT_EQ( 780 sandboxir::GlobalValue::getMinUnnamedAddr(OrigUnnamedAddr, 781 NewUnnamedAddr), 782 llvm::GlobalValue::getMinUnnamedAddr(OrigUnnamedAddr, NewUnnamedAddr)); 783 // Check hasComdat(). 784 EXPECT_EQ(GV->hasComdat(), LLVMGV->hasComdat()); 785 // Check getVisibility(). 786 EXPECT_EQ(GV->getVisibility(), LLVMGV->getVisibility()); 787 // Check hasDefaultVisibility(). 788 EXPECT_EQ(GV->hasDefaultVisibility(), LLVMGV->hasDefaultVisibility()); 789 // Check hasHiddenVisibility(). 790 EXPECT_EQ(GV->hasHiddenVisibility(), LLVMGV->hasHiddenVisibility()); 791 // Check hasProtectedVisibility(). 792 EXPECT_EQ(GV->hasProtectedVisibility(), LLVMGV->hasProtectedVisibility()); 793 // Check setVisibility(). 794 auto OrigVisibility = GV->getVisibility(); 795 auto NewVisibility = 796 sandboxir::GlobalValue::VisibilityTypes::ProtectedVisibility; 797 EXPECT_NE(NewVisibility, OrigVisibility); 798 GV->setVisibility(NewVisibility); 799 EXPECT_EQ(GV->getVisibility(), NewVisibility); 800 GV->setVisibility(OrigVisibility); 801 EXPECT_EQ(GV->getVisibility(), OrigVisibility); 802 } 803 804 TEST_F(SandboxIRTest, GlobalObject) { 805 parseIR(C, R"IR( 806 declare external void @bar() 807 define void @foo() { 808 call void @bar() 809 ret void 810 } 811 )IR"); 812 Function &LLVMF = *M->getFunction("foo"); 813 auto *LLVMBB = &*LLVMF.begin(); 814 auto LLVMIt = LLVMBB->begin(); 815 auto *LLVMCall = cast<llvm::CallInst>(&*LLVMIt++); 816 auto *LLVMGO = cast<llvm::GlobalObject>(LLVMCall->getCalledOperand()); 817 sandboxir::Context Ctx(C); 818 819 auto &F = *Ctx.createFunction(&LLVMF); 820 auto *BB = &*F.begin(); 821 auto It = BB->begin(); 822 auto *Call = cast<sandboxir::CallInst>(&*It++); 823 // Check classof(), creation. 824 auto *GO = cast<sandboxir::GlobalObject>(Call->getCalledOperand()); 825 // Check getAlignment(). 826 EXPECT_EQ(GO->getAlignment(), LLVMGO->getAlignment()); 827 // Check getAlign(). 828 EXPECT_EQ(GO->getAlign(), LLVMGO->getAlign()); 829 // Check setAlignment(). 830 auto OrigMaybeAlign = GO->getAlign(); 831 auto NewMaybeAlign = MaybeAlign(128); 832 EXPECT_NE(NewMaybeAlign, OrigMaybeAlign); 833 GO->setAlignment(NewMaybeAlign); 834 EXPECT_EQ(GO->getAlign(), NewMaybeAlign); 835 GO->setAlignment(OrigMaybeAlign); 836 EXPECT_EQ(GO->getAlign(), OrigMaybeAlign); 837 // Check getGlobalObjectSubClassData(). 838 EXPECT_EQ(GO->getGlobalObjectSubClassData(), 839 LLVMGO->getGlobalObjectSubClassData()); 840 // Check setGlobalObjectSubClassData(). 841 auto OrigGOSCD = GO->getGlobalObjectSubClassData(); 842 auto NewGOSCD = 1u; 843 EXPECT_NE(NewGOSCD, OrigGOSCD); 844 GO->setGlobalObjectSubClassData(NewGOSCD); 845 EXPECT_EQ(GO->getGlobalObjectSubClassData(), NewGOSCD); 846 GO->setGlobalObjectSubClassData(OrigGOSCD); 847 EXPECT_EQ(GO->getGlobalObjectSubClassData(), OrigGOSCD); 848 // Check hasSection(). 849 EXPECT_EQ(GO->hasSection(), LLVMGO->hasSection()); 850 // Check getSection(). 851 EXPECT_EQ(GO->getSection(), LLVMGO->getSection()); 852 // Check setSection(). 853 auto OrigSection = GO->getSection(); 854 auto NewSection = ".some_section"; 855 EXPECT_NE(NewSection, OrigSection); 856 GO->setSection(NewSection); 857 EXPECT_EQ(GO->getSection(), NewSection); 858 GO->setSection(OrigSection); 859 EXPECT_EQ(GO->getSection(), OrigSection); 860 // Check hasComdat(). 861 EXPECT_EQ(GO->hasComdat(), LLVMGO->hasComdat()); 862 // Check getVCallVisibility(). 863 EXPECT_EQ(GO->getVCallVisibility(), LLVMGO->getVCallVisibility()); 864 // Check canIncreaseAlignment(). 865 EXPECT_EQ(GO->canIncreaseAlignment(), LLVMGO->canIncreaseAlignment()); 866 } 867 868 TEST_F(SandboxIRTest, GlobalIFunc) { 869 parseIR(C, R"IR( 870 declare external void @bar() 871 @ifunc0 = ifunc void(), ptr @foo 872 @ifunc1 = ifunc void(), ptr @foo 873 define void @foo() { 874 call void @ifunc0() 875 call void @ifunc1() 876 call void @bar() 877 ret void 878 } 879 )IR"); 880 Function &LLVMF = *M->getFunction("foo"); 881 auto *LLVMBB = &*LLVMF.begin(); 882 auto LLVMIt = LLVMBB->begin(); 883 auto *LLVMCall0 = cast<llvm::CallInst>(&*LLVMIt++); 884 auto *LLVMIFunc0 = cast<llvm::GlobalIFunc>(LLVMCall0->getCalledOperand()); 885 886 sandboxir::Context Ctx(C); 887 888 auto &F = *Ctx.createFunction(&LLVMF); 889 auto *BB = &*F.begin(); 890 auto It = BB->begin(); 891 auto *Call0 = cast<sandboxir::CallInst>(&*It++); 892 auto *Call1 = cast<sandboxir::CallInst>(&*It++); 893 auto *CallBar = cast<sandboxir::CallInst>(&*It++); 894 // Check classof(), creation. 895 auto *IFunc0 = cast<sandboxir::GlobalIFunc>(Call0->getCalledOperand()); 896 auto *IFunc1 = cast<sandboxir::GlobalIFunc>(Call1->getCalledOperand()); 897 auto *Bar = cast<sandboxir::Function>(CallBar->getCalledOperand()); 898 899 // Check getIterator(). 900 { 901 auto It0 = IFunc0->getIterator(); 902 auto It1 = IFunc1->getIterator(); 903 EXPECT_EQ(&*It0, IFunc0); 904 EXPECT_EQ(&*It1, IFunc1); 905 EXPECT_EQ(std::next(It0), It1); 906 EXPECT_EQ(std::prev(It1), It0); 907 EXPECT_EQ(&*std::next(It0), IFunc1); 908 EXPECT_EQ(&*std::prev(It1), IFunc0); 909 } 910 // Check getReverseIterator(). 911 { 912 auto RevIt0 = IFunc0->getReverseIterator(); 913 auto RevIt1 = IFunc1->getReverseIterator(); 914 EXPECT_EQ(&*RevIt0, IFunc0); 915 EXPECT_EQ(&*RevIt1, IFunc1); 916 EXPECT_EQ(std::prev(RevIt0), RevIt1); 917 EXPECT_EQ(std::next(RevIt1), RevIt0); 918 EXPECT_EQ(&*std::prev(RevIt0), IFunc1); 919 EXPECT_EQ(&*std::next(RevIt1), IFunc0); 920 } 921 922 // Check setResolver(), getResolver(). 923 EXPECT_EQ(IFunc0->getResolver(), Ctx.getValue(LLVMIFunc0->getResolver())); 924 auto *OrigResolver = IFunc0->getResolver(); 925 auto *NewResolver = Bar; 926 EXPECT_NE(NewResolver, OrigResolver); 927 IFunc0->setResolver(NewResolver); 928 EXPECT_EQ(IFunc0->getResolver(), NewResolver); 929 IFunc0->setResolver(OrigResolver); 930 EXPECT_EQ(IFunc0->getResolver(), OrigResolver); 931 // Check getResolverFunction(). 932 EXPECT_EQ(IFunc0->getResolverFunction(), 933 Ctx.getValue(LLVMIFunc0->getResolverFunction())); 934 // Check isValidLinkage(). 935 for (auto L : 936 {GlobalValue::ExternalLinkage, GlobalValue::AvailableExternallyLinkage, 937 GlobalValue::LinkOnceAnyLinkage, GlobalValue::LinkOnceODRLinkage, 938 GlobalValue::WeakAnyLinkage, GlobalValue::WeakODRLinkage, 939 GlobalValue::AppendingLinkage, GlobalValue::InternalLinkage, 940 GlobalValue::PrivateLinkage, GlobalValue::ExternalWeakLinkage, 941 GlobalValue::CommonLinkage}) { 942 EXPECT_EQ(IFunc0->isValidLinkage(L), LLVMIFunc0->isValidLinkage(L)); 943 } 944 } 945 946 TEST_F(SandboxIRTest, GlobalVariable) { 947 parseIR(C, R"IR( 948 @glob0 = global i32 42 949 @glob1 = global i32 43 950 define void @foo() { 951 %ld0 = load i32, ptr @glob0 952 %ld1 = load i32, ptr @glob1 953 ret void 954 } 955 )IR"); 956 Function &LLVMF = *M->getFunction("foo"); 957 auto *LLVMBB = &*LLVMF.begin(); 958 auto LLVMIt = LLVMBB->begin(); 959 auto *LLVMLd0 = cast<llvm::LoadInst>(&*LLVMIt++); 960 auto *LLVMGV0 = cast<llvm::GlobalVariable>(LLVMLd0->getPointerOperand()); 961 sandboxir::Context Ctx(C); 962 963 auto &F = *Ctx.createFunction(&LLVMF); 964 auto *BB = &*F.begin(); 965 auto It = BB->begin(); 966 auto *Ld0 = cast<sandboxir::LoadInst>(&*It++); 967 auto *Ld1 = cast<sandboxir::LoadInst>(&*It++); 968 // Check classof(), creation. 969 auto *GV0 = cast<sandboxir::GlobalVariable>(Ld0->getPointerOperand()); 970 auto *GV1 = cast<sandboxir::GlobalVariable>(Ld1->getPointerOperand()); 971 // Check getIterator(). 972 { 973 auto It0 = GV0->getIterator(); 974 auto It1 = GV1->getIterator(); 975 EXPECT_EQ(&*It0, GV0); 976 EXPECT_EQ(&*It1, GV1); 977 EXPECT_EQ(std::next(It0), It1); 978 EXPECT_EQ(std::prev(It1), It0); 979 EXPECT_EQ(&*std::next(It0), GV1); 980 EXPECT_EQ(&*std::prev(It1), GV0); 981 } 982 // Check getReverseIterator(). 983 { 984 auto RevIt0 = GV0->getReverseIterator(); 985 auto RevIt1 = GV1->getReverseIterator(); 986 EXPECT_EQ(&*RevIt0, GV0); 987 EXPECT_EQ(&*RevIt1, GV1); 988 EXPECT_EQ(std::prev(RevIt0), RevIt1); 989 EXPECT_EQ(std::next(RevIt1), RevIt0); 990 EXPECT_EQ(&*std::prev(RevIt0), GV1); 991 EXPECT_EQ(&*std::next(RevIt1), GV0); 992 } 993 // Check hasInitializer(). 994 EXPECT_EQ(GV0->hasInitializer(), LLVMGV0->hasInitializer()); 995 // Check hasDefinitiveInitializer(). 996 EXPECT_EQ(GV0->hasDefinitiveInitializer(), 997 LLVMGV0->hasDefinitiveInitializer()); 998 // Check hasUniqueInitializer(). 999 EXPECT_EQ(GV0->hasUniqueInitializer(), LLVMGV0->hasUniqueInitializer()); 1000 // Check getInitializer(). 1001 EXPECT_EQ(GV0->getInitializer(), Ctx.getValue(LLVMGV0->getInitializer())); 1002 // Check setInitializer(). 1003 auto *OrigInitializer = GV0->getInitializer(); 1004 auto *NewInitializer = GV1->getInitializer(); 1005 EXPECT_NE(NewInitializer, OrigInitializer); 1006 GV0->setInitializer(NewInitializer); 1007 EXPECT_EQ(GV0->getInitializer(), NewInitializer); 1008 GV0->setInitializer(OrigInitializer); 1009 EXPECT_EQ(GV0->getInitializer(), OrigInitializer); 1010 // Check isConstant(). 1011 EXPECT_EQ(GV0->isConstant(), LLVMGV0->isConstant()); 1012 // Check setConstant(). 1013 bool OrigIsConstant = GV0->isConstant(); 1014 bool NewIsConstant = !OrigIsConstant; 1015 GV0->setConstant(NewIsConstant); 1016 EXPECT_EQ(GV0->isConstant(), NewIsConstant); 1017 GV0->setConstant(OrigIsConstant); 1018 EXPECT_EQ(GV0->isConstant(), OrigIsConstant); 1019 // Check isExternallyInitialized(). 1020 EXPECT_EQ(GV0->isExternallyInitialized(), LLVMGV0->isExternallyInitialized()); 1021 // Check setExternallyInitialized(). 1022 bool OrigIsExtInit = GV0->isExternallyInitialized(); 1023 bool NewIsExtInit = !OrigIsExtInit; 1024 GV0->setExternallyInitialized(NewIsExtInit); 1025 EXPECT_EQ(GV0->isExternallyInitialized(), NewIsExtInit); 1026 GV0->setExternallyInitialized(OrigIsExtInit); 1027 EXPECT_EQ(GV0->isExternallyInitialized(), OrigIsExtInit); 1028 for (auto KindIdx : seq<int>(0, Attribute::AttrKind::EndAttrKinds)) { 1029 // Check hasAttribute(AttrKind). 1030 auto Kind = static_cast<Attribute::AttrKind>(KindIdx); 1031 EXPECT_EQ(GV0->hasAttribute(Kind), LLVMGV0->hasAttribute(Kind)); 1032 // Check hasAttribute(StringRef). 1033 StringRef KindStr = Attribute::getNameFromAttrKind(Kind); 1034 EXPECT_EQ(GV0->hasAttribute(KindStr), LLVMGV0->hasAttribute(KindStr)); 1035 } 1036 // Check hasAttributes(). 1037 EXPECT_EQ(GV0->hasAttributes(), LLVMGV0->hasAttributes()); 1038 1039 for (auto KindIdx : seq<int>(0, Attribute::AttrKind::EndAttrKinds)) { 1040 // Check getAttribute(AttrKind). 1041 auto Kind = static_cast<Attribute::AttrKind>(KindIdx); 1042 EXPECT_EQ(GV0->getAttribute(Kind), LLVMGV0->getAttribute(Kind)); 1043 // Check getAttribute(StringRef). 1044 StringRef KindStr = Attribute::getNameFromAttrKind(Kind); 1045 EXPECT_EQ(GV0->getAttribute(KindStr), LLVMGV0->getAttribute(KindStr)); 1046 } 1047 // Check getAttributes(). 1048 EXPECT_EQ(GV0->getAttributes(), LLVMGV0->getAttributes()); 1049 // Check getAttributesAsList(). 1050 EXPECT_THAT(GV0->getAttributesAsList(0u), 1051 testing::ContainerEq(LLVMGV0->getAttributesAsList(0u))); 1052 // Check hasImplicitSection(). 1053 EXPECT_EQ(GV0->hasImplicitSection(), LLVMGV0->hasImplicitSection()); 1054 // Check getCodeModelRaw(). 1055 EXPECT_EQ(GV0->getCodeModelRaw(), LLVMGV0->getCodeModelRaw()); 1056 // Check getCodeModel(). 1057 EXPECT_EQ(GV0->getCodeModel(), LLVMGV0->getCodeModel()); 1058 } 1059 1060 TEST_F(SandboxIRTest, GlobalAlias) { 1061 parseIR(C, R"IR( 1062 @alias0 = dso_local alias void(), ptr @foo 1063 @alias1 = dso_local alias void(), ptr @foo 1064 declare void @bar(); 1065 define void @foo() { 1066 call void @alias0() 1067 call void @alias1() 1068 call void @bar() 1069 ret void 1070 } 1071 )IR"); 1072 Function &LLVMF = *M->getFunction("foo"); 1073 auto *LLVMBB = &*LLVMF.begin(); 1074 auto LLVMIt = LLVMBB->begin(); 1075 auto *LLVMCall0 = cast<llvm::CallInst>(&*LLVMIt++); 1076 auto *LLVMAlias0 = cast<llvm::GlobalAlias>(LLVMCall0->getCalledOperand()); 1077 sandboxir::Context Ctx(C); 1078 1079 auto &F = *Ctx.createFunction(&LLVMF); 1080 auto *BB = &*F.begin(); 1081 auto It = BB->begin(); 1082 auto *Call0 = cast<sandboxir::CallInst>(&*It++); 1083 auto *Call1 = cast<sandboxir::CallInst>(&*It++); 1084 auto *CallBar = cast<sandboxir::CallInst>(&*It++); 1085 auto *CalleeBar = cast<sandboxir::Constant>(CallBar->getCalledOperand()); 1086 // Check classof(), creation. 1087 auto *Alias0 = cast<sandboxir::GlobalAlias>(Call0->getCalledOperand()); 1088 auto *Alias1 = cast<sandboxir::GlobalAlias>(Call1->getCalledOperand()); 1089 // Check getIterator(). 1090 { 1091 auto It0 = Alias0->getIterator(); 1092 auto It1 = Alias1->getIterator(); 1093 EXPECT_EQ(&*It0, Alias0); 1094 EXPECT_EQ(&*It1, Alias1); 1095 EXPECT_EQ(std::next(It0), It1); 1096 EXPECT_EQ(std::prev(It1), It0); 1097 EXPECT_EQ(&*std::next(It0), Alias1); 1098 EXPECT_EQ(&*std::prev(It1), Alias0); 1099 } 1100 // Check getReverseIterator(). 1101 { 1102 auto RevIt0 = Alias0->getReverseIterator(); 1103 auto RevIt1 = Alias1->getReverseIterator(); 1104 EXPECT_EQ(&*RevIt0, Alias0); 1105 EXPECT_EQ(&*RevIt1, Alias1); 1106 EXPECT_EQ(std::prev(RevIt0), RevIt1); 1107 EXPECT_EQ(std::next(RevIt1), RevIt0); 1108 EXPECT_EQ(&*std::prev(RevIt0), Alias1); 1109 EXPECT_EQ(&*std::next(RevIt1), Alias0); 1110 } 1111 // Check getAliasee(). 1112 EXPECT_EQ(Alias0->getAliasee(), Ctx.getValue(LLVMAlias0->getAliasee())); 1113 // Check setAliasee(). 1114 auto *OrigAliasee = Alias0->getAliasee(); 1115 auto *NewAliasee = CalleeBar; 1116 EXPECT_NE(NewAliasee, OrigAliasee); 1117 Alias0->setAliasee(NewAliasee); 1118 EXPECT_EQ(Alias0->getAliasee(), NewAliasee); 1119 Alias0->setAliasee(OrigAliasee); 1120 EXPECT_EQ(Alias0->getAliasee(), OrigAliasee); 1121 // Check getAliaseeObject(). 1122 EXPECT_EQ(Alias0->getAliaseeObject(), 1123 Ctx.getValue(LLVMAlias0->getAliaseeObject())); 1124 } 1125 1126 TEST_F(SandboxIRTest, NoCFIValue) { 1127 parseIR(C, R"IR( 1128 define void @foo() { 1129 call void no_cfi @foo() 1130 ret void 1131 } 1132 )IR"); 1133 Function &LLVMF = *M->getFunction("foo"); 1134 sandboxir::Context Ctx(C); 1135 1136 auto &F = *Ctx.createFunction(&LLVMF); 1137 auto *BB = &*F.begin(); 1138 auto It = BB->begin(); 1139 auto *Call = cast<sandboxir::CallInst>(&*It++); 1140 // Check classof(), creation. 1141 auto *NoCFI = cast<sandboxir::NoCFIValue>(Call->getCalledOperand()); 1142 // Check get(). 1143 auto *NewNoCFI = sandboxir::NoCFIValue::get(&F); 1144 EXPECT_EQ(NewNoCFI, NoCFI); 1145 // Check getGlobalValue(). 1146 EXPECT_EQ(NoCFI->getGlobalValue(), &F); 1147 // Check getType(). 1148 EXPECT_EQ(NoCFI->getType(), F.getType()); 1149 } 1150 1151 TEST_F(SandboxIRTest, ConstantPtrAuth) { 1152 parseIR(C, R"IR( 1153 define ptr @foo() { 1154 ret ptr ptrauth (ptr @foo, i32 2, i64 1234) 1155 } 1156 )IR"); 1157 Function &LLVMF = *M->getFunction("foo"); 1158 auto *LLVMBB = &*LLVMF.begin(); 1159 auto *LLVMRet = cast<llvm::ReturnInst>(&*LLVMBB->begin()); 1160 auto *LLVMPtrAuth = cast<llvm::ConstantPtrAuth>(LLVMRet->getReturnValue()); 1161 sandboxir::Context Ctx(C); 1162 1163 auto &F = *Ctx.createFunction(&LLVMF); 1164 auto *BB = &*F.begin(); 1165 auto It = BB->begin(); 1166 auto *Ret = cast<sandboxir::ReturnInst>(&*It++); 1167 // Check classof(), creation. 1168 auto *PtrAuth = cast<sandboxir::ConstantPtrAuth>(Ret->getReturnValue()); 1169 // Check get(), getKey(), getDiscriminator(), getAddrDiscriminator(). 1170 auto *NewPtrAuth = sandboxir::ConstantPtrAuth::get( 1171 &F, PtrAuth->getKey(), PtrAuth->getDiscriminator(), 1172 PtrAuth->getAddrDiscriminator()); 1173 EXPECT_EQ(NewPtrAuth, PtrAuth); 1174 // Check hasAddressDiscriminator(). 1175 EXPECT_EQ(PtrAuth->hasAddressDiscriminator(), 1176 LLVMPtrAuth->hasAddressDiscriminator()); 1177 // Check hasSpecialAddressDiscriminator(). 1178 EXPECT_EQ(PtrAuth->hasSpecialAddressDiscriminator(0u), 1179 LLVMPtrAuth->hasSpecialAddressDiscriminator(0u)); 1180 // Check isKnownCompatibleWith(). 1181 const DataLayout &DL = M->getDataLayout(); 1182 EXPECT_TRUE(PtrAuth->isKnownCompatibleWith(PtrAuth->getKey(), 1183 PtrAuth->getDiscriminator(), DL)); 1184 // Check getWithSameSchema(). 1185 EXPECT_EQ(PtrAuth->getWithSameSchema(&F), PtrAuth); 1186 } 1187 1188 TEST_F(SandboxIRTest, ConstantExpr) { 1189 parseIR(C, R"IR( 1190 define i32 @foo() { 1191 ret i32 ptrtoint (ptr @foo to i32) 1192 } 1193 )IR"); 1194 Function &LLVMF = *M->getFunction("foo"); 1195 sandboxir::Context Ctx(C); 1196 1197 auto &F = *Ctx.createFunction(&LLVMF); 1198 auto *BB = &*F.begin(); 1199 auto It = BB->begin(); 1200 auto *Ret = cast<sandboxir::ReturnInst>(&*It++); 1201 // Check classof(), creation. 1202 [[maybe_unused]] auto *ConstExpr = 1203 cast<sandboxir::ConstantExpr>(Ret->getReturnValue()); 1204 } 1205 1206 TEST_F(SandboxIRTest, BlockAddress) { 1207 parseIR(C, R"IR( 1208 define void @foo(ptr %ptr) { 1209 bb0: 1210 store ptr blockaddress(@foo, %bb0), ptr %ptr 1211 ret void 1212 bb1: 1213 ret void 1214 bb2: 1215 ret void 1216 } 1217 )IR"); 1218 Function &LLVMF = *M->getFunction("foo"); 1219 sandboxir::Context Ctx(C); 1220 1221 auto &F = *Ctx.createFunction(&LLVMF); 1222 auto *BB0 = cast<sandboxir::BasicBlock>( 1223 Ctx.getValue(getBasicBlockByName(LLVMF, "bb0"))); 1224 auto *BB1 = cast<sandboxir::BasicBlock>( 1225 Ctx.getValue(getBasicBlockByName(LLVMF, "bb1"))); 1226 auto *BB2 = cast<sandboxir::BasicBlock>( 1227 Ctx.getValue(getBasicBlockByName(LLVMF, "bb2"))); 1228 auto It = BB0->begin(); 1229 auto *SI = cast<sandboxir::StoreInst>(&*It++); 1230 [[maybe_unused]] auto *Ret = cast<sandboxir::ReturnInst>(&*It++); 1231 1232 // Check classof(), creation, getFunction(), getBasicBlock(). 1233 auto *BB0Addr = cast<sandboxir::BlockAddress>(SI->getValueOperand()); 1234 EXPECT_EQ(BB0Addr->getBasicBlock(), BB0); 1235 EXPECT_EQ(BB0Addr->getFunction(), &F); 1236 // Check get(F, BB). 1237 auto *NewBB0Addr = sandboxir::BlockAddress::get(&F, BB0); 1238 EXPECT_EQ(NewBB0Addr, BB0Addr); 1239 // Check get(BB). 1240 auto *NewBB0Addr2 = sandboxir::BlockAddress::get(BB0); 1241 EXPECT_EQ(NewBB0Addr2, BB0Addr); 1242 auto *BB1Addr = sandboxir::BlockAddress::get(BB1); 1243 EXPECT_EQ(BB1Addr->getBasicBlock(), BB1); 1244 EXPECT_NE(BB1Addr, BB0Addr); 1245 // Check lookup(). 1246 auto *LookupBB0Addr = sandboxir::BlockAddress::lookup(BB0); 1247 EXPECT_EQ(LookupBB0Addr, BB0Addr); 1248 auto *LookupBB1Addr = sandboxir::BlockAddress::lookup(BB1); 1249 EXPECT_EQ(LookupBB1Addr, BB1Addr); 1250 auto *LookupBB2Addr = sandboxir::BlockAddress::lookup(BB2); 1251 EXPECT_EQ(LookupBB2Addr, nullptr); 1252 } 1253 1254 TEST_F(SandboxIRTest, DSOLocalEquivalent) { 1255 parseIR(C, R"IR( 1256 declare void @bar() 1257 define void @foo() { 1258 call void dso_local_equivalent @bar() 1259 ret void 1260 } 1261 )IR"); 1262 Function &LLVMF = *M->getFunction("foo"); 1263 sandboxir::Context Ctx(C); 1264 1265 auto &F = *Ctx.createFunction(&LLVMF); 1266 auto *BB = &*F.begin(); 1267 auto It = BB->begin(); 1268 auto *CI = cast<sandboxir::CallInst>(&*It++); 1269 // Check classof(). 1270 auto *DSOLE = cast<sandboxir::DSOLocalEquivalent>(CI->getCalledOperand()); 1271 // Check getGlobalValue(). 1272 auto *GV = DSOLE->getGlobalValue(); 1273 // Check get(). 1274 auto *NewDSOLE = sandboxir::DSOLocalEquivalent::get(GV); 1275 EXPECT_EQ(NewDSOLE, DSOLE); 1276 } 1277 1278 TEST_F(SandboxIRTest, ConstantTokenNone) { 1279 parseIR(C, R"IR( 1280 define void @foo(ptr %ptr) { 1281 bb0: 1282 %cs = catchswitch within none [label %handler] unwind to caller 1283 handler: 1284 ret void 1285 } 1286 )IR"); 1287 Function &LLVMF = *M->getFunction("foo"); 1288 sandboxir::Context Ctx(C); 1289 1290 [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF); 1291 auto *BB0 = cast<sandboxir::BasicBlock>( 1292 Ctx.getValue(getBasicBlockByName(LLVMF, "bb0"))); 1293 auto *CS = cast<sandboxir::CatchSwitchInst>(&*BB0->begin()); 1294 1295 // Check classof(), creation, getFunction(), getBasicBlock(). 1296 auto *CTN = cast<sandboxir::ConstantTokenNone>(CS->getParentPad()); 1297 // Check get(). 1298 auto *NewCTN = sandboxir::ConstantTokenNone::get(Ctx); 1299 EXPECT_EQ(NewCTN, CTN); 1300 } 1301 1302 TEST_F(SandboxIRTest, Use) { 1303 parseIR(C, R"IR( 1304 define i32 @foo(i32 %v0, i32 %v1) { 1305 %add0 = add i32 %v0, %v1 1306 ret i32 %add0 1307 } 1308 )IR"); 1309 Function &LLVMF = *M->getFunction("foo"); 1310 sandboxir::Context Ctx(C); 1311 1312 BasicBlock *LLVMBB = &*LLVMF.begin(); 1313 auto LLVMBBIt = LLVMBB->begin(); 1314 Instruction *LLVMI0 = &*LLVMBBIt++; 1315 Instruction *LLVMRet = &*LLVMBBIt++; 1316 Argument *LLVMArg0 = LLVMF.getArg(0); 1317 Argument *LLVMArg1 = LLVMF.getArg(1); 1318 1319 auto &F = *Ctx.createFunction(&LLVMF); 1320 auto &BB = *F.begin(); 1321 auto *Arg0 = F.getArg(0); 1322 auto *Arg1 = F.getArg(1); 1323 auto It = BB.begin(); 1324 auto *I0 = &*It++; 1325 auto *Ret = cast<sandboxir::ReturnInst>(&*It++); 1326 1327 SmallVector<sandboxir::Argument *> Args{Arg0, Arg1}; 1328 unsigned OpIdx = 0; 1329 for (sandboxir::Use Use : I0->operands()) { 1330 // Check Use.getOperandNo(). 1331 EXPECT_EQ(Use.getOperandNo(), OpIdx); 1332 // Check Use.getUser(). 1333 EXPECT_EQ(Use.getUser(), I0); 1334 // Check Use.getContext(). 1335 EXPECT_EQ(Use.getContext(), &Ctx); 1336 // Check Use.get(). 1337 sandboxir::Value *Op = Use.get(); 1338 EXPECT_EQ(Op, Ctx.getValue(LLVMI0->getOperand(OpIdx))); 1339 // Check Use.getUser(). 1340 EXPECT_EQ(Use.getUser(), I0); 1341 // Check implicit cast to Value. 1342 sandboxir::Value *Cast = Use; 1343 EXPECT_EQ(Cast, Op); 1344 // Check that Use points to the correct operand. 1345 EXPECT_EQ(Op, Args[OpIdx]); 1346 // Check getOperand(). 1347 EXPECT_EQ(Op, I0->getOperand(OpIdx)); 1348 // Check getOperandUse(). 1349 EXPECT_EQ(Use, I0->getOperandUse(OpIdx)); 1350 ++OpIdx; 1351 } 1352 EXPECT_EQ(OpIdx, 2u); 1353 1354 // Check Use.operator==() and Use.operator!=(). 1355 sandboxir::Use UseA = I0->getOperandUse(0); 1356 sandboxir::Use UseB = I0->getOperandUse(0); 1357 EXPECT_TRUE(UseA == UseB); 1358 EXPECT_FALSE(UseA != UseB); 1359 1360 // Check getNumOperands(). 1361 EXPECT_EQ(I0->getNumOperands(), 2u); 1362 EXPECT_EQ(Ret->getNumOperands(), 1u); 1363 1364 EXPECT_EQ(Ret->getOperand(0), I0); 1365 1366 #ifndef NDEBUG 1367 // Check Use.dump(() 1368 std::string Buff; 1369 raw_string_ostream BS(Buff); 1370 BS << "\n"; 1371 I0->getOperandUse(0).dumpOS(BS); 1372 EXPECT_EQ(Buff, R"IR( 1373 Def: i32 %v0 ; SB2. (Argument) 1374 User: %add0 = add i32 %v0, %v1 ; SB5. (BinaryOperator) 1375 OperandNo: 0 1376 )IR"); 1377 #endif // NDEBUG 1378 1379 // Check Value.user_begin(). 1380 sandboxir::Value::user_iterator UIt = I0->user_begin(); 1381 sandboxir::User *U = *UIt; 1382 EXPECT_EQ(U, Ret); 1383 // Check Value.uses(). 1384 EXPECT_EQ(range_size(I0->uses()), 1u); 1385 EXPECT_EQ((*I0->uses().begin()).getUser(), Ret); 1386 // Check Value.users(). 1387 EXPECT_EQ(range_size(I0->users()), 1u); 1388 EXPECT_EQ(*I0->users().begin(), Ret); 1389 // Check Value.getNumUses(). 1390 EXPECT_EQ(I0->getNumUses(), 1u); 1391 // Check Value.hasNUsesOrMore(). 1392 EXPECT_TRUE(I0->hasNUsesOrMore(0u)); 1393 EXPECT_TRUE(I0->hasNUsesOrMore(1u)); 1394 EXPECT_FALSE(I0->hasNUsesOrMore(2u)); 1395 // Check Value.hasNUses(). 1396 EXPECT_FALSE(I0->hasNUses(0u)); 1397 EXPECT_TRUE(I0->hasNUses(1u)); 1398 EXPECT_FALSE(I0->hasNUses(2u)); 1399 1400 // Check Value.getExpectedType 1401 1402 // Check User.setOperand(). 1403 Ret->setOperand(0, Arg0); 1404 EXPECT_EQ(Ret->getOperand(0), Arg0); 1405 EXPECT_EQ(Ret->getOperandUse(0).get(), Arg0); 1406 EXPECT_EQ(LLVMRet->getOperand(0), LLVMArg0); 1407 1408 Ret->setOperand(0, Arg1); 1409 EXPECT_EQ(Ret->getOperand(0), Arg1); 1410 EXPECT_EQ(Ret->getOperandUse(0).get(), Arg1); 1411 EXPECT_EQ(LLVMRet->getOperand(0), LLVMArg1); 1412 } 1413 1414 TEST_F(SandboxIRTest, RUOW) { 1415 parseIR(C, R"IR( 1416 declare void @bar0() 1417 declare void @bar1() 1418 1419 @glob0 = global ptr @bar0 1420 @glob1 = global ptr @bar1 1421 1422 define i32 @foo(i32 %arg0, i32 %arg1) { 1423 %add0 = add i32 %arg0, %arg1 1424 %gep1 = getelementptr i8, ptr @glob0, i32 1 1425 %gep2 = getelementptr i8, ptr @glob1, i32 1 1426 ret i32 %add0 1427 } 1428 )IR"); 1429 llvm::Function &LLVMF = *M->getFunction("foo"); 1430 sandboxir::Context Ctx(C); 1431 1432 auto &F = *Ctx.createFunction(&LLVMF); 1433 auto &BB = *F.begin(); 1434 auto *Arg0 = F.getArg(0); 1435 auto *Arg1 = F.getArg(1); 1436 auto It = BB.begin(); 1437 auto *I0 = &*It++; 1438 auto *I1 = &*It++; 1439 auto *I2 = &*It++; 1440 auto *Ret = cast<sandboxir::ReturnInst>(&*It++); 1441 1442 bool Replaced; 1443 // Try to replace an operand that doesn't match. 1444 Replaced = I0->replaceUsesOfWith(Ret, Arg1); 1445 EXPECT_FALSE(Replaced); 1446 EXPECT_EQ(I0->getOperand(0), Arg0); 1447 EXPECT_EQ(I0->getOperand(1), Arg1); 1448 1449 // Replace I0 operands when operands differ. 1450 Replaced = I0->replaceUsesOfWith(Arg0, Arg1); 1451 EXPECT_TRUE(Replaced); 1452 EXPECT_EQ(I0->getOperand(0), Arg1); 1453 EXPECT_EQ(I0->getOperand(1), Arg1); 1454 1455 // Replace I0 operands when operands are the same. 1456 Replaced = I0->replaceUsesOfWith(Arg1, Arg0); 1457 EXPECT_TRUE(Replaced); 1458 EXPECT_EQ(I0->getOperand(0), Arg0); 1459 EXPECT_EQ(I0->getOperand(1), Arg0); 1460 1461 // Replace Ret operand. 1462 Replaced = Ret->replaceUsesOfWith(I0, Arg0); 1463 EXPECT_TRUE(Replaced); 1464 EXPECT_EQ(Ret->getOperand(0), Arg0); 1465 // Check RAUW on constant. 1466 auto *Glob0 = cast<sandboxir::Constant>(I1->getOperand(0)); 1467 auto *Glob1 = cast<sandboxir::Constant>(I2->getOperand(0)); 1468 auto *Glob0Op = Glob0->getOperand(0); 1469 Glob0->replaceUsesOfWith(Glob0Op, Glob1); 1470 EXPECT_EQ(Glob0->getOperand(0), Glob1); 1471 } 1472 1473 TEST_F(SandboxIRTest, GetExpected) { 1474 parseIR(C, R"IR( 1475 define float @foo(float %v, ptr %ptr) { 1476 %add = fadd float %v, %v 1477 store float %v, ptr %ptr 1478 ret float %v 1479 } 1480 define void @bar(float %v, ptr %ptr) { 1481 ret void 1482 } 1483 )IR"); 1484 llvm::Function &Foo = *M->getFunction("foo"); 1485 sandboxir::Context Ctx(C); 1486 1487 Ctx.createFunction(&Foo); 1488 auto *FooBB = cast<sandboxir::BasicBlock>(Ctx.getValue(&*Foo.begin())); 1489 auto FooIt = FooBB->begin(); 1490 auto Add = cast<sandboxir::Instruction>(&*FooIt++); 1491 auto *S0 = cast<sandboxir::Instruction>(&*FooIt++); 1492 auto *RetF = cast<sandboxir::Instruction>(&*FooIt++); 1493 // getExpectedValue 1494 EXPECT_EQ(sandboxir::Utils::getExpectedValue(Add), Add); 1495 EXPECT_EQ(sandboxir::Utils::getExpectedValue(S0), 1496 cast<sandboxir::StoreInst>(S0)->getValueOperand()); 1497 EXPECT_EQ(sandboxir::Utils::getExpectedValue(RetF), 1498 cast<sandboxir::ReturnInst>(RetF)->getReturnValue()); 1499 // getExpectedType 1500 EXPECT_EQ(sandboxir::Utils::getExpectedType(Add), Add->getType()); 1501 EXPECT_EQ(sandboxir::Utils::getExpectedType(S0), 1502 cast<sandboxir::StoreInst>(S0)->getValueOperand()->getType()); 1503 EXPECT_EQ(sandboxir::Utils::getExpectedType(RetF), 1504 cast<sandboxir::ReturnInst>(RetF)->getReturnValue()->getType()); 1505 1506 // getExpectedValue for void returns 1507 llvm::Function &Bar = *M->getFunction("bar"); 1508 Ctx.createFunction(&Bar); 1509 auto *BarBB = cast<sandboxir::BasicBlock>(Ctx.getValue(&*Bar.begin())); 1510 auto BarIt = BarBB->begin(); 1511 auto *RetV = cast<sandboxir::Instruction>(&*BarIt++); 1512 EXPECT_EQ(sandboxir::Utils::getExpectedValue(RetV), nullptr); 1513 } 1514 1515 TEST_F(SandboxIRTest, GetNumBits) { 1516 parseIR(C, R"IR( 1517 define void @foo(float %arg0, double %arg1, i8 %arg2, i64 %arg3) { 1518 bb0: 1519 ret void 1520 } 1521 )IR"); 1522 llvm::Function &Foo = *M->getFunction("foo"); 1523 sandboxir::Context Ctx(C); 1524 sandboxir::Function *F = Ctx.createFunction(&Foo); 1525 const DataLayout &DL = M->getDataLayout(); 1526 // getNumBits for scalars 1527 EXPECT_EQ(sandboxir::Utils::getNumBits(F->getArg(0), DL), 1528 DL.getTypeSizeInBits(Type::getFloatTy(C))); 1529 EXPECT_EQ(sandboxir::Utils::getNumBits(F->getArg(1), DL), 1530 DL.getTypeSizeInBits(Type::getDoubleTy(C))); 1531 EXPECT_EQ(sandboxir::Utils::getNumBits(F->getArg(2), DL), 8u); 1532 EXPECT_EQ(sandboxir::Utils::getNumBits(F->getArg(3), DL), 64u); 1533 } 1534 1535 TEST_F(SandboxIRTest, RAUW_RUWIf) { 1536 parseIR(C, R"IR( 1537 define void @foo(ptr %ptr) { 1538 %ld0 = load float, ptr %ptr 1539 %ld1 = load float, ptr %ptr 1540 store float %ld0, ptr %ptr 1541 store float %ld0, ptr %ptr 1542 ret void 1543 } 1544 )IR"); 1545 llvm::Function &LLVMF = *M->getFunction("foo"); 1546 sandboxir::Context Ctx(C); 1547 llvm::BasicBlock *LLVMBB = &*LLVMF.begin(); 1548 1549 Ctx.createFunction(&LLVMF); 1550 auto *BB = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB)); 1551 auto It = BB->begin(); 1552 sandboxir::Instruction *Ld0 = &*It++; 1553 sandboxir::Instruction *Ld1 = &*It++; 1554 sandboxir::Instruction *St0 = &*It++; 1555 sandboxir::Instruction *St1 = &*It++; 1556 // Check RUWIf when the lambda returns false. 1557 Ld0->replaceUsesWithIf(Ld1, [](const sandboxir::Use &Use) { return false; }); 1558 EXPECT_EQ(St0->getOperand(0), Ld0); 1559 EXPECT_EQ(St1->getOperand(0), Ld0); 1560 // Check RUWIf when the lambda returns true. 1561 Ld0->replaceUsesWithIf(Ld1, [](const sandboxir::Use &Use) { return true; }); 1562 EXPECT_EQ(St0->getOperand(0), Ld1); 1563 EXPECT_EQ(St1->getOperand(0), Ld1); 1564 St0->setOperand(0, Ld0); 1565 St1->setOperand(0, Ld0); 1566 // Check RUWIf user == St0. 1567 Ld0->replaceUsesWithIf( 1568 Ld1, [St0](const sandboxir::Use &Use) { return Use.getUser() == St0; }); 1569 EXPECT_EQ(St0->getOperand(0), Ld1); 1570 EXPECT_EQ(St1->getOperand(0), Ld0); 1571 St0->setOperand(0, Ld0); 1572 // Check RUWIf user == St1. 1573 Ld0->replaceUsesWithIf( 1574 Ld1, [St1](const sandboxir::Use &Use) { return Use.getUser() == St1; }); 1575 EXPECT_EQ(St0->getOperand(0), Ld0); 1576 EXPECT_EQ(St1->getOperand(0), Ld1); 1577 St1->setOperand(0, Ld0); 1578 // Check RAUW. 1579 Ld1->replaceAllUsesWith(Ld0); 1580 EXPECT_EQ(St0->getOperand(0), Ld0); 1581 EXPECT_EQ(St1->getOperand(0), Ld0); 1582 } 1583 1584 // Check that the operands/users are counted correctly. 1585 // I1 1586 // / \ 1587 // \ / 1588 // I2 1589 TEST_F(SandboxIRTest, DuplicateUses) { 1590 parseIR(C, R"IR( 1591 define void @foo(i8 %v) { 1592 %I1 = add i8 %v, %v 1593 %I2 = add i8 %I1, %I1 1594 ret void 1595 } 1596 )IR"); 1597 Function &LLVMF = *M->getFunction("foo"); 1598 sandboxir::Context Ctx(C); 1599 auto *F = Ctx.createFunction(&LLVMF); 1600 auto *BB = &*F->begin(); 1601 auto It = BB->begin(); 1602 auto *I1 = &*It++; 1603 auto *I2 = &*It++; 1604 EXPECT_EQ(range_size(I1->users()), 2u); 1605 EXPECT_EQ(range_size(I2->operands()), 2u); 1606 } 1607 1608 TEST_F(SandboxIRTest, Function) { 1609 parseIR(C, R"IR( 1610 define void @foo0(i32 %arg0, i32 %arg1) { 1611 bb0: 1612 br label %bb1 1613 bb1: 1614 ret void 1615 } 1616 define void @foo1() { 1617 ret void 1618 } 1619 1620 )IR"); 1621 llvm::Function *LLVMF0 = &*M->getFunction("foo0"); 1622 llvm::Function *LLVMF1 = &*M->getFunction("foo1"); 1623 llvm::Argument *LLVMArg0 = LLVMF0->getArg(0); 1624 llvm::Argument *LLVMArg1 = LLVMF0->getArg(1); 1625 1626 sandboxir::Context Ctx(C); 1627 sandboxir::Function *F0 = Ctx.createFunction(LLVMF0); 1628 sandboxir::Function *F1 = Ctx.createFunction(LLVMF1); 1629 1630 // Check getIterator(). 1631 { 1632 auto It0 = F0->getIterator(); 1633 auto It1 = F1->getIterator(); 1634 EXPECT_EQ(&*It0, F0); 1635 EXPECT_EQ(&*It1, F1); 1636 EXPECT_EQ(std::next(It0), It1); 1637 EXPECT_EQ(std::prev(It1), It0); 1638 EXPECT_EQ(&*std::next(It0), F1); 1639 EXPECT_EQ(&*std::prev(It1), F0); 1640 } 1641 // Check getReverseIterator(). 1642 { 1643 auto RevIt0 = F0->getReverseIterator(); 1644 auto RevIt1 = F1->getReverseIterator(); 1645 EXPECT_EQ(&*RevIt0, F0); 1646 EXPECT_EQ(&*RevIt1, F1); 1647 EXPECT_EQ(std::prev(RevIt0), RevIt1); 1648 EXPECT_EQ(std::next(RevIt1), RevIt0); 1649 EXPECT_EQ(&*std::prev(RevIt0), F1); 1650 EXPECT_EQ(&*std::next(RevIt1), F0); 1651 } 1652 1653 // Check F arguments 1654 EXPECT_EQ(F0->arg_size(), 2u); 1655 EXPECT_FALSE(F0->arg_empty()); 1656 EXPECT_EQ(F0->getArg(0), Ctx.getValue(LLVMArg0)); 1657 EXPECT_EQ(F0->getArg(1), Ctx.getValue(LLVMArg1)); 1658 1659 // Check F.begin(), F.end(), Function::iterator 1660 llvm::BasicBlock *LLVMBB = &*LLVMF0->begin(); 1661 for (sandboxir::BasicBlock &BB : *F0) { 1662 EXPECT_EQ(&BB, Ctx.getValue(LLVMBB)); 1663 LLVMBB = LLVMBB->getNextNode(); 1664 } 1665 1666 #ifndef NDEBUG 1667 { 1668 // Check F.dumpNameAndArgs() 1669 std::string Buff; 1670 raw_string_ostream BS(Buff); 1671 F0->dumpNameAndArgs(BS); 1672 EXPECT_EQ(Buff, "void @foo0(i32 %arg0, i32 %arg1)"); 1673 } 1674 { 1675 // Check F.dump() 1676 std::string Buff; 1677 raw_string_ostream BS(Buff); 1678 BS << "\n"; 1679 F0->dumpOS(BS); 1680 EXPECT_EQ(Buff, R"IR( 1681 void @foo0(i32 %arg0, i32 %arg1) { 1682 bb0: 1683 br label %bb1 ; SB4. (Br) 1684 1685 bb1: 1686 ret void ; SB6. (Ret) 1687 } 1688 )IR"); 1689 } 1690 #endif // NDEBUG 1691 } 1692 1693 TEST_F(SandboxIRTest, Module) { 1694 parseIR(C, R"IR( 1695 @glob0 = global i32 42 1696 @glob1 = global i32 43 1697 @internal0 = internal global i32 42 1698 @const0 = constant i32 42 1699 @alias0 = dso_local alias void(), ptr @foo 1700 @ifunc = ifunc void(), ptr @foo 1701 define void @foo() { 1702 ret void 1703 } 1704 define void @bar() { 1705 ret void 1706 } 1707 )IR"); 1708 llvm::Module *LLVMM = &*M; 1709 llvm::Function *LLVMFFoo = &*M->getFunction("foo"); 1710 llvm::Function *LLVMFBar = &*M->getFunction("bar"); 1711 1712 sandboxir::Context Ctx(C); 1713 auto *M = Ctx.createModule(LLVMM); 1714 // Check getContext(). 1715 EXPECT_EQ(&M->getContext(), &Ctx); 1716 // Check getFunction(). 1717 auto *FFoo = M->getFunction("foo"); 1718 auto *FBar = M->getFunction("bar"); 1719 EXPECT_EQ(FFoo, Ctx.getValue(LLVMFFoo)); 1720 EXPECT_EQ(FBar, Ctx.getValue(LLVMFBar)); 1721 // Check getDataLayout(). 1722 EXPECT_EQ(&M->getDataLayout(), &LLVMM->getDataLayout()); 1723 // Check getSourceFileName(). 1724 EXPECT_EQ(M->getSourceFileName(), LLVMM->getSourceFileName()); 1725 // Check getGlobalVariable(). 1726 for (const char *Name : {"global0", "global1", "internal0"}) 1727 EXPECT_EQ(M->getGlobalVariable(Name), 1728 Ctx.getValue(LLVMM->getGlobalVariable(Name))); 1729 // Check getGlobalVariable(AllowInternal). 1730 { 1731 auto *Internal0 = M->getGlobalVariable("internal0", /*AllowInternal=*/true); 1732 EXPECT_TRUE(Internal0 != nullptr); 1733 EXPECT_EQ(Internal0, Ctx.getValue(LLVMM->getNamedGlobal("internal0"))); 1734 } 1735 // Check getNamedGlobal(). 1736 { 1737 auto *Internal = M->getNamedGlobal("internal0"); 1738 EXPECT_TRUE(Internal != nullptr); 1739 EXPECT_EQ(Internal, Ctx.getValue(LLVMM->getNamedGlobal("internal0"))); 1740 } 1741 // Check getNamedAlias(). 1742 auto *Alias0 = M->getNamedAlias("alias0"); 1743 EXPECT_EQ(Alias0, Ctx.getValue(LLVMM->getNamedAlias("alias0"))); 1744 EXPECT_EQ(M->getNamedAlias("aliasFOO"), nullptr); 1745 // Check getNamedIFunc(). 1746 auto *IFunc0 = M->getNamedIFunc("ifunc0"); 1747 EXPECT_EQ(IFunc0, Ctx.getValue(LLVMM->getNamedAlias("ifunc0"))); 1748 EXPECT_EQ(M->getNamedIFunc("ifuncFOO"), nullptr); 1749 } 1750 1751 TEST_F(SandboxIRTest, BasicBlock) { 1752 parseIR(C, R"IR( 1753 define void @foo(i32 %v1) { 1754 bb0: 1755 br label %bb1 1756 bb1: 1757 ret void 1758 } 1759 )IR"); 1760 llvm::Function *LLVMF = &*M->getFunction("foo"); 1761 llvm::BasicBlock *LLVMBB0 = getBasicBlockByName(*LLVMF, "bb0"); 1762 llvm::BasicBlock *LLVMBB1 = getBasicBlockByName(*LLVMF, "bb1"); 1763 1764 sandboxir::Context Ctx(C); 1765 sandboxir::Function *F = Ctx.createFunction(LLVMF); 1766 auto &BB0 = cast<sandboxir::BasicBlock>(*Ctx.getValue(LLVMBB0)); 1767 auto &BB1 = cast<sandboxir::BasicBlock>(*Ctx.getValue(LLVMBB1)); 1768 1769 // Check BB::classof() 1770 EXPECT_TRUE(isa<sandboxir::Value>(BB0)); 1771 EXPECT_FALSE(isa<sandboxir::User>(BB0)); 1772 EXPECT_FALSE(isa<sandboxir::Instruction>(BB0)); 1773 EXPECT_FALSE(isa<sandboxir::Constant>(BB0)); 1774 EXPECT_FALSE(isa<sandboxir::Argument>(BB0)); 1775 1776 // Check BB.getParent() 1777 EXPECT_EQ(BB0.getParent(), F); 1778 EXPECT_EQ(BB1.getParent(), F); 1779 1780 // Check BBIterator, BB.begin(), BB.end(). 1781 llvm::Instruction *LLVMI = &*LLVMBB0->begin(); 1782 for (sandboxir::Instruction &I : BB0) { 1783 EXPECT_EQ(&I, Ctx.getValue(LLVMI)); 1784 LLVMI = LLVMI->getNextNode(); 1785 // Check getNodeParent(). 1786 EXPECT_EQ(I.getIterator().getNodeParent(), &BB0); 1787 } 1788 LLVMI = &*LLVMBB1->begin(); 1789 for (sandboxir::Instruction &I : BB1) { 1790 EXPECT_EQ(&I, Ctx.getValue(LLVMI)); 1791 LLVMI = LLVMI->getNextNode(); 1792 } 1793 // Check NodeParent() for BB::end(). 1794 EXPECT_EQ(BB0.end().getNodeParent(), &BB0); 1795 1796 // Check BB.getTerminator() 1797 EXPECT_EQ(BB0.getTerminator(), Ctx.getValue(LLVMBB0->getTerminator())); 1798 EXPECT_EQ(BB1.getTerminator(), Ctx.getValue(LLVMBB1->getTerminator())); 1799 1800 // Check BB.rbegin(), BB.rend() 1801 EXPECT_EQ(&*BB0.rbegin(), BB0.getTerminator()); 1802 EXPECT_EQ(&*std::prev(BB0.rend()), &*BB0.begin()); 1803 1804 #ifndef NDEBUG 1805 { 1806 // Check BB.dump() 1807 std::string Buff; 1808 raw_string_ostream BS(Buff); 1809 BS << "\n"; 1810 BB0.dumpOS(BS); 1811 EXPECT_EQ(Buff, R"IR( 1812 bb0: 1813 br label %bb1 ; SB3. (Br) 1814 )IR"); 1815 } 1816 #endif // NDEBUG 1817 } 1818 1819 TEST_F(SandboxIRTest, Instruction) { 1820 parseIR(C, R"IR( 1821 define void @foo(i8 %v1, ptr %ptr) { 1822 bb0: 1823 %add0 = add i8 %v1, %v1 1824 %sub1 = sub i8 %add0, %v1 1825 ret void 1826 1827 bb1: 1828 %add1 = add i8 %v1, %v1 1829 %sub2 = sub i8 %add1, %v1 1830 %ld0 = load i8, ptr %ptr 1831 store i8 %ld0, ptr %ptr 1832 store volatile i8 %ld0, ptr %ptr 1833 %atomicrmw = atomicrmw add ptr %ptr, i8 %v1 acquire 1834 %udiv = udiv i8 %ld0, %v1 1835 %urem = urem i8 %ld0, %v1 1836 call void @foo(), !dbg !1 1837 ret void, !tbaa !2 1838 } 1839 1840 !1 = !{} 1841 !2 = !{} 1842 )IR"); 1843 llvm::Function *LLVMF = &*M->getFunction("foo"); 1844 llvm::BasicBlock *LLVMBB1 = getBasicBlockByName(*LLVMF, "bb1"); 1845 sandboxir::Context Ctx(C); 1846 sandboxir::Function *F = Ctx.createFunction(LLVMF); 1847 auto *Arg = F->getArg(0); 1848 auto *BB = cast<sandboxir::BasicBlock>( 1849 Ctx.getValue(getBasicBlockByName(*LLVMF, "bb0"))); 1850 auto It = BB->begin(); 1851 auto *I0 = &*It++; 1852 auto *I1 = &*It++; 1853 auto *Ret = cast<sandboxir::ReturnInst>(&*It++); 1854 1855 // Check getPrevNode(). 1856 EXPECT_EQ(Ret->getPrevNode(), I1); 1857 EXPECT_EQ(I1->getPrevNode(), I0); 1858 EXPECT_EQ(I0->getPrevNode(), nullptr); 1859 1860 // Check getNextNode(). 1861 EXPECT_EQ(I0->getNextNode(), I1); 1862 EXPECT_EQ(I1->getNextNode(), Ret); 1863 EXPECT_EQ(Ret->getNextNode(), nullptr); 1864 1865 // Check getIterator(). 1866 EXPECT_EQ(I0->getIterator(), std::next(BB->begin(), 0)); 1867 EXPECT_EQ(I1->getIterator(), std::next(BB->begin(), 1)); 1868 EXPECT_EQ(Ret->getIterator(), std::next(BB->begin(), 2)); 1869 1870 // Check getOpcode(). 1871 EXPECT_EQ(I0->getOpcode(), sandboxir::Instruction::Opcode::Add); 1872 EXPECT_EQ(I1->getOpcode(), sandboxir::Instruction::Opcode::Sub); 1873 EXPECT_EQ(Ret->getOpcode(), sandboxir::Instruction::Opcode::Ret); 1874 1875 // Check getOpcodeName(). 1876 EXPECT_STREQ(I0->getOpcodeName(), "Add"); 1877 EXPECT_STREQ(I1->getOpcodeName(), "Sub"); 1878 EXPECT_STREQ(Ret->getOpcodeName(), "Ret"); 1879 1880 EXPECT_STREQ(sandboxir::Instruction::getOpcodeName( 1881 sandboxir::Instruction::Opcode::Alloca), 1882 "Alloca"); 1883 1884 // Check moveBefore(I). 1885 I1->moveBefore(I0); 1886 EXPECT_EQ(I0->getPrevNode(), I1); 1887 EXPECT_EQ(I1->getNextNode(), I0); 1888 1889 // Check moveAfter(I). 1890 I1->moveAfter(I0); 1891 EXPECT_EQ(I0->getNextNode(), I1); 1892 EXPECT_EQ(I1->getPrevNode(), I0); 1893 1894 // Check comesBefore(I). 1895 EXPECT_TRUE(I0->comesBefore(I1)); 1896 EXPECT_FALSE(I1->comesBefore(I0)); 1897 1898 // Check moveBefore(BB, It). 1899 I1->moveBefore(*BB, BB->begin()); 1900 EXPECT_EQ(I1->getPrevNode(), nullptr); 1901 EXPECT_EQ(I1->getNextNode(), I0); 1902 I1->moveBefore(*BB, BB->end()); 1903 EXPECT_EQ(I1->getNextNode(), nullptr); 1904 EXPECT_EQ(Ret->getNextNode(), I1); 1905 I1->moveBefore(*BB, std::next(BB->begin())); 1906 EXPECT_EQ(I0->getNextNode(), I1); 1907 EXPECT_EQ(I1->getNextNode(), Ret); 1908 1909 // Check removeFromParent(). 1910 I0->removeFromParent(); 1911 #ifndef NDEBUG 1912 EXPECT_DEATH(I0->getPrevNode(), ".*Detached.*"); 1913 EXPECT_DEATH(I0->getNextNode(), ".*Detached.*"); 1914 #endif // NDEBUG 1915 EXPECT_EQ(I0->getParent(), nullptr); 1916 EXPECT_EQ(I1->getPrevNode(), nullptr); 1917 EXPECT_EQ(I0->getOperand(0), Arg); 1918 1919 // Check insertBefore(). 1920 I0->insertBefore(I1); 1921 EXPECT_EQ(I1->getPrevNode(), I0); 1922 1923 // Check insertInto(). 1924 I0->removeFromParent(); 1925 I0->insertInto(BB, BB->end()); 1926 EXPECT_EQ(Ret->getNextNode(), I0); 1927 I0->moveBefore(I1); 1928 EXPECT_EQ(I0->getNextNode(), I1); 1929 1930 // Check eraseFromParent(). 1931 #ifndef NDEBUG 1932 EXPECT_DEATH(I0->eraseFromParent(), "Still connected to users.*"); 1933 #endif 1934 I1->eraseFromParent(); 1935 EXPECT_EQ(I0->getNumUses(), 0u); 1936 EXPECT_EQ(I0->getNextNode(), Ret); 1937 1938 for (auto &LLVMI : *LLVMBB1) { 1939 auto &I = cast<sandboxir::Instruction>(*Ctx.getValue(&LLVMI)); 1940 // Check isTerminator(). 1941 EXPECT_EQ(LLVMI.isTerminator(), I.isTerminator()); 1942 // Check isUnaryOp(). 1943 EXPECT_EQ(LLVMI.isUnaryOp(), I.isUnaryOp()); 1944 // Check isBinaryOp(). 1945 EXPECT_EQ(LLVMI.isBinaryOp(), I.isBinaryOp()); 1946 // Check isIntDivRem(). 1947 EXPECT_EQ(LLVMI.isIntDivRem(), I.isIntDivRem()); 1948 // Check isShift(). 1949 EXPECT_EQ(LLVMI.isShift(), I.isShift()); 1950 // Check isCast(). 1951 EXPECT_EQ(LLVMI.isCast(), I.isCast()); 1952 // Check isFuncletPad(). 1953 EXPECT_EQ(LLVMI.isFuncletPad(), I.isFuncletPad()); 1954 // Check isSpecialTerminator(). 1955 EXPECT_EQ(LLVMI.isSpecialTerminator(), I.isSpecialTerminator()); 1956 // Check isOnlyUserOfAnyOperand(). 1957 EXPECT_EQ(LLVMI.isOnlyUserOfAnyOperand(), I.isOnlyUserOfAnyOperand()); 1958 // Check isLogicalShift(). 1959 EXPECT_EQ(LLVMI.isLogicalShift(), I.isLogicalShift()); 1960 // Check hasMetadata(). 1961 EXPECT_EQ(LLVMI.hasMetadata(), I.hasMetadata()); 1962 // Check hasMetadataOtherThanDebugLoc(). 1963 EXPECT_EQ(LLVMI.hasMetadataOtherThanDebugLoc(), 1964 I.hasMetadataOtherThanDebugLoc()); 1965 // Check isAssociative(). 1966 EXPECT_EQ(LLVMI.isAssociative(), I.isAssociative()); 1967 // Check isCommutative(). 1968 EXPECT_EQ(LLVMI.isCommutative(), I.isCommutative()); 1969 // Check isIdempotent(). 1970 EXPECT_EQ(LLVMI.isIdempotent(), I.isIdempotent()); 1971 // Check isNilpotent(). 1972 EXPECT_EQ(LLVMI.isNilpotent(), I.isNilpotent()); 1973 // Check mayWriteToMemory(). 1974 EXPECT_EQ(LLVMI.mayWriteToMemory(), I.mayWriteToMemory()); 1975 // Check mayReadFromMemory(). 1976 EXPECT_EQ(LLVMI.mayReadFromMemory(), I.mayReadFromMemory()); 1977 // Check mayReadOrWriteMemory(). 1978 EXPECT_EQ(LLVMI.mayReadOrWriteMemory(), I.mayReadOrWriteMemory()); 1979 // Check isAtomic(). 1980 EXPECT_EQ(LLVMI.isAtomic(), I.isAtomic()); 1981 if (I.isAtomic()) { 1982 // Check hasAtomicLoad(). 1983 EXPECT_EQ(LLVMI.hasAtomicLoad(), I.hasAtomicLoad()); 1984 // Check hasAtomicStore(). 1985 EXPECT_EQ(LLVMI.hasAtomicStore(), I.hasAtomicStore()); 1986 } 1987 // Check isVolatile(). 1988 EXPECT_EQ(LLVMI.isVolatile(), I.isVolatile()); 1989 // Check getAccessType(). 1990 EXPECT_EQ(Ctx.getType(LLVMI.getAccessType()), I.getAccessType()); 1991 // Check mayThrow(). 1992 EXPECT_EQ(LLVMI.mayThrow(), I.mayThrow()); 1993 // Check isFenceLike(). 1994 EXPECT_EQ(LLVMI.isFenceLike(), I.isFenceLike()); 1995 // Check mayHaveSideEffects(). 1996 EXPECT_EQ(LLVMI.mayHaveSideEffects(), I.mayHaveSideEffects()); 1997 } 1998 } 1999 2000 TEST_F(SandboxIRTest, Instruction_isStackSaveOrRestoreIntrinsic) { 2001 parseIR(C, R"IR( 2002 declare void @llvm.sideeffect() 2003 define void @foo(i8 %v1, ptr %ptr) { 2004 %add = add i8 %v1, %v1 2005 %stacksave = call ptr @llvm.stacksave() 2006 call void @llvm.stackrestore(ptr %stacksave) 2007 call void @llvm.sideeffect() 2008 ret void 2009 } 2010 )IR"); 2011 llvm::Function *LLVMF = &*M->getFunction("foo"); 2012 sandboxir::Context Ctx(C); 2013 sandboxir::Function *F = Ctx.createFunction(LLVMF); 2014 auto *BB = &*F->begin(); 2015 auto It = BB->begin(); 2016 auto *Add = cast<sandboxir::BinaryOperator>(&*It++); 2017 auto *StackSave = cast<sandboxir::CallInst>(&*It++); 2018 auto *StackRestore = cast<sandboxir::CallInst>(&*It++); 2019 auto *Other = cast<sandboxir::CallInst>(&*It++); 2020 auto *Ret = cast<sandboxir::ReturnInst>(&*It++); 2021 2022 EXPECT_FALSE(Add->isStackSaveOrRestoreIntrinsic()); 2023 EXPECT_TRUE(StackSave->isStackSaveOrRestoreIntrinsic()); 2024 EXPECT_TRUE(StackRestore->isStackSaveOrRestoreIntrinsic()); 2025 EXPECT_FALSE(Other->isStackSaveOrRestoreIntrinsic()); 2026 EXPECT_FALSE(Ret->isStackSaveOrRestoreIntrinsic()); 2027 } 2028 2029 TEST_F(SandboxIRTest, Instruction_isMemDepCandidate) { 2030 parseIR(C, R"IR( 2031 declare void @llvm.fake.use(...) 2032 declare void @llvm.sideeffect() 2033 declare void @llvm.pseudoprobe(i64, i64, i32, i64) 2034 declare void @bar() 2035 define void @foo(i8 %v1, ptr %ptr) { 2036 %add0 = add i8 %v1, %v1 2037 %ld0 = load i8, ptr %ptr 2038 store i8 %v1, ptr %ptr 2039 call void @llvm.sideeffect() 2040 call void @llvm.pseudoprobe(i64 42, i64 1, i32 0, i64 -1) 2041 call void @llvm.fake.use(ptr %ptr) 2042 call void @bar() 2043 ret void 2044 } 2045 )IR"); 2046 llvm::Function *LLVMF = &*M->getFunction("foo"); 2047 sandboxir::Context Ctx(C); 2048 sandboxir::Function *F = Ctx.createFunction(LLVMF); 2049 auto *BB = &*F->begin(); 2050 auto It = BB->begin(); 2051 auto *Add0 = cast<sandboxir::BinaryOperator>(&*It++); 2052 auto *Ld0 = cast<sandboxir::LoadInst>(&*It++); 2053 auto *St0 = cast<sandboxir::StoreInst>(&*It++); 2054 auto *SideEffect0 = cast<sandboxir::CallInst>(&*It++); 2055 auto *PseudoProbe0 = cast<sandboxir::CallInst>(&*It++); 2056 auto *OtherIntrinsic0 = cast<sandboxir::CallInst>(&*It++); 2057 auto *CallBar = cast<sandboxir::CallInst>(&*It++); 2058 auto *Ret = cast<sandboxir::ReturnInst>(&*It++); 2059 2060 EXPECT_FALSE(Add0->isMemDepCandidate()); 2061 EXPECT_TRUE(Ld0->isMemDepCandidate()); 2062 EXPECT_TRUE(St0->isMemDepCandidate()); 2063 EXPECT_FALSE(SideEffect0->isMemDepCandidate()); 2064 EXPECT_FALSE(PseudoProbe0->isMemDepCandidate()); 2065 EXPECT_TRUE(OtherIntrinsic0->isMemDepCandidate()); 2066 EXPECT_TRUE(CallBar->isMemDepCandidate()); 2067 EXPECT_FALSE(Ret->isMemDepCandidate()); 2068 } 2069 2070 TEST_F(SandboxIRTest, VAArgInst) { 2071 parseIR(C, R"IR( 2072 define void @foo(ptr %va) { 2073 %va_arg = va_arg ptr %va, i32 2074 ret void 2075 } 2076 )IR"); 2077 llvm::Function *LLVMF = &*M->getFunction("foo"); 2078 2079 sandboxir::Context Ctx(C); 2080 sandboxir::Function *F = Ctx.createFunction(LLVMF); 2081 auto *Arg = F->getArg(0); 2082 auto *BB = &*F->begin(); 2083 auto It = BB->begin(); 2084 auto *VA = cast<sandboxir::VAArgInst>(&*It++); 2085 auto *Ret = cast<sandboxir::ReturnInst>(&*It++); 2086 2087 // Check getPointerOperand(). 2088 EXPECT_EQ(VA->getPointerOperand(), Arg); 2089 // Check getPOinterOperandIndex(). 2090 EXPECT_EQ(sandboxir::VAArgInst::getPointerOperandIndex(), 2091 llvm::VAArgInst::getPointerOperandIndex()); 2092 // Check create(). 2093 auto *NewVATy = sandboxir::Type::getInt8Ty(Ctx); 2094 auto *NewVA = sandboxir::VAArgInst::create(Arg, NewVATy, Ret->getIterator(), 2095 Ret->getParent(), Ctx, "NewVA"); 2096 EXPECT_EQ(NewVA->getNextNode(), Ret); 2097 EXPECT_EQ(NewVA->getType(), NewVATy); 2098 #ifndef NDEBUG 2099 EXPECT_EQ(NewVA->getName(), "NewVA"); 2100 #endif // NDEBUG 2101 } 2102 2103 TEST_F(SandboxIRTest, FreezeInst) { 2104 parseIR(C, R"IR( 2105 define void @foo(i8 %arg) { 2106 freeze i8 %arg 2107 ret void 2108 } 2109 )IR"); 2110 llvm::Function *LLVMF = &*M->getFunction("foo"); 2111 2112 sandboxir::Context Ctx(C); 2113 sandboxir::Function *F = Ctx.createFunction(LLVMF); 2114 auto *Arg = F->getArg(0); 2115 auto *BB = &*F->begin(); 2116 auto It = BB->begin(); 2117 auto *Freeze = cast<sandboxir::FreezeInst>(&*It++); 2118 auto *Ret = cast<sandboxir::ReturnInst>(&*It++); 2119 2120 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(Freeze)); 2121 EXPECT_EQ(Freeze->getOperand(0), Arg); 2122 2123 // Check create(). 2124 auto *NewFreeze = sandboxir::FreezeInst::create( 2125 Arg, Ret->getIterator(), Ret->getParent(), Ctx, "NewFreeze"); 2126 EXPECT_EQ(NewFreeze->getNextNode(), Ret); 2127 #ifndef NDEBUG 2128 EXPECT_EQ(NewFreeze->getName(), "NewFreeze"); 2129 #endif // NDEBUG 2130 } 2131 2132 TEST_F(SandboxIRTest, FenceInst) { 2133 parseIR(C, R"IR( 2134 define void @foo() { 2135 fence syncscope("singlethread") seq_cst 2136 ret void 2137 } 2138 )IR"); 2139 llvm::Function *LLVMF = &*M->getFunction("foo"); 2140 llvm::BasicBlock *LLVMBB = &*LLVMF->begin(); 2141 auto *LLVMFence = cast<llvm::FenceInst>(&*LLVMBB->begin()); 2142 sandboxir::Context Ctx(C); 2143 sandboxir::Function *F = Ctx.createFunction(LLVMF); 2144 auto *BB = &*F->begin(); 2145 auto It = BB->begin(); 2146 auto *Fence = cast<sandboxir::FenceInst>(&*It++); 2147 auto *Ret = cast<sandboxir::ReturnInst>(&*It++); 2148 2149 // Check getOrdering(). 2150 EXPECT_EQ(Fence->getOrdering(), LLVMFence->getOrdering()); 2151 // Check setOrdering(). 2152 auto OrigOrdering = Fence->getOrdering(); 2153 auto NewOrdering = AtomicOrdering::Release; 2154 EXPECT_NE(NewOrdering, OrigOrdering); 2155 Fence->setOrdering(NewOrdering); 2156 EXPECT_EQ(Fence->getOrdering(), NewOrdering); 2157 Fence->setOrdering(OrigOrdering); 2158 EXPECT_EQ(Fence->getOrdering(), OrigOrdering); 2159 // Check getSyncScopeID(). 2160 EXPECT_EQ(Fence->getSyncScopeID(), LLVMFence->getSyncScopeID()); 2161 // Check setSyncScopeID(). 2162 auto OrigSSID = Fence->getSyncScopeID(); 2163 auto NewSSID = SyncScope::System; 2164 EXPECT_NE(NewSSID, OrigSSID); 2165 Fence->setSyncScopeID(NewSSID); 2166 EXPECT_EQ(Fence->getSyncScopeID(), NewSSID); 2167 Fence->setSyncScopeID(OrigSSID); 2168 EXPECT_EQ(Fence->getSyncScopeID(), OrigSSID); 2169 // Check create(). 2170 auto *NewFence = 2171 sandboxir::FenceInst::create(AtomicOrdering::Release, Ret->getIterator(), 2172 BB, Ctx, SyncScope::SingleThread); 2173 EXPECT_EQ(NewFence->getNextNode(), Ret); 2174 EXPECT_EQ(NewFence->getOrdering(), AtomicOrdering::Release); 2175 EXPECT_EQ(NewFence->getSyncScopeID(), SyncScope::SingleThread); 2176 } 2177 2178 TEST_F(SandboxIRTest, SelectInst) { 2179 parseIR(C, R"IR( 2180 define void @foo(i1 %c0, i8 %v0, i8 %v1, i1 %c1) { 2181 %sel = select i1 %c0, i8 %v0, i8 %v1 2182 ret void 2183 } 2184 )IR"); 2185 llvm::Function *LLVMF = &*M->getFunction("foo"); 2186 sandboxir::Context Ctx(C); 2187 sandboxir::Function *F = Ctx.createFunction(LLVMF); 2188 auto *Cond0 = F->getArg(0); 2189 auto *V0 = F->getArg(1); 2190 auto *V1 = F->getArg(2); 2191 auto *Cond1 = F->getArg(3); 2192 auto *BB = &*F->begin(); 2193 auto It = BB->begin(); 2194 auto *Select = cast<sandboxir::SelectInst>(&*It++); 2195 const auto *ConstSelect = Select; // To test the const getters. 2196 auto *Ret = &*It++; 2197 2198 // Check getCondition(). 2199 EXPECT_EQ(Select->getCondition(), Cond0); 2200 EXPECT_EQ(ConstSelect->getCondition(), Cond0); 2201 // Check getTrueValue(). 2202 EXPECT_EQ(Select->getTrueValue(), V0); 2203 EXPECT_EQ(ConstSelect->getTrueValue(), V0); 2204 // Check getFalseValue(). 2205 EXPECT_EQ(Select->getFalseValue(), V1); 2206 EXPECT_EQ(ConstSelect->getFalseValue(), V1); 2207 // Check setCondition(). 2208 Select->setCondition(Cond1); 2209 EXPECT_EQ(Select->getCondition(), Cond1); 2210 // Check setTrueValue(). 2211 Select->setTrueValue(V1); 2212 EXPECT_EQ(Select->getTrueValue(), V1); 2213 // Check setFalseValue(). 2214 Select->setFalseValue(V0); 2215 EXPECT_EQ(Select->getFalseValue(), V0); 2216 // Check swapValues(). 2217 Select->swapValues(); 2218 EXPECT_EQ(Select->getTrueValue(), V0); 2219 EXPECT_EQ(Select->getFalseValue(), V1); 2220 // Check areInvalidOperands. 2221 EXPECT_EQ(sandboxir::SelectInst::areInvalidOperands(Cond0, V0, V1), nullptr); 2222 EXPECT_NE(sandboxir::SelectInst::areInvalidOperands(V0, V1, Cond0), nullptr); 2223 2224 { 2225 // Check SelectInst::create() InsertBefore. 2226 auto *NewSel = cast<sandboxir::SelectInst>(sandboxir::SelectInst::create( 2227 Cond0, V0, V1, /*InsertBefore=*/Ret, Ctx)); 2228 EXPECT_EQ(NewSel->getCondition(), Cond0); 2229 EXPECT_EQ(NewSel->getTrueValue(), V0); 2230 EXPECT_EQ(NewSel->getFalseValue(), V1); 2231 EXPECT_EQ(NewSel->getNextNode(), Ret); 2232 } 2233 { 2234 // Check SelectInst::create() InsertAtEnd. 2235 auto *NewSel = cast<sandboxir::SelectInst>( 2236 sandboxir::SelectInst::create(Cond0, V0, V1, /*InsertAtEnd=*/BB, Ctx)); 2237 EXPECT_EQ(NewSel->getCondition(), Cond0); 2238 EXPECT_EQ(NewSel->getTrueValue(), V0); 2239 EXPECT_EQ(NewSel->getFalseValue(), V1); 2240 EXPECT_EQ(NewSel->getPrevNode(), Ret); 2241 } 2242 { 2243 // Check SelectInst::create() Folded. 2244 auto *False = sandboxir::ConstantInt::get(sandboxir::Type::getInt1Ty(Ctx), 2245 0, /*IsSigned=*/false); 2246 auto *FortyTwo = 2247 sandboxir::ConstantInt::get(sandboxir::Type::getInt1Ty(Ctx), 42, 2248 /*IsSigned=*/false); 2249 auto *NewSel = 2250 sandboxir::SelectInst::create(False, FortyTwo, FortyTwo, Ret, Ctx); 2251 EXPECT_TRUE(isa<sandboxir::Constant>(NewSel)); 2252 EXPECT_EQ(NewSel, FortyTwo); 2253 } 2254 } 2255 2256 TEST_F(SandboxIRTest, ExtractElementInst) { 2257 parseIR(C, R"IR( 2258 define void @foo(<2 x i8> %vec, i32 %idx) { 2259 %ins0 = extractelement <2 x i8> %vec, i32 %idx 2260 ret void 2261 } 2262 )IR"); 2263 Function &LLVMF = *M->getFunction("foo"); 2264 sandboxir::Context Ctx(C); 2265 auto &F = *Ctx.createFunction(&LLVMF); 2266 auto *ArgVec = F.getArg(0); 2267 auto *ArgIdx = F.getArg(1); 2268 auto *BB = &*F.begin(); 2269 auto It = BB->begin(); 2270 auto *EI = cast<sandboxir::ExtractElementInst>(&*It++); 2271 auto *Ret = &*It++; 2272 2273 EXPECT_EQ(EI->getOpcode(), sandboxir::Instruction::Opcode::ExtractElement); 2274 EXPECT_EQ(EI->getOperand(0), ArgVec); 2275 EXPECT_EQ(EI->getOperand(1), ArgIdx); 2276 EXPECT_EQ(EI->getVectorOperand(), ArgVec); 2277 EXPECT_EQ(EI->getIndexOperand(), ArgIdx); 2278 EXPECT_EQ(EI->getVectorOperandType(), ArgVec->getType()); 2279 2280 auto *NewI1 = 2281 cast<sandboxir::ExtractElementInst>(sandboxir::ExtractElementInst::create( 2282 ArgVec, ArgIdx, Ret, Ctx, "NewExtrBeforeRet")); 2283 EXPECT_EQ(NewI1->getOperand(0), ArgVec); 2284 EXPECT_EQ(NewI1->getOperand(1), ArgIdx); 2285 EXPECT_EQ(NewI1->getNextNode(), Ret); 2286 2287 auto *NewI2 = 2288 cast<sandboxir::ExtractElementInst>(sandboxir::ExtractElementInst::create( 2289 ArgVec, ArgIdx, BB, Ctx, "NewExtrAtEndOfBB")); 2290 EXPECT_EQ(NewI2->getPrevNode(), Ret); 2291 2292 auto *LLVMArgVec = LLVMF.getArg(0); 2293 auto *LLVMArgIdx = LLVMF.getArg(1); 2294 EXPECT_EQ(sandboxir::ExtractElementInst::isValidOperands(ArgVec, ArgIdx), 2295 llvm::ExtractElementInst::isValidOperands(LLVMArgVec, LLVMArgIdx)); 2296 EXPECT_EQ(sandboxir::ExtractElementInst::isValidOperands(ArgIdx, ArgVec), 2297 llvm::ExtractElementInst::isValidOperands(LLVMArgIdx, LLVMArgVec)); 2298 } 2299 2300 TEST_F(SandboxIRTest, InsertElementInst) { 2301 parseIR(C, R"IR( 2302 define void @foo(i8 %v0, i8 %v1, <2 x i8> %vec) { 2303 %ins0 = insertelement <2 x i8> poison, i8 %v0, i32 0 2304 %ins1 = insertelement <2 x i8> %ins0, i8 %v1, i32 1 2305 ret void 2306 } 2307 )IR"); 2308 Function &LLVMF = *M->getFunction("foo"); 2309 sandboxir::Context Ctx(C); 2310 auto &F = *Ctx.createFunction(&LLVMF); 2311 auto *Arg0 = F.getArg(0); 2312 auto *Arg1 = F.getArg(1); 2313 auto *ArgVec = F.getArg(2); 2314 auto *BB = &*F.begin(); 2315 auto It = BB->begin(); 2316 auto *Ins0 = cast<sandboxir::InsertElementInst>(&*It++); 2317 auto *Ins1 = cast<sandboxir::InsertElementInst>(&*It++); 2318 auto *Ret = &*It++; 2319 2320 EXPECT_EQ(Ins0->getOpcode(), sandboxir::Instruction::Opcode::InsertElement); 2321 EXPECT_EQ(Ins0->getOperand(1), Arg0); 2322 EXPECT_EQ(Ins1->getOperand(1), Arg1); 2323 EXPECT_EQ(Ins1->getOperand(0), Ins0); 2324 auto *Poison = Ins0->getOperand(0); 2325 auto *Idx = Ins0->getOperand(2); 2326 auto *NewI1 = 2327 cast<sandboxir::InsertElementInst>(sandboxir::InsertElementInst::create( 2328 Poison, Arg0, Idx, Ret, Ctx, "NewIns1")); 2329 EXPECT_EQ(NewI1->getOperand(0), Poison); 2330 EXPECT_EQ(NewI1->getNextNode(), Ret); 2331 2332 auto *NewI2 = 2333 cast<sandboxir::InsertElementInst>(sandboxir::InsertElementInst::create( 2334 Poison, Arg0, Idx, BB, Ctx, "NewIns2")); 2335 EXPECT_EQ(NewI2->getPrevNode(), Ret); 2336 2337 auto *LLVMArg0 = LLVMF.getArg(0); 2338 auto *LLVMArgVec = LLVMF.getArg(2); 2339 auto *Zero = sandboxir::ConstantInt::get(sandboxir::Type::getInt8Ty(Ctx), 0); 2340 auto *LLVMZero = llvm::ConstantInt::get(Type::getInt8Ty(C), 0); 2341 EXPECT_EQ( 2342 sandboxir::InsertElementInst::isValidOperands(ArgVec, Arg0, Zero), 2343 llvm::InsertElementInst::isValidOperands(LLVMArgVec, LLVMArg0, LLVMZero)); 2344 EXPECT_EQ( 2345 sandboxir::InsertElementInst::isValidOperands(Arg0, ArgVec, Zero), 2346 llvm::InsertElementInst::isValidOperands(LLVMArg0, LLVMArgVec, LLVMZero)); 2347 } 2348 2349 TEST_F(SandboxIRTest, ShuffleVectorInst) { 2350 parseIR(C, R"IR( 2351 define void @foo(<2 x i8> %v1, <2 x i8> %v2) { 2352 %shuf = shufflevector <2 x i8> %v1, <2 x i8> %v2, <2 x i32> <i32 0, i32 2> 2353 %extr = extractelement <2 x i8> <i8 0, i8 1>, i32 0 2354 ret void 2355 } 2356 )IR"); 2357 Function &LLVMF = *M->getFunction("foo"); 2358 sandboxir::Context Ctx(C); 2359 auto &F = *Ctx.createFunction(&LLVMF); 2360 auto *ArgV1 = F.getArg(0); 2361 auto *ArgV2 = F.getArg(1); 2362 auto *BB = &*F.begin(); 2363 auto It = BB->begin(); 2364 auto *SVI = cast<sandboxir::ShuffleVectorInst>(&*It++); 2365 auto *EEI = cast<sandboxir::ExtractElementInst>(&*It++); 2366 auto *Ret = &*It++; 2367 2368 EXPECT_EQ(SVI->getOpcode(), sandboxir::Instruction::Opcode::ShuffleVector); 2369 EXPECT_EQ(SVI->getOperand(0), ArgV1); 2370 EXPECT_EQ(SVI->getOperand(1), ArgV2); 2371 2372 // In order to test all the methods we need masks of different lengths, so we 2373 // can't simply reuse one of the instructions created above. This helper 2374 // creates a new `shufflevector %v1, %2, <mask>` with the given mask indices. 2375 auto CreateShuffleWithMask = [&](auto &&...Indices) { 2376 SmallVector<int, 4> Mask = {Indices...}; 2377 return cast<sandboxir::ShuffleVectorInst>( 2378 sandboxir::ShuffleVectorInst::create(ArgV1, ArgV2, Mask, Ret, Ctx)); 2379 }; 2380 2381 // create (InsertBefore) 2382 auto *NewI1 = 2383 cast<sandboxir::ShuffleVectorInst>(sandboxir::ShuffleVectorInst::create( 2384 ArgV1, ArgV2, ArrayRef<int>({0, 2, 1, 3}), Ret, Ctx, 2385 "NewShuffleBeforeRet")); 2386 EXPECT_EQ(NewI1->getOperand(0), ArgV1); 2387 EXPECT_EQ(NewI1->getOperand(1), ArgV2); 2388 EXPECT_EQ(NewI1->getNextNode(), Ret); 2389 #ifndef NDEBUG 2390 EXPECT_EQ(NewI1->getName(), "NewShuffleBeforeRet"); 2391 #endif 2392 2393 // create (InsertAtEnd) 2394 auto *NewI2 = 2395 cast<sandboxir::ShuffleVectorInst>(sandboxir::ShuffleVectorInst::create( 2396 ArgV1, ArgV2, ArrayRef<int>({0, 1}), BB, Ctx, "NewShuffleAtEndOfBB")); 2397 EXPECT_EQ(NewI2->getPrevNode(), Ret); 2398 2399 // Test the path that creates a folded constant. We're currently using an 2400 // extractelement instruction with a constant operand in the textual IR above 2401 // to obtain a constant vector to work with. 2402 // TODO: Refactor this once sandboxir::ConstantVector lands. 2403 auto *ShouldBeConstant = sandboxir::ShuffleVectorInst::create( 2404 EEI->getOperand(0), EEI->getOperand(0), ArrayRef<int>({0, 3}), BB, Ctx); 2405 EXPECT_TRUE(isa<sandboxir::Constant>(ShouldBeConstant)); 2406 2407 // isValidOperands 2408 auto *LLVMArgV1 = LLVMF.getArg(0); 2409 auto *LLVMArgV2 = LLVMF.getArg(1); 2410 SmallVector<int, 2> Mask({1, 2}); 2411 EXPECT_EQ( 2412 sandboxir::ShuffleVectorInst::isValidOperands(ArgV1, ArgV2, Mask), 2413 llvm::ShuffleVectorInst::isValidOperands(LLVMArgV1, LLVMArgV2, Mask)); 2414 EXPECT_EQ(sandboxir::ShuffleVectorInst::isValidOperands(ArgV1, ArgV1, ArgV1), 2415 llvm::ShuffleVectorInst::isValidOperands(LLVMArgV1, LLVMArgV1, 2416 LLVMArgV1)); 2417 2418 // commute 2419 { 2420 auto *I = CreateShuffleWithMask(0, 2); 2421 I->commute(); 2422 EXPECT_EQ(I->getOperand(0), ArgV2); 2423 EXPECT_EQ(I->getOperand(1), ArgV1); 2424 EXPECT_THAT(I->getShuffleMask(), testing::ElementsAre(2, 0)); 2425 } 2426 2427 // getType 2428 EXPECT_EQ(SVI->getType(), ArgV1->getType()); 2429 2430 // getMaskValue 2431 EXPECT_EQ(SVI->getMaskValue(0), 0); 2432 EXPECT_EQ(SVI->getMaskValue(1), 2); 2433 2434 // getShuffleMask / getShuffleMaskForBitcode 2435 { 2436 EXPECT_THAT(SVI->getShuffleMask(), testing::ElementsAre(0, 2)); 2437 2438 SmallVector<int, 2> Result; 2439 SVI->getShuffleMask(Result); 2440 EXPECT_THAT(Result, testing::ElementsAre(0, 2)); 2441 2442 Result.clear(); 2443 sandboxir::ShuffleVectorInst::getShuffleMask( 2444 SVI->getShuffleMaskForBitcode(), Result); 2445 EXPECT_THAT(Result, testing::ElementsAre(0, 2)); 2446 } 2447 2448 // convertShuffleMaskForBitcode 2449 { 2450 auto *C = sandboxir::ShuffleVectorInst::convertShuffleMaskForBitcode( 2451 ArrayRef<int>({2, 3}), ArgV1->getType()); 2452 SmallVector<int, 2> Result; 2453 sandboxir::ShuffleVectorInst::getShuffleMask(C, Result); 2454 EXPECT_THAT(Result, testing::ElementsAre(2, 3)); 2455 } 2456 2457 // setShuffleMask 2458 { 2459 auto *I = CreateShuffleWithMask(0, 1); 2460 I->setShuffleMask(ArrayRef<int>({2, 3})); 2461 EXPECT_THAT(I->getShuffleMask(), testing::ElementsAre(2, 3)); 2462 } 2463 2464 // The following functions check different mask properties. Note that most 2465 // of these come in three different flavors: a method that checks the mask 2466 // in the current instructions and two static member functions that check 2467 // a mask given as an ArrayRef<int> or Constant*, so there's quite a bit of 2468 // repetition in order to check all of them. 2469 2470 // changesLength / increasesLength 2471 { 2472 auto *I = CreateShuffleWithMask(1); 2473 EXPECT_TRUE(I->changesLength()); 2474 EXPECT_FALSE(I->increasesLength()); 2475 } 2476 { 2477 auto *I = CreateShuffleWithMask(1, 1); 2478 EXPECT_FALSE(I->changesLength()); 2479 EXPECT_FALSE(I->increasesLength()); 2480 } 2481 { 2482 auto *I = CreateShuffleWithMask(1, 1, 1); 2483 EXPECT_TRUE(I->changesLength()); 2484 EXPECT_TRUE(I->increasesLength()); 2485 } 2486 2487 // isSingleSource / isSingleSourceMask 2488 { 2489 auto *I = CreateShuffleWithMask(0, 1); 2490 EXPECT_TRUE(I->isSingleSource()); 2491 EXPECT_TRUE(sandboxir::ShuffleVectorInst::isSingleSourceMask( 2492 I->getShuffleMaskForBitcode(), 2)); 2493 EXPECT_TRUE(sandboxir::ShuffleVectorInst::isSingleSourceMask( 2494 I->getShuffleMask(), 2)); 2495 } 2496 { 2497 auto *I = CreateShuffleWithMask(0, 2); 2498 EXPECT_FALSE(I->isSingleSource()); 2499 EXPECT_FALSE(sandboxir::ShuffleVectorInst::isSingleSourceMask( 2500 I->getShuffleMaskForBitcode(), 2)); 2501 EXPECT_FALSE(sandboxir::ShuffleVectorInst::isSingleSourceMask( 2502 I->getShuffleMask(), 2)); 2503 } 2504 2505 // isIdentity / isIdentityMask 2506 { 2507 auto *I = CreateShuffleWithMask(0, 1); 2508 EXPECT_TRUE(I->isIdentity()); 2509 EXPECT_TRUE(sandboxir::ShuffleVectorInst::isIdentityMask( 2510 I->getShuffleMaskForBitcode(), 2)); 2511 EXPECT_TRUE( 2512 sandboxir::ShuffleVectorInst::isIdentityMask(I->getShuffleMask(), 2)); 2513 } 2514 { 2515 auto *I = CreateShuffleWithMask(1, 0); 2516 EXPECT_FALSE(I->isIdentity()); 2517 EXPECT_FALSE(sandboxir::ShuffleVectorInst::isIdentityMask( 2518 I->getShuffleMaskForBitcode(), 2)); 2519 EXPECT_FALSE( 2520 sandboxir::ShuffleVectorInst::isIdentityMask(I->getShuffleMask(), 2)); 2521 } 2522 2523 // isIdentityWithPadding 2524 EXPECT_TRUE(CreateShuffleWithMask(0, 1, -1, -1)->isIdentityWithPadding()); 2525 EXPECT_FALSE(CreateShuffleWithMask(0, 1)->isIdentityWithPadding()); 2526 2527 // isIdentityWithExtract 2528 EXPECT_TRUE(CreateShuffleWithMask(0)->isIdentityWithExtract()); 2529 EXPECT_FALSE(CreateShuffleWithMask(0, 1)->isIdentityWithExtract()); 2530 EXPECT_FALSE(CreateShuffleWithMask(0, 1, 2)->isIdentityWithExtract()); 2531 EXPECT_FALSE(CreateShuffleWithMask(1)->isIdentityWithExtract()); 2532 2533 // isConcat 2534 EXPECT_TRUE(CreateShuffleWithMask(0, 1, 2, 3)->isConcat()); 2535 EXPECT_FALSE(CreateShuffleWithMask(0, 3)->isConcat()); 2536 2537 // isSelect / isSelectMask 2538 { 2539 auto *I = CreateShuffleWithMask(0, 3); 2540 EXPECT_TRUE(I->isSelect()); 2541 EXPECT_TRUE(sandboxir::ShuffleVectorInst::isSelectMask( 2542 I->getShuffleMaskForBitcode(), 2)); 2543 EXPECT_TRUE( 2544 sandboxir::ShuffleVectorInst::isSelectMask(I->getShuffleMask(), 2)); 2545 } 2546 { 2547 auto *I = CreateShuffleWithMask(0, 2); 2548 EXPECT_FALSE(I->isSelect()); 2549 EXPECT_FALSE(sandboxir::ShuffleVectorInst::isSelectMask( 2550 I->getShuffleMaskForBitcode(), 2)); 2551 EXPECT_FALSE( 2552 sandboxir::ShuffleVectorInst::isSelectMask(I->getShuffleMask(), 2)); 2553 } 2554 2555 // isReverse / isReverseMask 2556 { 2557 auto *I = CreateShuffleWithMask(1, 0); 2558 EXPECT_TRUE(I->isReverse()); 2559 EXPECT_TRUE(sandboxir::ShuffleVectorInst::isReverseMask( 2560 I->getShuffleMaskForBitcode(), 2)); 2561 EXPECT_TRUE( 2562 sandboxir::ShuffleVectorInst::isReverseMask(I->getShuffleMask(), 2)); 2563 } 2564 { 2565 auto *I = CreateShuffleWithMask(1, 2); 2566 EXPECT_FALSE(I->isReverse()); 2567 EXPECT_FALSE(sandboxir::ShuffleVectorInst::isReverseMask( 2568 I->getShuffleMaskForBitcode(), 2)); 2569 EXPECT_FALSE( 2570 sandboxir::ShuffleVectorInst::isReverseMask(I->getShuffleMask(), 2)); 2571 } 2572 2573 // isZeroEltSplat / isZeroEltSplatMask 2574 { 2575 auto *I = CreateShuffleWithMask(0, 0); 2576 EXPECT_TRUE(I->isZeroEltSplat()); 2577 EXPECT_TRUE(sandboxir::ShuffleVectorInst::isZeroEltSplatMask( 2578 I->getShuffleMaskForBitcode(), 2)); 2579 EXPECT_TRUE(sandboxir::ShuffleVectorInst::isZeroEltSplatMask( 2580 I->getShuffleMask(), 2)); 2581 } 2582 { 2583 auto *I = CreateShuffleWithMask(1, 1); 2584 EXPECT_FALSE(I->isZeroEltSplat()); 2585 EXPECT_FALSE(sandboxir::ShuffleVectorInst::isZeroEltSplatMask( 2586 I->getShuffleMaskForBitcode(), 2)); 2587 EXPECT_FALSE(sandboxir::ShuffleVectorInst::isZeroEltSplatMask( 2588 I->getShuffleMask(), 2)); 2589 } 2590 2591 // isTranspose / isTransposeMask 2592 { 2593 auto *I = CreateShuffleWithMask(0, 2); 2594 EXPECT_TRUE(I->isTranspose()); 2595 EXPECT_TRUE(sandboxir::ShuffleVectorInst::isTransposeMask( 2596 I->getShuffleMaskForBitcode(), 2)); 2597 EXPECT_TRUE( 2598 sandboxir::ShuffleVectorInst::isTransposeMask(I->getShuffleMask(), 2)); 2599 } 2600 { 2601 auto *I = CreateShuffleWithMask(1, 1); 2602 EXPECT_FALSE(I->isTranspose()); 2603 EXPECT_FALSE(sandboxir::ShuffleVectorInst::isTransposeMask( 2604 I->getShuffleMaskForBitcode(), 2)); 2605 EXPECT_FALSE( 2606 sandboxir::ShuffleVectorInst::isTransposeMask(I->getShuffleMask(), 2)); 2607 } 2608 2609 // isSplice / isSpliceMask 2610 { 2611 auto *I = CreateShuffleWithMask(1, 2); 2612 int Index; 2613 EXPECT_TRUE(I->isSplice(Index)); 2614 EXPECT_EQ(Index, 1); 2615 EXPECT_TRUE(sandboxir::ShuffleVectorInst::isSpliceMask( 2616 I->getShuffleMaskForBitcode(), 2, Index)); 2617 EXPECT_TRUE(sandboxir::ShuffleVectorInst::isSpliceMask(I->getShuffleMask(), 2618 2, Index)); 2619 } 2620 { 2621 auto *I = CreateShuffleWithMask(2, 1); 2622 int Index; 2623 EXPECT_FALSE(I->isSplice(Index)); 2624 EXPECT_FALSE(sandboxir::ShuffleVectorInst::isSpliceMask( 2625 I->getShuffleMaskForBitcode(), 2, Index)); 2626 EXPECT_FALSE(sandboxir::ShuffleVectorInst::isSpliceMask(I->getShuffleMask(), 2627 2, Index)); 2628 } 2629 2630 // isExtractSubvectorMask 2631 { 2632 auto *I = CreateShuffleWithMask(1); 2633 int Index; 2634 EXPECT_TRUE(I->isExtractSubvectorMask(Index)); 2635 EXPECT_EQ(Index, 1); 2636 EXPECT_TRUE(sandboxir::ShuffleVectorInst::isExtractSubvectorMask( 2637 I->getShuffleMaskForBitcode(), 2, Index)); 2638 EXPECT_TRUE(sandboxir::ShuffleVectorInst::isExtractSubvectorMask( 2639 I->getShuffleMask(), 2, Index)); 2640 } 2641 { 2642 auto *I = CreateShuffleWithMask(1, 2); 2643 int Index; 2644 EXPECT_FALSE(I->isExtractSubvectorMask(Index)); 2645 EXPECT_FALSE(sandboxir::ShuffleVectorInst::isExtractSubvectorMask( 2646 I->getShuffleMaskForBitcode(), 2, Index)); 2647 EXPECT_FALSE(sandboxir::ShuffleVectorInst::isExtractSubvectorMask( 2648 I->getShuffleMask(), 2, Index)); 2649 } 2650 2651 // isInsertSubvectorMask 2652 { 2653 auto *I = CreateShuffleWithMask(0, 2); 2654 int NumSubElts, Index; 2655 EXPECT_TRUE(I->isInsertSubvectorMask(NumSubElts, Index)); 2656 EXPECT_EQ(Index, 1); 2657 EXPECT_EQ(NumSubElts, 1); 2658 EXPECT_TRUE(sandboxir::ShuffleVectorInst::isInsertSubvectorMask( 2659 I->getShuffleMaskForBitcode(), 2, NumSubElts, Index)); 2660 EXPECT_TRUE(sandboxir::ShuffleVectorInst::isInsertSubvectorMask( 2661 I->getShuffleMask(), 2, NumSubElts, Index)); 2662 } 2663 { 2664 auto *I = CreateShuffleWithMask(0, 1); 2665 int NumSubElts, Index; 2666 EXPECT_FALSE(I->isInsertSubvectorMask(NumSubElts, Index)); 2667 EXPECT_FALSE(sandboxir::ShuffleVectorInst::isInsertSubvectorMask( 2668 I->getShuffleMaskForBitcode(), 2, NumSubElts, Index)); 2669 EXPECT_FALSE(sandboxir::ShuffleVectorInst::isInsertSubvectorMask( 2670 I->getShuffleMask(), 2, NumSubElts, Index)); 2671 } 2672 2673 // isReplicationMask 2674 { 2675 auto *I = CreateShuffleWithMask(0, 0, 0, 1, 1, 1); 2676 int ReplicationFactor, VF; 2677 EXPECT_TRUE(I->isReplicationMask(ReplicationFactor, VF)); 2678 EXPECT_EQ(ReplicationFactor, 3); 2679 EXPECT_EQ(VF, 2); 2680 EXPECT_TRUE(sandboxir::ShuffleVectorInst::isReplicationMask( 2681 I->getShuffleMaskForBitcode(), ReplicationFactor, VF)); 2682 EXPECT_TRUE(sandboxir::ShuffleVectorInst::isReplicationMask( 2683 I->getShuffleMask(), ReplicationFactor, VF)); 2684 } 2685 { 2686 auto *I = CreateShuffleWithMask(1, 2); 2687 int ReplicationFactor, VF; 2688 EXPECT_FALSE(I->isReplicationMask(ReplicationFactor, VF)); 2689 EXPECT_FALSE(sandboxir::ShuffleVectorInst::isReplicationMask( 2690 I->getShuffleMaskForBitcode(), ReplicationFactor, VF)); 2691 EXPECT_FALSE(sandboxir::ShuffleVectorInst::isReplicationMask( 2692 I->getShuffleMask(), ReplicationFactor, VF)); 2693 } 2694 2695 // isOneUseSingleSourceMask 2696 { 2697 auto *I = CreateShuffleWithMask(0, 1, 1, 0); 2698 EXPECT_TRUE(I->isOneUseSingleSourceMask(2)); 2699 EXPECT_TRUE(sandboxir::ShuffleVectorInst::isOneUseSingleSourceMask( 2700 I->getShuffleMask(), 2)); 2701 } 2702 { 2703 auto *I = CreateShuffleWithMask(0, 1, 0, 0); 2704 EXPECT_FALSE(I->isOneUseSingleSourceMask(2)); 2705 EXPECT_FALSE(sandboxir::ShuffleVectorInst::isOneUseSingleSourceMask( 2706 I->getShuffleMask(), 2)); 2707 } 2708 2709 // commuteShuffleMask 2710 { 2711 SmallVector<int, 4> M = {0, 2, 1, 3}; 2712 ShuffleVectorInst::commuteShuffleMask(M, 2); 2713 EXPECT_THAT(M, testing::ElementsAre(2, 0, 3, 1)); 2714 } 2715 2716 // isInterleave / isInterleaveMask 2717 { 2718 auto *I = CreateShuffleWithMask(0, 2, 1, 3); 2719 EXPECT_TRUE(I->isInterleave(2)); 2720 EXPECT_TRUE(sandboxir::ShuffleVectorInst::isInterleaveMask( 2721 I->getShuffleMask(), 2, 4)); 2722 SmallVector<unsigned, 4> StartIndexes; 2723 EXPECT_TRUE(sandboxir::ShuffleVectorInst::isInterleaveMask( 2724 I->getShuffleMask(), 2, 4, StartIndexes)); 2725 EXPECT_THAT(StartIndexes, testing::ElementsAre(0, 2)); 2726 } 2727 { 2728 auto *I = CreateShuffleWithMask(0, 3, 1, 2); 2729 EXPECT_FALSE(I->isInterleave(2)); 2730 EXPECT_FALSE(sandboxir::ShuffleVectorInst::isInterleaveMask( 2731 I->getShuffleMask(), 2, 4)); 2732 } 2733 2734 // isDeInterleaveMaskOfFactor 2735 { 2736 EXPECT_TRUE(sandboxir::ShuffleVectorInst::isDeInterleaveMaskOfFactor( 2737 ArrayRef<int>({0, 2}), 2)); 2738 EXPECT_FALSE(sandboxir::ShuffleVectorInst::isDeInterleaveMaskOfFactor( 2739 ArrayRef<int>({0, 1}), 2)); 2740 2741 unsigned Index; 2742 EXPECT_TRUE(sandboxir::ShuffleVectorInst::isDeInterleaveMaskOfFactor( 2743 ArrayRef<int>({1, 3}), 2, Index)); 2744 EXPECT_EQ(Index, 1u); 2745 } 2746 2747 // isBitRotateMask 2748 { 2749 unsigned NumSubElts, RotateAmt; 2750 EXPECT_TRUE(sandboxir::ShuffleVectorInst::isBitRotateMask( 2751 ArrayRef<int>({1, 0, 3, 2, 5, 4, 7, 6}), 8, 2, 2, NumSubElts, 2752 RotateAmt)); 2753 EXPECT_EQ(NumSubElts, 2u); 2754 EXPECT_EQ(RotateAmt, 8u); 2755 2756 EXPECT_FALSE(sandboxir::ShuffleVectorInst::isBitRotateMask( 2757 ArrayRef<int>({0, 7, 1, 6, 2, 5, 3, 4}), 8, 2, 2, NumSubElts, 2758 RotateAmt)); 2759 } 2760 } 2761 2762 TEST_F(SandboxIRTest, ExtractValueInst) { 2763 parseIR(C, R"IR( 2764 define void @foo({i32, float} %agg) { 2765 %ext_simple = extractvalue {i32, float} %agg, 0 2766 %ext_nested = extractvalue {float, {i32}} undef, 1, 0 2767 %const1 = extractvalue {i32, float} {i32 0, float 99.0}, 0 2768 ret void 2769 } 2770 )IR"); 2771 Function &LLVMF = *M->getFunction("foo"); 2772 auto *LLVMBB = &*LLVMF.begin(); 2773 auto LLVMIt = LLVMBB->begin(); 2774 [[maybe_unused]] auto *LLVMExtSimple = 2775 cast<llvm::ExtractValueInst>(&*LLVMIt++); 2776 auto *LLVMExtNested = cast<llvm::ExtractValueInst>(&*LLVMIt++); 2777 2778 sandboxir::Context Ctx(C); 2779 auto &F = *Ctx.createFunction(&LLVMF); 2780 auto *ArgAgg = F.getArg(0); 2781 auto *BB = &*F.begin(); 2782 auto It = BB->begin(); 2783 auto *ExtSimple = cast<sandboxir::ExtractValueInst>(&*It++); 2784 auto *ExtNested = cast<sandboxir::ExtractValueInst>(&*It++); 2785 auto *Const1 = cast<sandboxir::ExtractValueInst>(&*It++); 2786 auto *Ret = &*It++; 2787 2788 EXPECT_EQ(ExtSimple->getOperand(0), ArgAgg); 2789 2790 // create before instruction 2791 auto *NewExtBeforeRet = 2792 cast<sandboxir::ExtractValueInst>(sandboxir::ExtractValueInst::create( 2793 ArgAgg, ArrayRef<unsigned>({0}), Ret->getIterator(), Ret->getParent(), 2794 Ctx, "NewExtBeforeRet")); 2795 EXPECT_EQ(NewExtBeforeRet->getNextNode(), Ret); 2796 #ifndef NDEBUG 2797 EXPECT_EQ(NewExtBeforeRet->getName(), "NewExtBeforeRet"); 2798 #endif // NDEBUG 2799 2800 // create at end of BB 2801 auto *NewExtAtEnd = 2802 cast<sandboxir::ExtractValueInst>(sandboxir::ExtractValueInst::create( 2803 ArgAgg, ArrayRef<unsigned>({0}), BB->end(), BB, Ctx, "NewExtAtEnd")); 2804 EXPECT_EQ(NewExtAtEnd->getPrevNode(), Ret); 2805 #ifndef NDEBUG 2806 EXPECT_EQ(NewExtAtEnd->getName(), "NewExtAtEnd"); 2807 #endif // NDEBUG 2808 2809 // Test the path that creates a folded constant. 2810 auto *ShouldBeConstant = sandboxir::ExtractValueInst::create( 2811 Const1->getOperand(0), ArrayRef<unsigned>({0}), BB->end(), BB, Ctx); 2812 EXPECT_TRUE(isa<sandboxir::Constant>(ShouldBeConstant)); 2813 2814 auto *Zero = sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 0); 2815 EXPECT_EQ(ShouldBeConstant, Zero); 2816 2817 // getIndexedType 2818 sandboxir::Type *AggType = ExtNested->getAggregateOperand()->getType(); 2819 llvm::Type *LLVMAggType = LLVMExtNested->getAggregateOperand()->getType(); 2820 EXPECT_EQ(sandboxir::ExtractValueInst::getIndexedType( 2821 AggType, ArrayRef<unsigned>({1, 0})), 2822 Ctx.getType(llvm::ExtractValueInst::getIndexedType( 2823 LLVMAggType, ArrayRef<unsigned>({1, 0})))); 2824 2825 EXPECT_EQ(sandboxir::ExtractValueInst::getIndexedType( 2826 AggType, ArrayRef<unsigned>({2})), 2827 nullptr); 2828 2829 // idx_begin / idx_end 2830 { 2831 SmallVector<int, 2> IndicesSimple(ExtSimple->idx_begin(), 2832 ExtSimple->idx_end()); 2833 EXPECT_THAT(IndicesSimple, testing::ElementsAre(0u)); 2834 2835 SmallVector<int, 2> IndicesNested(ExtNested->idx_begin(), 2836 ExtNested->idx_end()); 2837 EXPECT_THAT(IndicesNested, testing::ElementsAre(1u, 0u)); 2838 } 2839 2840 // indices 2841 { 2842 SmallVector<int, 2> IndicesSimple(ExtSimple->indices()); 2843 EXPECT_THAT(IndicesSimple, testing::ElementsAre(0u)); 2844 2845 SmallVector<int, 2> IndicesNested(ExtNested->indices()); 2846 EXPECT_THAT(IndicesNested, testing::ElementsAre(1u, 0u)); 2847 } 2848 2849 // getAggregateOperand 2850 EXPECT_EQ(ExtSimple->getAggregateOperand(), ArgAgg); 2851 const auto *ConstExtSimple = ExtSimple; 2852 EXPECT_EQ(ConstExtSimple->getAggregateOperand(), ArgAgg); 2853 2854 // getAggregateOperandIndex 2855 EXPECT_EQ(sandboxir::ExtractValueInst::getAggregateOperandIndex(), 2856 llvm::ExtractValueInst::getAggregateOperandIndex()); 2857 2858 // getIndices 2859 EXPECT_EQ(ExtSimple->getIndices().size(), 1u); 2860 EXPECT_EQ(ExtSimple->getIndices()[0], 0u); 2861 2862 // getNumIndices 2863 EXPECT_EQ(ExtSimple->getNumIndices(), 1u); 2864 2865 // hasIndices 2866 EXPECT_EQ(ExtSimple->hasIndices(), true); 2867 } 2868 2869 TEST_F(SandboxIRTest, InsertValueInst) { 2870 parseIR(C, R"IR( 2871 define void @foo({i32, float} %agg, i32 %i) { 2872 %ins_simple = insertvalue {i32, float} %agg, i32 %i, 0 2873 %ins_nested = insertvalue {float, {i32}} undef, i32 %i, 1, 0 2874 %const1 = insertvalue {i32, float} {i32 99, float 99.0}, i32 %i, 0 2875 %const2 = insertvalue {i32, float} {i32 0, float 99.0}, i32 %i, 0 2876 ret void 2877 } 2878 )IR"); 2879 Function &LLVMF = *M->getFunction("foo"); 2880 sandboxir::Context Ctx(C); 2881 auto &F = *Ctx.createFunction(&LLVMF); 2882 auto *ArgAgg = F.getArg(0); 2883 auto *ArgInt = F.getArg(1); 2884 auto *BB = &*F.begin(); 2885 auto It = BB->begin(); 2886 auto *InsSimple = cast<sandboxir::InsertValueInst>(&*It++); 2887 auto *InsNested = cast<sandboxir::InsertValueInst>(&*It++); 2888 // These "const" instructions are helpers to create constant struct operands. 2889 // TODO: Remove them once sandboxir::ConstantStruct gets added. 2890 auto *Const1 = cast<sandboxir::InsertValueInst>(&*It++); 2891 auto *Const2 = cast<sandboxir::InsertValueInst>(&*It++); 2892 auto *Ret = &*It++; 2893 2894 EXPECT_EQ(InsSimple->getOperand(0), ArgAgg); 2895 EXPECT_EQ(InsSimple->getOperand(1), ArgInt); 2896 2897 // create before instruction 2898 auto *NewInsBeforeRet = 2899 cast<sandboxir::InsertValueInst>(sandboxir::InsertValueInst::create( 2900 ArgAgg, ArgInt, ArrayRef<unsigned>({0}), Ret->getIterator(), 2901 Ret->getParent(), Ctx, "NewInsBeforeRet")); 2902 EXPECT_EQ(NewInsBeforeRet->getNextNode(), Ret); 2903 #ifndef NDEBUG 2904 EXPECT_EQ(NewInsBeforeRet->getName(), "NewInsBeforeRet"); 2905 #endif // NDEBUG 2906 2907 // create at end of BB 2908 auto *NewInsAtEnd = 2909 cast<sandboxir::InsertValueInst>(sandboxir::InsertValueInst::create( 2910 ArgAgg, ArgInt, ArrayRef<unsigned>({0}), BB->end(), BB, Ctx, 2911 "NewInsAtEnd")); 2912 EXPECT_EQ(NewInsAtEnd->getPrevNode(), Ret); 2913 #ifndef NDEBUG 2914 EXPECT_EQ(NewInsAtEnd->getName(), "NewInsAtEnd"); 2915 #endif // NDEBUG 2916 2917 // Test the path that creates a folded constant. 2918 auto *Zero = sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 0); 2919 auto *ShouldBeConstant = sandboxir::InsertValueInst::create( 2920 Const1->getOperand(0), Zero, ArrayRef<unsigned>({0}), BB->end(), BB, Ctx); 2921 auto *ExpectedConstant = Const2->getOperand(0); 2922 EXPECT_TRUE(isa<sandboxir::Constant>(ShouldBeConstant)); 2923 EXPECT_EQ(ShouldBeConstant, ExpectedConstant); 2924 2925 // idx_begin / idx_end 2926 { 2927 SmallVector<int, 2> IndicesSimple(InsSimple->idx_begin(), 2928 InsSimple->idx_end()); 2929 EXPECT_THAT(IndicesSimple, testing::ElementsAre(0u)); 2930 2931 SmallVector<int, 2> IndicesNested(InsNested->idx_begin(), 2932 InsNested->idx_end()); 2933 EXPECT_THAT(IndicesNested, testing::ElementsAre(1u, 0u)); 2934 } 2935 2936 // indices 2937 { 2938 SmallVector<int, 2> IndicesSimple(InsSimple->indices()); 2939 EXPECT_THAT(IndicesSimple, testing::ElementsAre(0u)); 2940 2941 SmallVector<int, 2> IndicesNested(InsNested->indices()); 2942 EXPECT_THAT(IndicesNested, testing::ElementsAre(1u, 0u)); 2943 } 2944 2945 // getAggregateOperand 2946 EXPECT_EQ(InsSimple->getAggregateOperand(), ArgAgg); 2947 const auto *ConstInsSimple = InsSimple; 2948 EXPECT_EQ(ConstInsSimple->getAggregateOperand(), ArgAgg); 2949 2950 // getAggregateOperandIndex 2951 EXPECT_EQ(sandboxir::InsertValueInst::getAggregateOperandIndex(), 2952 llvm::InsertValueInst::getAggregateOperandIndex()); 2953 2954 // getInsertedValueOperand 2955 EXPECT_EQ(InsSimple->getInsertedValueOperand(), ArgInt); 2956 EXPECT_EQ(ConstInsSimple->getInsertedValueOperand(), ArgInt); 2957 2958 // getInsertedValueOperandIndex 2959 EXPECT_EQ(sandboxir::InsertValueInst::getInsertedValueOperandIndex(), 2960 llvm::InsertValueInst::getInsertedValueOperandIndex()); 2961 2962 // getIndices 2963 EXPECT_EQ(InsSimple->getIndices().size(), 1u); 2964 EXPECT_EQ(InsSimple->getIndices()[0], 0u); 2965 2966 // getNumIndices 2967 EXPECT_EQ(InsSimple->getNumIndices(), 1u); 2968 2969 // hasIndices 2970 EXPECT_EQ(InsSimple->hasIndices(), true); 2971 } 2972 2973 TEST_F(SandboxIRTest, BranchInst) { 2974 parseIR(C, R"IR( 2975 define void @foo(i1 %cond0, i1 %cond2) { 2976 bb0: 2977 br i1 %cond0, label %bb1, label %bb2 2978 bb1: 2979 ret void 2980 bb2: 2981 ret void 2982 } 2983 )IR"); 2984 llvm::Function *LLVMF = &*M->getFunction("foo"); 2985 sandboxir::Context Ctx(C); 2986 sandboxir::Function *F = Ctx.createFunction(LLVMF); 2987 auto *Cond0 = F->getArg(0); 2988 auto *Cond1 = F->getArg(1); 2989 auto *BB0 = cast<sandboxir::BasicBlock>( 2990 Ctx.getValue(getBasicBlockByName(*LLVMF, "bb0"))); 2991 auto *BB1 = cast<sandboxir::BasicBlock>( 2992 Ctx.getValue(getBasicBlockByName(*LLVMF, "bb1"))); 2993 auto *Ret1 = BB1->getTerminator(); 2994 auto *BB2 = cast<sandboxir::BasicBlock>( 2995 Ctx.getValue(getBasicBlockByName(*LLVMF, "bb2"))); 2996 auto *Ret2 = BB2->getTerminator(); 2997 auto It = BB0->begin(); 2998 auto *Br0 = cast<sandboxir::BranchInst>(&*It++); 2999 // Check isUnconditional(). 3000 EXPECT_FALSE(Br0->isUnconditional()); 3001 // Check isConditional(). 3002 EXPECT_TRUE(Br0->isConditional()); 3003 // Check getCondition(). 3004 EXPECT_EQ(Br0->getCondition(), Cond0); 3005 // Check setCondition(). 3006 Br0->setCondition(Cond1); 3007 EXPECT_EQ(Br0->getCondition(), Cond1); 3008 // Check getNumSuccessors(). 3009 EXPECT_EQ(Br0->getNumSuccessors(), 2u); 3010 // Check getSuccessor(). 3011 EXPECT_EQ(Br0->getSuccessor(0), BB1); 3012 EXPECT_EQ(Br0->getSuccessor(1), BB2); 3013 // Check swapSuccessors(). 3014 Br0->swapSuccessors(); 3015 EXPECT_EQ(Br0->getSuccessor(0), BB2); 3016 EXPECT_EQ(Br0->getSuccessor(1), BB1); 3017 // Check successors(). 3018 EXPECT_EQ(range_size(Br0->successors()), 2u); 3019 unsigned SuccIdx = 0; 3020 SmallVector<sandboxir::BasicBlock *> ExpectedSuccs({BB1, BB2}); 3021 for (sandboxir::BasicBlock *Succ : Br0->successors()) 3022 EXPECT_EQ(Succ, ExpectedSuccs[SuccIdx++]); 3023 3024 { 3025 // Check unconditional BranchInst::create() InsertBefore. 3026 auto *Br = sandboxir::BranchInst::create(BB1, /*InsertBefore=*/Ret1, Ctx); 3027 EXPECT_FALSE(Br->isConditional()); 3028 EXPECT_TRUE(Br->isUnconditional()); 3029 #ifndef NDEBUG 3030 EXPECT_DEATH(Br->getCondition(), ".*condition.*"); 3031 #endif // NDEBUG 3032 unsigned SuccIdx = 0; 3033 SmallVector<sandboxir::BasicBlock *> ExpectedSuccs({BB1}); 3034 for (sandboxir::BasicBlock *Succ : Br->successors()) 3035 EXPECT_EQ(Succ, ExpectedSuccs[SuccIdx++]); 3036 EXPECT_EQ(Br->getNextNode(), Ret1); 3037 } 3038 { 3039 // Check unconditional BranchInst::create() InsertAtEnd. 3040 auto *Br = sandboxir::BranchInst::create(BB1, /*InsertAtEnd=*/BB1, Ctx); 3041 EXPECT_FALSE(Br->isConditional()); 3042 EXPECT_TRUE(Br->isUnconditional()); 3043 #ifndef NDEBUG 3044 EXPECT_DEATH(Br->getCondition(), ".*condition.*"); 3045 #endif // NDEBUG 3046 unsigned SuccIdx = 0; 3047 SmallVector<sandboxir::BasicBlock *> ExpectedSuccs({BB1}); 3048 for (sandboxir::BasicBlock *Succ : Br->successors()) 3049 EXPECT_EQ(Succ, ExpectedSuccs[SuccIdx++]); 3050 EXPECT_EQ(Br->getPrevNode(), Ret1); 3051 } 3052 { 3053 // Check conditional BranchInst::create() InsertBefore. 3054 auto *Br = sandboxir::BranchInst::create(BB1, BB2, Cond0, 3055 /*InsertBefore=*/Ret1, Ctx); 3056 EXPECT_TRUE(Br->isConditional()); 3057 EXPECT_EQ(Br->getCondition(), Cond0); 3058 unsigned SuccIdx = 0; 3059 SmallVector<sandboxir::BasicBlock *> ExpectedSuccs({BB2, BB1}); 3060 for (sandboxir::BasicBlock *Succ : Br->successors()) 3061 EXPECT_EQ(Succ, ExpectedSuccs[SuccIdx++]); 3062 EXPECT_EQ(Br->getNextNode(), Ret1); 3063 } 3064 { 3065 // Check conditional BranchInst::create() InsertAtEnd. 3066 auto *Br = sandboxir::BranchInst::create(BB1, BB2, Cond0, 3067 /*InsertAtEnd=*/BB2, Ctx); 3068 EXPECT_TRUE(Br->isConditional()); 3069 EXPECT_EQ(Br->getCondition(), Cond0); 3070 unsigned SuccIdx = 0; 3071 SmallVector<sandboxir::BasicBlock *> ExpectedSuccs({BB2, BB1}); 3072 for (sandboxir::BasicBlock *Succ : Br->successors()) 3073 EXPECT_EQ(Succ, ExpectedSuccs[SuccIdx++]); 3074 EXPECT_EQ(Br->getPrevNode(), Ret2); 3075 } 3076 } 3077 3078 TEST_F(SandboxIRTest, LoadInst) { 3079 parseIR(C, R"IR( 3080 define void @foo(ptr %arg0, ptr %arg1) { 3081 %ld = load i8, ptr %arg0, align 64 3082 %vld = load volatile i8, ptr %arg0, align 64 3083 ret void 3084 } 3085 )IR"); 3086 llvm::Function *LLVMF = &*M->getFunction("foo"); 3087 sandboxir::Context Ctx(C); 3088 sandboxir::Function *F = Ctx.createFunction(LLVMF); 3089 auto *Arg0 = F->getArg(0); 3090 auto *Arg1 = F->getArg(1); 3091 auto *BB = &*F->begin(); 3092 auto It = BB->begin(); 3093 auto *Ld = cast<sandboxir::LoadInst>(&*It++); 3094 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(Ld)); 3095 auto *VLd = cast<sandboxir::LoadInst>(&*It++); 3096 auto *Ret = cast<sandboxir::ReturnInst>(&*It++); 3097 bool OrigVolatileValue; 3098 3099 // Check isVolatile() 3100 EXPECT_FALSE(Ld->isVolatile()); 3101 // Check isVolatile() 3102 EXPECT_TRUE(VLd->isVolatile()); 3103 // Check getPointerOperand() 3104 EXPECT_EQ(Ld->getPointerOperand(), Arg0); 3105 // Check getAlign() 3106 EXPECT_EQ(Ld->getAlign(), 64); 3107 // Check create(InsertBefore) 3108 sandboxir::LoadInst *NewLd = 3109 sandboxir::LoadInst::create(Ld->getType(), Arg1, Align(8), 3110 /*InsertBefore=*/Ret, Ctx, "NewLd"); 3111 EXPECT_FALSE(NewLd->isVolatile()); 3112 OrigVolatileValue = NewLd->isVolatile(); 3113 NewLd->setVolatile(true); 3114 EXPECT_TRUE(NewLd->isVolatile()); 3115 NewLd->setVolatile(OrigVolatileValue); 3116 EXPECT_FALSE(NewLd->isVolatile()); 3117 EXPECT_EQ(NewLd->getType(), Ld->getType()); 3118 EXPECT_EQ(NewLd->getPointerOperand(), Arg1); 3119 EXPECT_EQ(NewLd->getAlign(), 8); 3120 EXPECT_EQ(NewLd->getName(), "NewLd"); 3121 // Check create(InsertBefore, IsVolatile=true) 3122 sandboxir::LoadInst *NewVLd = 3123 sandboxir::LoadInst::create(VLd->getType(), Arg1, Align(8), 3124 /*InsertBefore=*/Ret, 3125 /*IsVolatile=*/true, Ctx, "NewVLd"); 3126 3127 EXPECT_TRUE(NewVLd->isVolatile()); 3128 OrigVolatileValue = NewVLd->isVolatile(); 3129 NewVLd->setVolatile(false); 3130 EXPECT_FALSE(NewVLd->isVolatile()); 3131 NewVLd->setVolatile(OrigVolatileValue); 3132 EXPECT_TRUE(NewVLd->isVolatile()); 3133 EXPECT_EQ(NewVLd->getName(), "NewVLd"); 3134 // Check create(InsertAtEnd) 3135 sandboxir::LoadInst *NewLdEnd = 3136 sandboxir::LoadInst::create(Ld->getType(), Arg1, Align(8), 3137 /*InsertAtEnd=*/BB, Ctx, "NewLdEnd"); 3138 EXPECT_FALSE(NewLdEnd->isVolatile()); 3139 EXPECT_EQ(NewLdEnd->getName(), "NewLdEnd"); 3140 EXPECT_EQ(NewLdEnd->getType(), Ld->getType()); 3141 EXPECT_EQ(NewLdEnd->getPointerOperand(), Arg1); 3142 EXPECT_EQ(NewLdEnd->getAlign(), 8); 3143 EXPECT_EQ(NewLdEnd->getParent(), BB); 3144 EXPECT_EQ(NewLdEnd->getNextNode(), nullptr); 3145 // Check create(InsertAtEnd, IsVolatile=true) 3146 sandboxir::LoadInst *NewVLdEnd = 3147 sandboxir::LoadInst::create(VLd->getType(), Arg1, Align(8), 3148 /*InsertAtEnd=*/BB, 3149 /*IsVolatile=*/true, Ctx, "NewVLdEnd"); 3150 EXPECT_TRUE(NewVLdEnd->isVolatile()); 3151 EXPECT_EQ(NewVLdEnd->getName(), "NewVLdEnd"); 3152 EXPECT_EQ(NewVLdEnd->getType(), VLd->getType()); 3153 EXPECT_EQ(NewVLdEnd->getPointerOperand(), Arg1); 3154 EXPECT_EQ(NewVLdEnd->getAlign(), 8); 3155 EXPECT_EQ(NewVLdEnd->getParent(), BB); 3156 EXPECT_EQ(NewVLdEnd->getNextNode(), nullptr); 3157 } 3158 3159 TEST_F(SandboxIRTest, StoreInst) { 3160 parseIR(C, R"IR( 3161 define void @foo(i8 %val, ptr %ptr) { 3162 store i8 %val, ptr %ptr, align 64 3163 store volatile i8 %val, ptr %ptr, align 64 3164 ret void 3165 } 3166 )IR"); 3167 llvm::Function *LLVMF = &*M->getFunction("foo"); 3168 sandboxir::Context Ctx(C); 3169 sandboxir::Function *F = Ctx.createFunction(LLVMF); 3170 auto *Val = F->getArg(0); 3171 auto *Ptr = F->getArg(1); 3172 auto *BB = &*F->begin(); 3173 auto It = BB->begin(); 3174 auto *St = cast<sandboxir::StoreInst>(&*It++); 3175 auto *VSt = cast<sandboxir::StoreInst>(&*It++); 3176 auto *Ret = cast<sandboxir::ReturnInst>(&*It++); 3177 bool OrigVolatileValue; 3178 3179 // Check that the StoreInst has been created correctly. 3180 EXPECT_FALSE(St->isVolatile()); 3181 EXPECT_TRUE(VSt->isVolatile()); 3182 // Check getPointerOperand() 3183 EXPECT_EQ(St->getValueOperand(), Val); 3184 EXPECT_EQ(St->getPointerOperand(), Ptr); 3185 // Check getAlign() 3186 EXPECT_EQ(St->getAlign(), 64); 3187 // Check create(InsertBefore) 3188 sandboxir::StoreInst *NewSt = 3189 sandboxir::StoreInst::create(Val, Ptr, Align(8), 3190 /*InsertBefore=*/Ret, Ctx); 3191 EXPECT_FALSE(NewSt->isVolatile()); 3192 OrigVolatileValue = NewSt->isVolatile(); 3193 NewSt->setVolatile(true); 3194 EXPECT_TRUE(NewSt->isVolatile()); 3195 NewSt->setVolatile(OrigVolatileValue); 3196 EXPECT_FALSE(NewSt->isVolatile()); 3197 EXPECT_EQ(NewSt->getType(), St->getType()); 3198 EXPECT_EQ(NewSt->getValueOperand(), Val); 3199 EXPECT_EQ(NewSt->getPointerOperand(), Ptr); 3200 EXPECT_EQ(NewSt->getAlign(), 8); 3201 EXPECT_EQ(NewSt->getNextNode(), Ret); 3202 // Check create(InsertBefore, IsVolatile=true) 3203 sandboxir::StoreInst *NewVSt = 3204 sandboxir::StoreInst::create(Val, Ptr, Align(8), 3205 /*InsertBefore=*/Ret, 3206 /*IsVolatile=*/true, Ctx); 3207 EXPECT_TRUE(NewVSt->isVolatile()); 3208 OrigVolatileValue = NewVSt->isVolatile(); 3209 NewVSt->setVolatile(false); 3210 EXPECT_FALSE(NewVSt->isVolatile()); 3211 NewVSt->setVolatile(OrigVolatileValue); 3212 EXPECT_TRUE(NewVSt->isVolatile()); 3213 EXPECT_EQ(NewVSt->getType(), VSt->getType()); 3214 EXPECT_EQ(NewVSt->getValueOperand(), Val); 3215 EXPECT_EQ(NewVSt->getPointerOperand(), Ptr); 3216 EXPECT_EQ(NewVSt->getAlign(), 8); 3217 EXPECT_EQ(NewVSt->getNextNode(), Ret); 3218 // Check create(InsertAtEnd) 3219 sandboxir::StoreInst *NewStEnd = 3220 sandboxir::StoreInst::create(Val, Ptr, Align(8), 3221 /*InsertAtEnd=*/BB, Ctx); 3222 EXPECT_FALSE(NewStEnd->isVolatile()); 3223 EXPECT_EQ(NewStEnd->getType(), St->getType()); 3224 EXPECT_EQ(NewStEnd->getValueOperand(), Val); 3225 EXPECT_EQ(NewStEnd->getPointerOperand(), Ptr); 3226 EXPECT_EQ(NewStEnd->getAlign(), 8); 3227 EXPECT_EQ(NewStEnd->getParent(), BB); 3228 EXPECT_EQ(NewStEnd->getNextNode(), nullptr); 3229 // Check create(InsertAtEnd, IsVolatile=true) 3230 sandboxir::StoreInst *NewVStEnd = 3231 sandboxir::StoreInst::create(Val, Ptr, Align(8), 3232 /*InsertAtEnd=*/BB, 3233 /*IsVolatile=*/true, Ctx); 3234 EXPECT_TRUE(NewVStEnd->isVolatile()); 3235 EXPECT_EQ(NewVStEnd->getType(), VSt->getType()); 3236 EXPECT_EQ(NewVStEnd->getValueOperand(), Val); 3237 EXPECT_EQ(NewVStEnd->getPointerOperand(), Ptr); 3238 EXPECT_EQ(NewVStEnd->getAlign(), 8); 3239 EXPECT_EQ(NewVStEnd->getParent(), BB); 3240 EXPECT_EQ(NewVStEnd->getNextNode(), nullptr); 3241 } 3242 3243 TEST_F(SandboxIRTest, ReturnInst) { 3244 parseIR(C, R"IR( 3245 define i8 @foo(i8 %val) { 3246 %add = add i8 %val, 42 3247 ret i8 %val 3248 } 3249 )IR"); 3250 llvm::Function *LLVMF = &*M->getFunction("foo"); 3251 sandboxir::Context Ctx(C); 3252 sandboxir::Function *F = Ctx.createFunction(LLVMF); 3253 auto *Val = F->getArg(0); 3254 auto *BB = &*F->begin(); 3255 auto It = BB->begin(); 3256 It++; 3257 auto *Ret = cast<sandboxir::ReturnInst>(&*It++); 3258 3259 // Check that the ReturnInst has been created correctly. 3260 // Check getReturnValue(). 3261 EXPECT_EQ(Ret->getReturnValue(), Val); 3262 3263 // Check create(InsertBefore) a void ReturnInst. 3264 auto *NewRet1 = cast<sandboxir::ReturnInst>( 3265 sandboxir::ReturnInst::create(nullptr, /*InsertBefore=*/Ret, Ctx)); 3266 EXPECT_EQ(NewRet1->getReturnValue(), nullptr); 3267 // Check create(InsertBefore) a non-void ReturnInst. 3268 auto *NewRet2 = cast<sandboxir::ReturnInst>( 3269 sandboxir::ReturnInst::create(Val, /*InsertBefore=*/Ret, Ctx)); 3270 EXPECT_EQ(NewRet2->getReturnValue(), Val); 3271 3272 // Check create(InsertAtEnd) a void ReturnInst. 3273 auto *NewRet3 = cast<sandboxir::ReturnInst>( 3274 sandboxir::ReturnInst::create(nullptr, /*InsertAtEnd=*/BB, Ctx)); 3275 EXPECT_EQ(NewRet3->getReturnValue(), nullptr); 3276 // Check create(InsertAtEnd) a non-void ReturnInst. 3277 auto *NewRet4 = cast<sandboxir::ReturnInst>( 3278 sandboxir::ReturnInst::create(Val, /*InsertAtEnd=*/BB, Ctx)); 3279 EXPECT_EQ(NewRet4->getReturnValue(), Val); 3280 } 3281 3282 TEST_F(SandboxIRTest, CallBase) { 3283 parseIR(C, R"IR( 3284 declare void @bar1(i8) 3285 declare void @bar2() 3286 declare void @bar3() 3287 declare void @variadic(ptr, ...) 3288 3289 define i8 @foo(i8 %arg0, i32 %arg1, ptr %indirectFoo) { 3290 %call = call i8 @foo(i8 %arg0, i32 %arg1) 3291 call void @bar1(i8 %arg0) 3292 call void @bar2() 3293 call void %indirectFoo() 3294 call void @bar2() noreturn 3295 tail call fastcc void @bar2() 3296 call void (ptr, ...) @variadic(ptr %indirectFoo, i32 1) 3297 ret i8 %call 3298 } 3299 )IR"); 3300 llvm::Function &LLVMF = *M->getFunction("foo"); 3301 unsigned ArgIdx = 0; 3302 llvm::Argument *LLVMArg0 = LLVMF.getArg(ArgIdx++); 3303 llvm::Argument *LLVMArg1 = LLVMF.getArg(ArgIdx++); 3304 llvm::BasicBlock *LLVMBB = &*LLVMF.begin(); 3305 SmallVector<llvm::CallBase *, 8> LLVMCalls; 3306 auto LLVMIt = LLVMBB->begin(); 3307 while (isa<llvm::CallBase>(&*LLVMIt)) 3308 LLVMCalls.push_back(cast<llvm::CallBase>(&*LLVMIt++)); 3309 3310 sandboxir::Context Ctx(C); 3311 sandboxir::Function &F = *Ctx.createFunction(&LLVMF); 3312 3313 for (llvm::CallBase *LLVMCall : LLVMCalls) { 3314 // Check classof(Instruction *). 3315 auto *Call = cast<sandboxir::CallBase>(Ctx.getValue(LLVMCall)); 3316 // Check classof(Value *). 3317 EXPECT_TRUE(isa<sandboxir::CallBase>((sandboxir::Value *)Call)); 3318 // Check getFunctionType(). 3319 EXPECT_EQ(Call->getFunctionType(), 3320 Ctx.getType(LLVMCall->getFunctionType())); 3321 // Check data_ops(). 3322 EXPECT_EQ(range_size(Call->data_ops()), range_size(LLVMCall->data_ops())); 3323 auto DataOpIt = Call->data_operands_begin(); 3324 for (llvm::Use &LLVMUse : LLVMCall->data_ops()) { 3325 Value *LLVMOp = LLVMUse.get(); 3326 sandboxir::Use Use = *DataOpIt++; 3327 EXPECT_EQ(Ctx.getValue(LLVMOp), Use.get()); 3328 // Check isDataOperand(). 3329 EXPECT_EQ(Call->isDataOperand(Use), LLVMCall->isDataOperand(&LLVMUse)); 3330 // Check getDataOperandNo(). 3331 EXPECT_EQ(Call->getDataOperandNo(Use), 3332 LLVMCall->getDataOperandNo(&LLVMUse)); 3333 // Check isArgOperand(). 3334 EXPECT_EQ(Call->isArgOperand(Use), LLVMCall->isArgOperand(&LLVMUse)); 3335 // Check isCallee(). 3336 EXPECT_EQ(Call->isCallee(Use), LLVMCall->isCallee(&LLVMUse)); 3337 } 3338 // Check data_operands_empty(). 3339 EXPECT_EQ(Call->data_operands_empty(), LLVMCall->data_operands_empty()); 3340 // Check data_operands_size(). 3341 EXPECT_EQ(Call->data_operands_size(), LLVMCall->data_operands_size()); 3342 // Check getNumTotalBundleOperands(). 3343 EXPECT_EQ(Call->getNumTotalBundleOperands(), 3344 LLVMCall->getNumTotalBundleOperands()); 3345 // Check args(). 3346 EXPECT_EQ(range_size(Call->args()), range_size(LLVMCall->args())); 3347 auto ArgIt = Call->arg_begin(); 3348 for (llvm::Use &LLVMUse : LLVMCall->args()) { 3349 Value *LLVMArg = LLVMUse.get(); 3350 sandboxir::Use Use = *ArgIt++; 3351 EXPECT_EQ(Ctx.getValue(LLVMArg), Use.get()); 3352 } 3353 // Check arg_empty(). 3354 EXPECT_EQ(Call->arg_empty(), LLVMCall->arg_empty()); 3355 // Check arg_size(). 3356 EXPECT_EQ(Call->arg_size(), LLVMCall->arg_size()); 3357 for (unsigned ArgIdx = 0, E = Call->arg_size(); ArgIdx != E; ++ArgIdx) { 3358 // Check getArgOperand(). 3359 EXPECT_EQ(Call->getArgOperand(ArgIdx), 3360 Ctx.getValue(LLVMCall->getArgOperand(ArgIdx))); 3361 // Check getArgOperandUse(). 3362 sandboxir::Use Use = Call->getArgOperandUse(ArgIdx); 3363 llvm::Use &LLVMUse = LLVMCall->getArgOperandUse(ArgIdx); 3364 EXPECT_EQ(Use.get(), Ctx.getValue(LLVMUse.get())); 3365 // Check getArgOperandNo(). 3366 EXPECT_EQ(Call->getArgOperandNo(Use), 3367 LLVMCall->getArgOperandNo(&LLVMUse)); 3368 } 3369 // Check hasArgument(). 3370 SmallVector<llvm::Value *> TestArgs( 3371 {LLVMArg0, LLVMArg1, &LLVMF, LLVMBB, LLVMCall}); 3372 for (llvm::Value *LLVMV : TestArgs) { 3373 sandboxir::Value *V = Ctx.getValue(LLVMV); 3374 EXPECT_EQ(Call->hasArgument(V), LLVMCall->hasArgument(LLVMV)); 3375 } 3376 // Check getCalledOperand(). 3377 EXPECT_EQ(Call->getCalledOperand(), 3378 Ctx.getValue(LLVMCall->getCalledOperand())); 3379 // Check getCalledOperandUse(). 3380 EXPECT_EQ(Call->getCalledOperandUse().get(), 3381 Ctx.getValue(LLVMCall->getCalledOperandUse())); 3382 // Check getCalledFunction(). 3383 if (LLVMCall->getCalledFunction() == nullptr) 3384 EXPECT_EQ(Call->getCalledFunction(), nullptr); 3385 else { 3386 auto *LLVMCF = cast<llvm::Function>(LLVMCall->getCalledFunction()); 3387 (void)LLVMCF; 3388 EXPECT_EQ(Call->getCalledFunction(), 3389 cast<sandboxir::Function>( 3390 Ctx.getValue(LLVMCall->getCalledFunction()))); 3391 } 3392 // Check isIndirectCall(). 3393 EXPECT_EQ(Call->isIndirectCall(), LLVMCall->isIndirectCall()); 3394 // Check getCaller(). 3395 EXPECT_EQ(Call->getCaller(), Ctx.getValue(LLVMCall->getCaller())); 3396 // Check isMustTailCall(). 3397 EXPECT_EQ(Call->isMustTailCall(), LLVMCall->isMustTailCall()); 3398 // Check isTailCall(). 3399 EXPECT_EQ(Call->isTailCall(), LLVMCall->isTailCall()); 3400 // Check getIntrinsicID(). 3401 EXPECT_EQ(Call->getIntrinsicID(), LLVMCall->getIntrinsicID()); 3402 // Check getCallingConv(). 3403 EXPECT_EQ(Call->getCallingConv(), LLVMCall->getCallingConv()); 3404 // Check isInlineAsm(). 3405 EXPECT_EQ(Call->isInlineAsm(), LLVMCall->isInlineAsm()); 3406 } 3407 3408 auto *Arg0 = F.getArg(0); 3409 auto *Arg1 = F.getArg(1); 3410 auto *BB = &*F.begin(); 3411 auto It = BB->begin(); 3412 auto *Call0 = cast<sandboxir::CallBase>(&*It++); 3413 [[maybe_unused]] auto *Call1 = cast<sandboxir::CallBase>(&*It++); 3414 auto *Call2 = cast<sandboxir::CallBase>(&*It++); 3415 // Check setArgOperand 3416 Call0->setArgOperand(0, Arg1); 3417 EXPECT_EQ(Call0->getArgOperand(0), Arg1); 3418 Call0->setArgOperand(0, Arg0); 3419 EXPECT_EQ(Call0->getArgOperand(0), Arg0); 3420 3421 auto *Bar3F = Ctx.createFunction(M->getFunction("bar3")); 3422 3423 // Check setCalledOperand 3424 auto *SvOp = Call0->getCalledOperand(); 3425 Call0->setCalledOperand(Bar3F); 3426 EXPECT_EQ(Call0->getCalledOperand(), Bar3F); 3427 Call0->setCalledOperand(SvOp); 3428 // Check setCalledFunction 3429 Call2->setCalledFunction(Bar3F); 3430 EXPECT_EQ(Call2->getCalledFunction(), Bar3F); 3431 } 3432 3433 TEST_F(SandboxIRTest, CallInst) { 3434 parseIR(C, R"IR( 3435 define i8 @foo(i8 %arg) { 3436 %call = call i8 @foo(i8 %arg) 3437 ret i8 %call 3438 } 3439 )IR"); 3440 Function &LLVMF = *M->getFunction("foo"); 3441 sandboxir::Context Ctx(C); 3442 auto &F = *Ctx.createFunction(&LLVMF); 3443 unsigned ArgIdx = 0; 3444 auto *Arg0 = F.getArg(ArgIdx++); 3445 auto *BB = &*F.begin(); 3446 auto It = BB->begin(); 3447 auto *Call = cast<sandboxir::CallInst>(&*It++); 3448 auto *Ret = cast<sandboxir::ReturnInst>(&*It++); 3449 EXPECT_EQ(Call->getNumOperands(), 2u); 3450 EXPECT_EQ(Ret->getOpcode(), sandboxir::Instruction::Opcode::Ret); 3451 sandboxir::FunctionType *FTy = F.getFunctionType(); 3452 SmallVector<sandboxir::Value *, 1> Args; 3453 Args.push_back(Arg0); 3454 { 3455 // Check create() WhereIt. 3456 auto *Call = cast<sandboxir::CallInst>(sandboxir::CallInst::create( 3457 FTy, &F, Args, /*WhereIt=*/Ret->getIterator(), BB, Ctx)); 3458 EXPECT_EQ(Call->getNextNode(), Ret); 3459 EXPECT_EQ(Call->getCalledFunction(), &F); 3460 EXPECT_EQ(range_size(Call->args()), 1u); 3461 EXPECT_EQ(Call->getArgOperand(0), Arg0); 3462 } 3463 { 3464 // Check create() InsertBefore. 3465 auto *Call = cast<sandboxir::CallInst>( 3466 sandboxir::CallInst::create(FTy, &F, Args, /*InsertBefore=*/Ret, Ctx)); 3467 EXPECT_EQ(Call->getNextNode(), Ret); 3468 EXPECT_EQ(Call->getCalledFunction(), &F); 3469 EXPECT_EQ(range_size(Call->args()), 1u); 3470 EXPECT_EQ(Call->getArgOperand(0), Arg0); 3471 } 3472 { 3473 // Check create() InsertAtEnd. 3474 auto *Call = cast<sandboxir::CallInst>( 3475 sandboxir::CallInst::create(FTy, &F, Args, /*InsertAtEnd=*/BB, Ctx)); 3476 EXPECT_EQ(Call->getPrevNode(), Ret); 3477 EXPECT_EQ(Call->getCalledFunction(), &F); 3478 EXPECT_EQ(range_size(Call->args()), 1u); 3479 EXPECT_EQ(Call->getArgOperand(0), Arg0); 3480 } 3481 } 3482 3483 TEST_F(SandboxIRTest, InvokeInst) { 3484 parseIR(C, R"IR( 3485 define void @foo(i8 %arg) { 3486 bb0: 3487 invoke i8 @foo(i8 %arg) to label %normal_bb 3488 unwind label %exception_bb 3489 normal_bb: 3490 ret void 3491 exception_bb: 3492 %lpad = landingpad { ptr, i32} 3493 cleanup 3494 ret void 3495 other_bb: 3496 ret void 3497 } 3498 )IR"); 3499 Function &LLVMF = *M->getFunction("foo"); 3500 sandboxir::Context Ctx(C); 3501 auto &F = *Ctx.createFunction(&LLVMF); 3502 auto *Arg = F.getArg(0); 3503 auto *BB0 = cast<sandboxir::BasicBlock>( 3504 Ctx.getValue(getBasicBlockByName(LLVMF, "bb0"))); 3505 auto *NormalBB = cast<sandboxir::BasicBlock>( 3506 Ctx.getValue(getBasicBlockByName(LLVMF, "normal_bb"))); 3507 auto *ExceptionBB = cast<sandboxir::BasicBlock>( 3508 Ctx.getValue(getBasicBlockByName(LLVMF, "exception_bb"))); 3509 auto *LandingPad = &*ExceptionBB->begin(); 3510 auto *OtherBB = cast<sandboxir::BasicBlock>( 3511 Ctx.getValue(getBasicBlockByName(LLVMF, "other_bb"))); 3512 auto It = BB0->begin(); 3513 // Check classof(Instruction *). 3514 auto *Invoke = cast<sandboxir::InvokeInst>(&*It++); 3515 3516 // Check getNormalDest(). 3517 EXPECT_EQ(Invoke->getNormalDest(), NormalBB); 3518 // Check getUnwindDest(). 3519 EXPECT_EQ(Invoke->getUnwindDest(), ExceptionBB); 3520 // Check getSuccessor(). 3521 EXPECT_EQ(Invoke->getSuccessor(0), NormalBB); 3522 EXPECT_EQ(Invoke->getSuccessor(1), ExceptionBB); 3523 // Check setNormalDest(). 3524 Invoke->setNormalDest(OtherBB); 3525 EXPECT_EQ(Invoke->getNormalDest(), OtherBB); 3526 EXPECT_EQ(Invoke->getUnwindDest(), ExceptionBB); 3527 // Check setUnwindDest(). 3528 Invoke->setUnwindDest(OtherBB); 3529 EXPECT_EQ(Invoke->getNormalDest(), OtherBB); 3530 EXPECT_EQ(Invoke->getUnwindDest(), OtherBB); 3531 // Check setSuccessor(). 3532 Invoke->setSuccessor(0, NormalBB); 3533 EXPECT_EQ(Invoke->getNormalDest(), NormalBB); 3534 Invoke->setSuccessor(1, ExceptionBB); 3535 EXPECT_EQ(Invoke->getUnwindDest(), ExceptionBB); 3536 // Check getLandingPadInst(). 3537 EXPECT_EQ(Invoke->getLandingPadInst(), LandingPad); 3538 3539 { 3540 // Check create() WhereIt, WhereBB. 3541 SmallVector<sandboxir::Value *> Args({Arg}); 3542 auto *InsertBefore = &*BB0->begin(); 3543 auto *NewInvoke = cast<sandboxir::InvokeInst>(sandboxir::InvokeInst::create( 3544 F.getFunctionType(), &F, NormalBB, ExceptionBB, Args, 3545 /*WhereIt=*/InsertBefore->getIterator(), /*WhereBB=*/BB0, Ctx)); 3546 EXPECT_EQ(NewInvoke->getNormalDest(), NormalBB); 3547 EXPECT_EQ(NewInvoke->getUnwindDest(), ExceptionBB); 3548 EXPECT_EQ(NewInvoke->getNextNode(), InsertBefore); 3549 } 3550 { 3551 // Check create() InsertBefore. 3552 SmallVector<sandboxir::Value *> Args({Arg}); 3553 auto *InsertBefore = &*BB0->begin(); 3554 auto *NewInvoke = cast<sandboxir::InvokeInst>( 3555 sandboxir::InvokeInst::create(F.getFunctionType(), &F, NormalBB, 3556 ExceptionBB, Args, InsertBefore, Ctx)); 3557 EXPECT_EQ(NewInvoke->getNormalDest(), NormalBB); 3558 EXPECT_EQ(NewInvoke->getUnwindDest(), ExceptionBB); 3559 EXPECT_EQ(NewInvoke->getNextNode(), InsertBefore); 3560 } 3561 { 3562 // Check create() InsertAtEnd. 3563 SmallVector<sandboxir::Value *> Args({Arg}); 3564 auto *NewInvoke = cast<sandboxir::InvokeInst>(sandboxir::InvokeInst::create( 3565 F.getFunctionType(), &F, NormalBB, ExceptionBB, Args, 3566 /*InsertAtEnd=*/BB0, Ctx)); 3567 EXPECT_EQ(NewInvoke->getNormalDest(), NormalBB); 3568 EXPECT_EQ(NewInvoke->getUnwindDest(), ExceptionBB); 3569 EXPECT_EQ(NewInvoke->getParent(), BB0); 3570 EXPECT_EQ(NewInvoke->getNextNode(), nullptr); 3571 } 3572 } 3573 3574 TEST_F(SandboxIRTest, CallBrInst) { 3575 parseIR(C, R"IR( 3576 define void @foo(i8 %arg) { 3577 bb0: 3578 callbr void asm "", ""() 3579 to label %bb1 [label %bb2] 3580 bb1: 3581 ret void 3582 bb2: 3583 ret void 3584 other_bb: 3585 ret void 3586 bb3: 3587 callbr void @foo(i8 %arg) 3588 to label %bb1 [label %bb2] 3589 } 3590 )IR"); 3591 Function &LLVMF = *M->getFunction("foo"); 3592 auto *LLVMBB0 = getBasicBlockByName(LLVMF, "bb0"); 3593 auto *LLVMCallBr = cast<llvm::CallBrInst>(&*LLVMBB0->begin()); 3594 sandboxir::Context Ctx(C); 3595 auto &F = *Ctx.createFunction(&LLVMF); 3596 auto *Arg = F.getArg(0); 3597 auto *BB0 = cast<sandboxir::BasicBlock>( 3598 Ctx.getValue(getBasicBlockByName(LLVMF, "bb0"))); 3599 auto *BB1 = cast<sandboxir::BasicBlock>( 3600 Ctx.getValue(getBasicBlockByName(LLVMF, "bb1"))); 3601 auto *BB2 = cast<sandboxir::BasicBlock>( 3602 Ctx.getValue(getBasicBlockByName(LLVMF, "bb2"))); 3603 auto *BB3 = cast<sandboxir::BasicBlock>( 3604 Ctx.getValue(getBasicBlockByName(LLVMF, "bb3"))); 3605 auto *OtherBB = cast<sandboxir::BasicBlock>( 3606 Ctx.getValue(getBasicBlockByName(LLVMF, "other_bb"))); 3607 auto It = BB0->begin(); 3608 // Check classof(Instruction *). 3609 auto *CallBr0 = cast<sandboxir::CallBrInst>(&*It++); 3610 3611 It = BB3->begin(); 3612 auto *CallBr1 = cast<sandboxir::CallBrInst>(&*It++); 3613 for (sandboxir::CallBrInst *CallBr : {CallBr0, CallBr1}) { 3614 // Check getNumIndirectDests(). 3615 EXPECT_EQ(CallBr->getNumIndirectDests(), 1u); 3616 // Check getIndirectDestLabel(). 3617 EXPECT_EQ(CallBr->getIndirectDestLabel(0), 3618 Ctx.getValue(LLVMCallBr->getIndirectDestLabel(0))); 3619 // Check getIndirectDestLabelUse(). 3620 EXPECT_EQ(CallBr->getIndirectDestLabelUse(0), 3621 Ctx.getValue(LLVMCallBr->getIndirectDestLabelUse(0))); 3622 // Check getDefaultDest(). 3623 EXPECT_EQ(CallBr->getDefaultDest(), 3624 Ctx.getValue(LLVMCallBr->getDefaultDest())); 3625 // Check getIndirectDest(). 3626 EXPECT_EQ(CallBr->getIndirectDest(0), 3627 Ctx.getValue(LLVMCallBr->getIndirectDest(0))); 3628 // Check getIndirectDests(). 3629 auto Dests = CallBr->getIndirectDests(); 3630 EXPECT_EQ(Dests.size(), LLVMCallBr->getIndirectDests().size()); 3631 EXPECT_EQ(Dests[0], Ctx.getValue(LLVMCallBr->getIndirectDests()[0])); 3632 // Check getNumSuccessors(). 3633 EXPECT_EQ(CallBr->getNumSuccessors(), LLVMCallBr->getNumSuccessors()); 3634 // Check getSuccessor(). 3635 for (unsigned SuccIdx = 0, E = CallBr->getNumSuccessors(); SuccIdx != E; 3636 ++SuccIdx) 3637 EXPECT_EQ(CallBr->getSuccessor(SuccIdx), 3638 Ctx.getValue(LLVMCallBr->getSuccessor(SuccIdx))); 3639 // Check setDefaultDest(). 3640 auto *SvDefaultDest = CallBr->getDefaultDest(); 3641 CallBr->setDefaultDest(OtherBB); 3642 EXPECT_EQ(CallBr->getDefaultDest(), OtherBB); 3643 CallBr->setDefaultDest(SvDefaultDest); 3644 // Check setIndirectDest(). 3645 auto *SvIndirectDest = CallBr->getIndirectDest(0); 3646 CallBr->setIndirectDest(0, OtherBB); 3647 EXPECT_EQ(CallBr->getIndirectDest(0), OtherBB); 3648 CallBr->setIndirectDest(0, SvIndirectDest); 3649 } 3650 3651 { 3652 // Check create() WhereIt, WhereBB. 3653 SmallVector<sandboxir::Value *> Args({Arg}); 3654 auto *NewCallBr = cast<sandboxir::CallBrInst>(sandboxir::CallBrInst::create( 3655 F.getFunctionType(), &F, BB1, {BB2}, Args, /*WhereIt=*/BB0->end(), 3656 /*WhereBB=*/BB0, Ctx)); 3657 EXPECT_EQ(NewCallBr->getDefaultDest(), BB1); 3658 EXPECT_EQ(NewCallBr->getIndirectDests().size(), 1u); 3659 EXPECT_EQ(NewCallBr->getIndirectDests()[0], BB2); 3660 EXPECT_EQ(NewCallBr->getNextNode(), nullptr); 3661 EXPECT_EQ(NewCallBr->getParent(), BB0); 3662 } 3663 { 3664 // Check create() InsertBefore 3665 SmallVector<sandboxir::Value *> Args({Arg}); 3666 auto *InsertBefore = &*BB0->rbegin(); 3667 auto *NewCallBr = cast<sandboxir::CallBrInst>(sandboxir::CallBrInst::create( 3668 F.getFunctionType(), &F, BB1, {BB2}, Args, InsertBefore, Ctx)); 3669 EXPECT_EQ(NewCallBr->getDefaultDest(), BB1); 3670 EXPECT_EQ(NewCallBr->getIndirectDests().size(), 1u); 3671 EXPECT_EQ(NewCallBr->getIndirectDests()[0], BB2); 3672 EXPECT_EQ(NewCallBr->getNextNode(), InsertBefore); 3673 } 3674 { 3675 // Check create() InsertAtEnd. 3676 SmallVector<sandboxir::Value *> Args({Arg}); 3677 auto *NewCallBr = cast<sandboxir::CallBrInst>( 3678 sandboxir::CallBrInst::create(F.getFunctionType(), &F, BB1, {BB2}, Args, 3679 /*InsertAtEnd=*/BB0, Ctx)); 3680 EXPECT_EQ(NewCallBr->getDefaultDest(), BB1); 3681 EXPECT_EQ(NewCallBr->getIndirectDests().size(), 1u); 3682 EXPECT_EQ(NewCallBr->getIndirectDests()[0], BB2); 3683 EXPECT_EQ(NewCallBr->getNextNode(), nullptr); 3684 EXPECT_EQ(NewCallBr->getParent(), BB0); 3685 } 3686 } 3687 3688 TEST_F(SandboxIRTest, LandingPadInst) { 3689 parseIR(C, R"IR( 3690 define void @foo() { 3691 entry: 3692 invoke void @foo() 3693 to label %bb unwind label %unwind 3694 unwind: 3695 %lpad = landingpad { ptr, i32 } 3696 catch ptr null 3697 ret void 3698 bb: 3699 ret void 3700 } 3701 )IR"); 3702 Function &LLVMF = *M->getFunction("foo"); 3703 auto *LLVMUnwind = getBasicBlockByName(LLVMF, "unwind"); 3704 auto *LLVMLPad = cast<llvm::LandingPadInst>(&*LLVMUnwind->begin()); 3705 3706 sandboxir::Context Ctx(C); 3707 [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF); 3708 auto *Unwind = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMUnwind)); 3709 auto *BB = cast<sandboxir::BasicBlock>( 3710 Ctx.getValue(getBasicBlockByName(LLVMF, "bb"))); 3711 auto It = Unwind->begin(); 3712 auto *LPad = cast<sandboxir::LandingPadInst>(&*It++); 3713 [[maybe_unused]] auto *Ret = cast<sandboxir::ReturnInst>(&*It++); 3714 3715 // Check isCleanup(). 3716 EXPECT_EQ(LPad->isCleanup(), LLVMLPad->isCleanup()); 3717 // Check setCleanup(). 3718 auto OrigIsCleanup = LPad->isCleanup(); 3719 auto NewIsCleanup = true; 3720 EXPECT_NE(NewIsCleanup, OrigIsCleanup); 3721 LPad->setCleanup(NewIsCleanup); 3722 EXPECT_EQ(LPad->isCleanup(), NewIsCleanup); 3723 LPad->setCleanup(OrigIsCleanup); 3724 EXPECT_EQ(LPad->isCleanup(), OrigIsCleanup); 3725 // Check getNumClauses(). 3726 EXPECT_EQ(LPad->getNumClauses(), LLVMLPad->getNumClauses()); 3727 // Check getClause(). 3728 for (auto Idx : seq<unsigned>(0, LPad->getNumClauses())) 3729 EXPECT_EQ(LPad->getClause(Idx), Ctx.getValue(LLVMLPad->getClause(Idx))); 3730 // Check isCatch(). 3731 for (auto Idx : seq<unsigned>(0, LPad->getNumClauses())) 3732 EXPECT_EQ(LPad->isCatch(Idx), LLVMLPad->isCatch(Idx)); 3733 // Check isFilter(). 3734 for (auto Idx : seq<unsigned>(0, LPad->getNumClauses())) 3735 EXPECT_EQ(LPad->isFilter(Idx), LLVMLPad->isFilter(Idx)); 3736 // Check create(). 3737 auto *BBRet = &*BB->begin(); 3738 auto *NewLPad = 3739 cast<sandboxir::LandingPadInst>(sandboxir::LandingPadInst::create( 3740 sandboxir::Type::getInt8Ty(Ctx), 0, BBRet->getIterator(), 3741 BBRet->getParent(), Ctx, "NewLPad")); 3742 EXPECT_EQ(NewLPad->getNextNode(), BBRet); 3743 EXPECT_FALSE(NewLPad->isCleanup()); 3744 #ifndef NDEBUG 3745 EXPECT_EQ(NewLPad->getName(), "NewLPad"); 3746 #endif // NDEBUG 3747 } 3748 3749 TEST_F(SandboxIRTest, FuncletPadInst_CatchPadInst_CleanupPadInst) { 3750 parseIR(C, R"IR( 3751 define void @foo() { 3752 dispatch: 3753 %cs = catchswitch within none [label %handler0] unwind to caller 3754 handler0: 3755 %catchpad = catchpad within %cs [ptr @foo] 3756 ret void 3757 handler1: 3758 %cleanuppad = cleanuppad within %cs [ptr @foo] 3759 ret void 3760 bb: 3761 ret void 3762 } 3763 )IR"); 3764 Function &LLVMF = *M->getFunction("foo"); 3765 BasicBlock *LLVMDispatch = getBasicBlockByName(LLVMF, "dispatch"); 3766 BasicBlock *LLVMHandler0 = getBasicBlockByName(LLVMF, "handler0"); 3767 BasicBlock *LLVMHandler1 = getBasicBlockByName(LLVMF, "handler1"); 3768 auto *LLVMCP = cast<llvm::CatchPadInst>(&*LLVMHandler0->begin()); 3769 auto *LLVMCLP = cast<llvm::CleanupPadInst>(&*LLVMHandler1->begin()); 3770 3771 sandboxir::Context Ctx(C); 3772 [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF); 3773 auto *Dispatch = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMDispatch)); 3774 auto *Handler0 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMHandler0)); 3775 auto *Handler1 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMHandler1)); 3776 auto *BB = cast<sandboxir::BasicBlock>( 3777 Ctx.getValue(getBasicBlockByName(LLVMF, "bb"))); 3778 auto *BBRet = cast<sandboxir::ReturnInst>(&*BB->begin()); 3779 auto *CS = cast<sandboxir::CatchSwitchInst>(&*Dispatch->begin()); 3780 [[maybe_unused]] auto *CP = 3781 cast<sandboxir::CatchPadInst>(&*Handler0->begin()); 3782 [[maybe_unused]] auto *CLP = 3783 cast<sandboxir::CleanupPadInst>(&*Handler1->begin()); 3784 3785 // Check getCatchSwitch(). 3786 EXPECT_EQ(CP->getCatchSwitch(), CS); 3787 EXPECT_EQ(CP->getCatchSwitch(), Ctx.getValue(LLVMCP->getCatchSwitch())); 3788 3789 for (llvm::FuncletPadInst *LLVMFPI : 3790 {static_cast<llvm::FuncletPadInst *>(LLVMCP), 3791 static_cast<llvm::FuncletPadInst *>(LLVMCLP)}) { 3792 auto *FPI = cast<sandboxir::FuncletPadInst>(Ctx.getValue(LLVMFPI)); 3793 // Check arg_size(). 3794 EXPECT_EQ(FPI->arg_size(), LLVMFPI->arg_size()); 3795 // Check getParentPad(). 3796 EXPECT_EQ(FPI->getParentPad(), Ctx.getValue(LLVMFPI->getParentPad())); 3797 // Check setParentPad(). 3798 auto *OrigParentPad = FPI->getParentPad(); 3799 auto *NewParentPad = Dispatch; 3800 EXPECT_NE(NewParentPad, OrigParentPad); 3801 FPI->setParentPad(NewParentPad); 3802 EXPECT_EQ(FPI->getParentPad(), NewParentPad); 3803 FPI->setParentPad(OrigParentPad); 3804 EXPECT_EQ(FPI->getParentPad(), OrigParentPad); 3805 // Check getArgOperand(). 3806 for (auto Idx : seq<unsigned>(0, FPI->arg_size())) 3807 EXPECT_EQ(FPI->getArgOperand(Idx), 3808 Ctx.getValue(LLVMFPI->getArgOperand(Idx))); 3809 // Check setArgOperand(). 3810 auto *OrigArgOperand = FPI->getArgOperand(0); 3811 auto *NewArgOperand = Dispatch; 3812 EXPECT_NE(NewArgOperand, OrigArgOperand); 3813 FPI->setArgOperand(0, NewArgOperand); 3814 EXPECT_EQ(FPI->getArgOperand(0), NewArgOperand); 3815 FPI->setArgOperand(0, OrigArgOperand); 3816 EXPECT_EQ(FPI->getArgOperand(0), OrigArgOperand); 3817 } 3818 // Check CatchPadInst::create(). 3819 auto *NewCPI = cast<sandboxir::CatchPadInst>(sandboxir::CatchPadInst::create( 3820 CS, {}, BBRet->getIterator(), BB, Ctx, "NewCPI")); 3821 EXPECT_EQ(NewCPI->getCatchSwitch(), CS); 3822 EXPECT_EQ(NewCPI->arg_size(), 0u); 3823 EXPECT_EQ(NewCPI->getNextNode(), BBRet); 3824 #ifndef NDEBUG 3825 EXPECT_EQ(NewCPI->getName(), "NewCPI"); 3826 #endif // NDEBUG 3827 // Check CleanupPadInst::create(). 3828 auto *NewCLPI = 3829 cast<sandboxir::CleanupPadInst>(sandboxir::CleanupPadInst::create( 3830 CS, {}, BBRet->getIterator(), BB, Ctx, "NewCLPI")); 3831 EXPECT_EQ(NewCLPI->getParentPad(), CS); 3832 EXPECT_EQ(NewCLPI->arg_size(), 0u); 3833 EXPECT_EQ(NewCLPI->getNextNode(), BBRet); 3834 #ifndef NDEBUG 3835 EXPECT_EQ(NewCLPI->getName(), "NewCLPI"); 3836 #endif // NDEBUG 3837 } 3838 3839 TEST_F(SandboxIRTest, CatchReturnInst) { 3840 parseIR(C, R"IR( 3841 define void @foo() { 3842 dispatch: 3843 %cs = catchswitch within none [label %catch] unwind to caller 3844 catch: 3845 %catchpad = catchpad within %cs [ptr @foo] 3846 catchret from %catchpad to label %continue 3847 continue: 3848 ret void 3849 catch2: 3850 %catchpad2 = catchpad within %cs [ptr @foo] 3851 ret void 3852 } 3853 )IR"); 3854 Function &LLVMF = *M->getFunction("foo"); 3855 BasicBlock *LLVMCatch = getBasicBlockByName(LLVMF, "catch"); 3856 auto LLVMIt = LLVMCatch->begin(); 3857 [[maybe_unused]] auto *LLVMCP = cast<llvm::CatchPadInst>(&*LLVMIt++); 3858 auto *LLVMCR = cast<llvm::CatchReturnInst>(&*LLVMIt++); 3859 3860 sandboxir::Context Ctx(C); 3861 [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF); 3862 auto *Catch = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMCatch)); 3863 auto *Catch2 = cast<sandboxir::BasicBlock>( 3864 Ctx.getValue(getBasicBlockByName(LLVMF, "catch2"))); 3865 auto It = Catch->begin(); 3866 [[maybe_unused]] auto *CP = cast<sandboxir::CatchPadInst>(&*It++); 3867 auto *CR = cast<sandboxir::CatchReturnInst>(&*It++); 3868 auto *CP2 = cast<sandboxir::CatchPadInst>(&*Catch2->begin()); 3869 3870 // Check getCatchPad(). 3871 EXPECT_EQ(CR->getCatchPad(), Ctx.getValue(LLVMCR->getCatchPad())); 3872 // Check setCatchPad(). 3873 auto *OrigCP = CR->getCatchPad(); 3874 auto *NewCP = CP2; 3875 EXPECT_NE(NewCP, OrigCP); 3876 CR->setCatchPad(NewCP); 3877 EXPECT_EQ(CR->getCatchPad(), NewCP); 3878 CR->setCatchPad(OrigCP); 3879 EXPECT_EQ(CR->getCatchPad(), OrigCP); 3880 // Check getSuccessor(). 3881 EXPECT_EQ(CR->getSuccessor(), Ctx.getValue(LLVMCR->getSuccessor())); 3882 // Check setSuccessor(). 3883 auto *OrigSucc = CR->getSuccessor(); 3884 auto *NewSucc = Catch; 3885 EXPECT_NE(NewSucc, OrigSucc); 3886 CR->setSuccessor(NewSucc); 3887 EXPECT_EQ(CR->getSuccessor(), NewSucc); 3888 CR->setSuccessor(OrigSucc); 3889 EXPECT_EQ(CR->getSuccessor(), OrigSucc); 3890 // Check getNumSuccessors(). 3891 EXPECT_EQ(CR->getNumSuccessors(), LLVMCR->getNumSuccessors()); 3892 // Check getCatchSwitchParentPad(). 3893 EXPECT_EQ(CR->getCatchSwitchParentPad(), 3894 Ctx.getValue(LLVMCR->getCatchSwitchParentPad())); 3895 // Check create(). 3896 auto *CRI = 3897 cast<sandboxir::CatchReturnInst>(sandboxir::CatchReturnInst::create( 3898 CP, Catch, CP->getIterator(), Catch, Ctx)); 3899 EXPECT_EQ(CRI->getNextNode(), CP); 3900 EXPECT_EQ(CRI->getCatchPad(), CP); 3901 EXPECT_EQ(CRI->getSuccessor(), Catch); 3902 } 3903 3904 TEST_F(SandboxIRTest, CleanupReturnInst) { 3905 parseIR(C, R"IR( 3906 define void @foo() { 3907 dispatch: 3908 invoke void @foo() 3909 to label %throw unwind label %cleanup 3910 throw: 3911 ret void 3912 cleanup: 3913 %cleanuppad = cleanuppad within none [] 3914 cleanupret from %cleanuppad unwind label %cleanup2 3915 cleanup2: 3916 %cleanuppad2 = cleanuppad within none [] 3917 ret void 3918 } 3919 )IR"); 3920 Function &LLVMF = *M->getFunction("foo"); 3921 BasicBlock *LLVMCleanup = getBasicBlockByName(LLVMF, "cleanup"); 3922 auto LLVMIt = LLVMCleanup->begin(); 3923 [[maybe_unused]] auto *LLVMCP = cast<llvm::CleanupPadInst>(&*LLVMIt++); 3924 auto *LLVMCRI = cast<llvm::CleanupReturnInst>(&*LLVMIt++); 3925 3926 sandboxir::Context Ctx(C); 3927 [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF); 3928 auto *Throw = cast<sandboxir::BasicBlock>( 3929 Ctx.getValue(getBasicBlockByName(LLVMF, "throw"))); 3930 auto *Cleanup = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMCleanup)); 3931 auto *Cleanup2 = cast<sandboxir::BasicBlock>( 3932 Ctx.getValue(getBasicBlockByName(LLVMF, "cleanup2"))); 3933 auto It = Cleanup->begin(); 3934 [[maybe_unused]] auto *CP = cast<sandboxir::CleanupPadInst>(&*It++); 3935 auto *CRI = cast<sandboxir::CleanupReturnInst>(&*It++); 3936 It = Cleanup2->begin(); 3937 auto *CP2 = cast<sandboxir::CleanupPadInst>(&*It++); 3938 auto *Ret = cast<sandboxir::ReturnInst>(&*It++); 3939 3940 // Check hasUnwindDest(). 3941 EXPECT_EQ(CRI->hasUnwindDest(), LLVMCRI->hasUnwindDest()); 3942 // Check unwindsToCaller(). 3943 EXPECT_EQ(CRI->unwindsToCaller(), LLVMCRI->unwindsToCaller()); 3944 // Check getCleanupPad(). 3945 EXPECT_EQ(CRI->getCleanupPad(), Ctx.getValue(LLVMCRI->getCleanupPad())); 3946 // Check setCleanupPad(). 3947 auto *OrigCleanupPad = CRI->getCleanupPad(); 3948 auto *NewCleanupPad = CP2; 3949 EXPECT_NE(NewCleanupPad, OrigCleanupPad); 3950 CRI->setCleanupPad(NewCleanupPad); 3951 EXPECT_EQ(CRI->getCleanupPad(), NewCleanupPad); 3952 CRI->setCleanupPad(OrigCleanupPad); 3953 EXPECT_EQ(CRI->getCleanupPad(), OrigCleanupPad); 3954 // Check setNumSuccessors(). 3955 EXPECT_EQ(CRI->getNumSuccessors(), LLVMCRI->getNumSuccessors()); 3956 // Check getUnwindDest(). 3957 EXPECT_EQ(CRI->getUnwindDest(), Ctx.getValue(LLVMCRI->getUnwindDest())); 3958 // Check setUnwindDest(). 3959 auto *OrigUnwindDest = CRI->getUnwindDest(); 3960 auto *NewUnwindDest = Throw; 3961 EXPECT_NE(NewUnwindDest, OrigUnwindDest); 3962 CRI->setUnwindDest(NewUnwindDest); 3963 EXPECT_EQ(CRI->getUnwindDest(), NewUnwindDest); 3964 CRI->setUnwindDest(OrigUnwindDest); 3965 EXPECT_EQ(CRI->getUnwindDest(), OrigUnwindDest); 3966 // Check create(). 3967 auto *UnwindBB = Cleanup; 3968 auto *NewCRI = sandboxir::CleanupReturnInst::create( 3969 CP2, UnwindBB, Ret->getIterator(), Ret->getParent(), Ctx); 3970 EXPECT_EQ(NewCRI->getCleanupPad(), CP2); 3971 EXPECT_EQ(NewCRI->getUnwindDest(), UnwindBB); 3972 EXPECT_EQ(NewCRI->getNextNode(), Ret); 3973 } 3974 3975 TEST_F(SandboxIRTest, GetElementPtrInstruction) { 3976 parseIR(C, R"IR( 3977 define void @foo(ptr %ptr, <2 x ptr> %ptrs) { 3978 %gep0 = getelementptr i8, ptr %ptr, i32 0 3979 %gep1 = getelementptr nusw i8, ptr %ptr, i32 0 3980 %gep2 = getelementptr nuw i8, ptr %ptr, i32 0 3981 %gep3 = getelementptr inbounds {i32, {i32, i8}}, ptr %ptr, i32 1, i32 0 3982 %gep4 = getelementptr inbounds {i8, i8, {i32, i16}}, <2 x ptr> %ptrs, i32 2, <2 x i32> <i32 0, i32 0> 3983 ret void 3984 } 3985 )IR"); 3986 Function &LLVMF = *M->getFunction("foo"); 3987 BasicBlock *LLVMBB = &*LLVMF.begin(); 3988 auto LLVMIt = LLVMBB->begin(); 3989 SmallVector<llvm::GetElementPtrInst *, 4> LLVMGEPs; 3990 while (isa<llvm::GetElementPtrInst>(&*LLVMIt)) 3991 LLVMGEPs.push_back(cast<llvm::GetElementPtrInst>(&*LLVMIt++)); 3992 auto *LLVMRet = cast<llvm::ReturnInst>(&*LLVMIt++); 3993 sandboxir::Context Ctx(C); 3994 [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF); 3995 3996 for (llvm::GetElementPtrInst *LLVMGEP : LLVMGEPs) { 3997 // Check classof(). 3998 auto *GEP = cast<sandboxir::GetElementPtrInst>(Ctx.getValue(LLVMGEP)); 3999 // Check getSourceElementType(). 4000 EXPECT_EQ(GEP->getSourceElementType(), 4001 Ctx.getType(LLVMGEP->getSourceElementType())); 4002 // Check getResultElementType(). 4003 EXPECT_EQ(GEP->getResultElementType(), 4004 Ctx.getType(LLVMGEP->getResultElementType())); 4005 // Check getAddressSpace(). 4006 EXPECT_EQ(GEP->getAddressSpace(), LLVMGEP->getAddressSpace()); 4007 // Check indices(). 4008 EXPECT_EQ(range_size(GEP->indices()), range_size(LLVMGEP->indices())); 4009 auto IdxIt = GEP->idx_begin(); 4010 for (llvm::Value *LLVMIdxV : LLVMGEP->indices()) { 4011 sandboxir::Value *IdxV = *IdxIt++; 4012 EXPECT_EQ(IdxV, Ctx.getValue(LLVMIdxV)); 4013 } 4014 // Check getPointerOperand(). 4015 EXPECT_EQ(GEP->getPointerOperand(), 4016 Ctx.getValue(LLVMGEP->getPointerOperand())); 4017 // Check getPointerOperandIndex(). 4018 EXPECT_EQ(GEP->getPointerOperandIndex(), LLVMGEP->getPointerOperandIndex()); 4019 // Check getPointerOperandType(). 4020 EXPECT_EQ(GEP->getPointerOperandType(), 4021 Ctx.getType(LLVMGEP->getPointerOperandType())); 4022 // Check getPointerAddressSpace(). 4023 EXPECT_EQ(GEP->getPointerAddressSpace(), LLVMGEP->getPointerAddressSpace()); 4024 // Check getNumIndices(). 4025 EXPECT_EQ(GEP->getNumIndices(), LLVMGEP->getNumIndices()); 4026 // Check hasIndices(). 4027 EXPECT_EQ(GEP->hasIndices(), LLVMGEP->hasIndices()); 4028 // Check hasAllConstantIndices(). 4029 EXPECT_EQ(GEP->hasAllConstantIndices(), LLVMGEP->hasAllConstantIndices()); 4030 // Check getNoWrapFlags(). 4031 EXPECT_EQ(GEP->getNoWrapFlags(), LLVMGEP->getNoWrapFlags()); 4032 // Check isInBounds(). 4033 EXPECT_EQ(GEP->isInBounds(), LLVMGEP->isInBounds()); 4034 // Check hasNoUnsignedWrap(). 4035 EXPECT_EQ(GEP->hasNoUnsignedWrap(), LLVMGEP->hasNoUnsignedWrap()); 4036 // Check accumulateConstantOffset(). 4037 const DataLayout &DL = M->getDataLayout(); 4038 APInt Offset1 = 4039 APInt::getZero(DL.getIndexSizeInBits(GEP->getPointerAddressSpace())); 4040 APInt Offset2 = 4041 APInt::getZero(DL.getIndexSizeInBits(GEP->getPointerAddressSpace())); 4042 EXPECT_EQ(GEP->accumulateConstantOffset(DL, Offset1), 4043 LLVMGEP->accumulateConstantOffset(DL, Offset2)); 4044 EXPECT_EQ(Offset1, Offset2); 4045 } 4046 4047 auto *BB = &*F.begin(); 4048 auto *GEP0 = cast<sandboxir::GetElementPtrInst>(&*BB->begin()); 4049 auto *Ret = cast<sandboxir::ReturnInst>(Ctx.getValue(LLVMRet)); 4050 SmallVector<sandboxir::Value *> Indices(GEP0->indices()); 4051 4052 // Check create() WhereIt, WhereBB. 4053 auto *NewGEP0 = 4054 cast<sandboxir::GetElementPtrInst>(sandboxir::GetElementPtrInst::create( 4055 GEP0->getType(), GEP0->getPointerOperand(), Indices, 4056 /*WhereIt=*/Ret->getIterator(), /*WhereBB=*/Ret->getParent(), Ctx, 4057 "NewGEP0")); 4058 EXPECT_EQ(NewGEP0->getName(), "NewGEP0"); 4059 EXPECT_EQ(NewGEP0->getType(), GEP0->getType()); 4060 EXPECT_EQ(NewGEP0->getPointerOperand(), GEP0->getPointerOperand()); 4061 EXPECT_EQ(range_size(NewGEP0->indices()), range_size(GEP0->indices())); 4062 for (auto NewIt = NewGEP0->idx_begin(), NewItE = NewGEP0->idx_end(), 4063 OldIt = GEP0->idx_begin(); 4064 NewIt != NewItE; ++NewIt) { 4065 sandboxir::Value *NewIdxV = *NewIt; 4066 sandboxir::Value *OldIdxV = *OldIt; 4067 EXPECT_EQ(NewIdxV, OldIdxV); 4068 } 4069 EXPECT_EQ(NewGEP0->getNextNode(), Ret); 4070 4071 // Check create() InsertBefore. 4072 auto *NewGEP1 = 4073 cast<sandboxir::GetElementPtrInst>(sandboxir::GetElementPtrInst::create( 4074 GEP0->getType(), GEP0->getPointerOperand(), Indices, 4075 /*InsertBefore=*/Ret, Ctx, "NewGEP1")); 4076 EXPECT_EQ(NewGEP1->getName(), "NewGEP1"); 4077 EXPECT_EQ(NewGEP1->getType(), GEP0->getType()); 4078 EXPECT_EQ(NewGEP1->getPointerOperand(), GEP0->getPointerOperand()); 4079 EXPECT_EQ(range_size(NewGEP1->indices()), range_size(GEP0->indices())); 4080 for (auto NewIt = NewGEP0->idx_begin(), NewItE = NewGEP0->idx_end(), 4081 OldIt = GEP0->idx_begin(); 4082 NewIt != NewItE; ++NewIt) { 4083 sandboxir::Value *NewIdxV = *NewIt; 4084 sandboxir::Value *OldIdxV = *OldIt; 4085 EXPECT_EQ(NewIdxV, OldIdxV); 4086 } 4087 EXPECT_EQ(NewGEP1->getNextNode(), Ret); 4088 4089 // Check create() InsertAtEnd. 4090 auto *NewGEP2 = 4091 cast<sandboxir::GetElementPtrInst>(sandboxir::GetElementPtrInst::create( 4092 GEP0->getType(), GEP0->getPointerOperand(), Indices, 4093 /*InsertAtEnd=*/BB, Ctx, "NewGEP2")); 4094 EXPECT_EQ(NewGEP2->getName(), "NewGEP2"); 4095 EXPECT_EQ(NewGEP2->getType(), GEP0->getType()); 4096 EXPECT_EQ(NewGEP2->getPointerOperand(), GEP0->getPointerOperand()); 4097 EXPECT_EQ(range_size(NewGEP2->indices()), range_size(GEP0->indices())); 4098 for (auto NewIt = NewGEP0->idx_begin(), NewItE = NewGEP0->idx_end(), 4099 OldIt = GEP0->idx_begin(); 4100 NewIt != NewItE; ++NewIt) { 4101 sandboxir::Value *NewIdxV = *NewIt; 4102 sandboxir::Value *OldIdxV = *OldIt; 4103 EXPECT_EQ(NewIdxV, OldIdxV); 4104 } 4105 EXPECT_EQ(NewGEP2->getPrevNode(), Ret); 4106 EXPECT_EQ(NewGEP2->getNextNode(), nullptr); 4107 } 4108 4109 TEST_F(SandboxIRTest, Flags) { 4110 parseIR(C, R"IR( 4111 define void @foo(i32 %arg, float %farg) { 4112 %add = add i32 %arg, %arg 4113 %fadd = fadd float %farg, %farg 4114 %udiv = udiv i32 %arg, %arg 4115 ret void 4116 } 4117 )IR"); 4118 Function &LLVMF = *M->getFunction("foo"); 4119 BasicBlock *LLVMBB = &*LLVMF.begin(); 4120 auto LLVMIt = LLVMBB->begin(); 4121 auto *LLVMAdd = &*LLVMIt++; 4122 auto *LLVMFAdd = &*LLVMIt++; 4123 auto *LLVMUDiv = &*LLVMIt++; 4124 4125 sandboxir::Context Ctx(C); 4126 auto &F = *Ctx.createFunction(&LLVMF); 4127 auto *BB = &*F.begin(); 4128 auto It = BB->begin(); 4129 auto *Add = &*It++; 4130 auto *FAdd = &*It++; 4131 auto *UDiv = &*It++; 4132 4133 #define CHECK_FLAG(I, LLVMI, GETTER, SETTER) \ 4134 { \ 4135 EXPECT_EQ(I->GETTER(), LLVMI->GETTER()); \ 4136 bool NewFlagVal = !I->GETTER(); \ 4137 I->SETTER(NewFlagVal); \ 4138 EXPECT_EQ(I->GETTER(), NewFlagVal); \ 4139 EXPECT_EQ(I->GETTER(), LLVMI->GETTER()); \ 4140 } 4141 4142 CHECK_FLAG(Add, LLVMAdd, hasNoUnsignedWrap, setHasNoUnsignedWrap); 4143 CHECK_FLAG(Add, LLVMAdd, hasNoSignedWrap, setHasNoSignedWrap); 4144 CHECK_FLAG(FAdd, LLVMFAdd, isFast, setFast); 4145 CHECK_FLAG(FAdd, LLVMFAdd, hasAllowReassoc, setHasAllowReassoc); 4146 CHECK_FLAG(UDiv, LLVMUDiv, isExact, setIsExact); 4147 CHECK_FLAG(FAdd, LLVMFAdd, hasNoNaNs, setHasNoNaNs); 4148 CHECK_FLAG(FAdd, LLVMFAdd, hasNoInfs, setHasNoInfs); 4149 CHECK_FLAG(FAdd, LLVMFAdd, hasNoSignedZeros, setHasNoSignedZeros); 4150 CHECK_FLAG(FAdd, LLVMFAdd, hasAllowReciprocal, setHasAllowReciprocal); 4151 CHECK_FLAG(FAdd, LLVMFAdd, hasAllowContract, setHasAllowContract); 4152 CHECK_FLAG(FAdd, LLVMFAdd, hasApproxFunc, setHasApproxFunc); 4153 4154 // Check getFastMathFlags(), copyFastMathFlags(). 4155 FAdd->setFastMathFlags(FastMathFlags::getFast()); 4156 EXPECT_FALSE(FAdd->getFastMathFlags() != LLVMFAdd->getFastMathFlags()); 4157 FastMathFlags OrigFMF = FAdd->getFastMathFlags(); 4158 FastMathFlags NewFMF; 4159 NewFMF.setAllowReassoc(true); 4160 EXPECT_TRUE(NewFMF != OrigFMF); 4161 FAdd->setFastMathFlags(NewFMF); 4162 EXPECT_FALSE(FAdd->getFastMathFlags() != OrigFMF); 4163 FAdd->copyFastMathFlags(NewFMF); 4164 EXPECT_FALSE(FAdd->getFastMathFlags() != NewFMF); 4165 EXPECT_FALSE(FAdd->getFastMathFlags() != LLVMFAdd->getFastMathFlags()); 4166 } 4167 4168 TEST_F(SandboxIRTest, CatchSwitchInst) { 4169 parseIR(C, R"IR( 4170 define void @foo(i32 %cond0, i32 %cond1) { 4171 bb0: 4172 %cs0 = catchswitch within none [label %handler0, label %handler1] unwind to caller 4173 bb1: 4174 %cs1 = catchswitch within %cs0 [label %handler0, label %handler1] unwind label %cleanup 4175 handler0: 4176 ret void 4177 handler1: 4178 ret void 4179 cleanup: 4180 ret void 4181 } 4182 )IR"); 4183 Function &LLVMF = *M->getFunction("foo"); 4184 auto *LLVMBB0 = getBasicBlockByName(LLVMF, "bb0"); 4185 auto *LLVMBB1 = getBasicBlockByName(LLVMF, "bb1"); 4186 auto *LLVMHandler0 = getBasicBlockByName(LLVMF, "handler0"); 4187 auto *LLVMHandler1 = getBasicBlockByName(LLVMF, "handler1"); 4188 auto *LLVMCleanup = getBasicBlockByName(LLVMF, "cleanup"); 4189 auto *LLVMCS0 = cast<llvm::CatchSwitchInst>(&*LLVMBB0->begin()); 4190 auto *LLVMCS1 = cast<llvm::CatchSwitchInst>(&*LLVMBB1->begin()); 4191 4192 sandboxir::Context Ctx(C); 4193 [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF); 4194 auto *BB0 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB0)); 4195 auto *BB1 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB1)); 4196 auto *Handler0 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMHandler0)); 4197 auto *Handler1 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMHandler1)); 4198 auto *Cleanup = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMCleanup)); 4199 auto *CS0 = cast<sandboxir::CatchSwitchInst>(&*BB0->begin()); 4200 auto *CS1 = cast<sandboxir::CatchSwitchInst>(&*BB1->begin()); 4201 4202 // Check getParentPad(). 4203 EXPECT_EQ(CS0->getParentPad(), Ctx.getValue(LLVMCS0->getParentPad())); 4204 EXPECT_EQ(CS1->getParentPad(), Ctx.getValue(LLVMCS1->getParentPad())); 4205 // Check setParentPad(). 4206 auto *OrigPad = CS0->getParentPad(); 4207 auto *NewPad = CS1; 4208 EXPECT_NE(NewPad, OrigPad); 4209 CS0->setParentPad(NewPad); 4210 EXPECT_EQ(CS0->getParentPad(), NewPad); 4211 CS0->setParentPad(OrigPad); 4212 EXPECT_EQ(CS0->getParentPad(), OrigPad); 4213 // Check hasUnwindDest(). 4214 EXPECT_EQ(CS0->hasUnwindDest(), LLVMCS0->hasUnwindDest()); 4215 EXPECT_EQ(CS1->hasUnwindDest(), LLVMCS1->hasUnwindDest()); 4216 // Check unwindsToCaller(). 4217 EXPECT_EQ(CS0->unwindsToCaller(), LLVMCS0->unwindsToCaller()); 4218 EXPECT_EQ(CS1->unwindsToCaller(), LLVMCS1->unwindsToCaller()); 4219 // Check getUnwindDest(). 4220 EXPECT_EQ(CS0->getUnwindDest(), Ctx.getValue(LLVMCS0->getUnwindDest())); 4221 EXPECT_EQ(CS1->getUnwindDest(), Ctx.getValue(LLVMCS1->getUnwindDest())); 4222 // Check setUnwindDest(). 4223 auto *OrigUnwindDest = CS1->getUnwindDest(); 4224 auto *NewUnwindDest = BB0; 4225 EXPECT_NE(NewUnwindDest, OrigUnwindDest); 4226 CS1->setUnwindDest(NewUnwindDest); 4227 EXPECT_EQ(CS1->getUnwindDest(), NewUnwindDest); 4228 CS1->setUnwindDest(OrigUnwindDest); 4229 EXPECT_EQ(CS1->getUnwindDest(), OrigUnwindDest); 4230 // Check getNumHandlers(). 4231 EXPECT_EQ(CS0->getNumHandlers(), LLVMCS0->getNumHandlers()); 4232 EXPECT_EQ(CS1->getNumHandlers(), LLVMCS1->getNumHandlers()); 4233 // Check handler_begin(), handler_end(). 4234 auto It = CS0->handler_begin(); 4235 EXPECT_EQ(*It++, Handler0); 4236 EXPECT_EQ(*It++, Handler1); 4237 EXPECT_EQ(It, CS0->handler_end()); 4238 // Check handlers(). 4239 SmallVector<sandboxir::BasicBlock *, 2> Handlers; 4240 for (sandboxir::BasicBlock *Handler : CS0->handlers()) 4241 Handlers.push_back(Handler); 4242 EXPECT_EQ(Handlers.size(), 2u); 4243 EXPECT_EQ(Handlers[0], Handler0); 4244 EXPECT_EQ(Handlers[1], Handler1); 4245 // Check addHandler(). 4246 CS0->addHandler(BB0); 4247 EXPECT_EQ(CS0->getNumHandlers(), 3u); 4248 EXPECT_EQ(*std::next(CS0->handler_begin(), 2), BB0); 4249 // Check getNumSuccessors(). 4250 EXPECT_EQ(CS0->getNumSuccessors(), LLVMCS0->getNumSuccessors()); 4251 EXPECT_EQ(CS1->getNumSuccessors(), LLVMCS1->getNumSuccessors()); 4252 // Check getSuccessor(). 4253 for (auto SuccIdx : seq<unsigned>(0, CS0->getNumSuccessors())) 4254 EXPECT_EQ(CS0->getSuccessor(SuccIdx), 4255 Ctx.getValue(LLVMCS0->getSuccessor(SuccIdx))); 4256 // Check setSuccessor(). 4257 auto *OrigSuccessor = CS0->getSuccessor(0); 4258 auto *NewSuccessor = BB0; 4259 EXPECT_NE(NewSuccessor, OrigSuccessor); 4260 CS0->setSuccessor(0, NewSuccessor); 4261 EXPECT_EQ(CS0->getSuccessor(0), NewSuccessor); 4262 CS0->setSuccessor(0, OrigSuccessor); 4263 EXPECT_EQ(CS0->getSuccessor(0), OrigSuccessor); 4264 // Check create(). 4265 CS1->eraseFromParent(); 4266 auto *NewCSI = sandboxir::CatchSwitchInst::create( 4267 CS0, Cleanup, 2, BB1->begin(), BB1, Ctx, "NewCSI"); 4268 EXPECT_TRUE(isa<sandboxir::CatchSwitchInst>(NewCSI)); 4269 EXPECT_EQ(NewCSI->getParentPad(), CS0); 4270 } 4271 4272 TEST_F(SandboxIRTest, ResumeInst) { 4273 parseIR(C, R"IR( 4274 define void @foo() { 4275 entry: 4276 invoke void @foo() 4277 to label %bb unwind label %unwind 4278 bb: 4279 ret void 4280 unwind: 4281 %lpad = landingpad { ptr, i32 } 4282 cleanup 4283 resume { ptr, i32 } %lpad 4284 } 4285 )IR"); 4286 Function &LLVMF = *M->getFunction("foo"); 4287 auto *LLVMUnwindBB = getBasicBlockByName(LLVMF, "unwind"); 4288 auto LLVMIt = LLVMUnwindBB->begin(); 4289 [[maybe_unused]] auto *LLVMLPad = cast<llvm::LandingPadInst>(&*LLVMIt++); 4290 auto *LLVMResume = cast<llvm::ResumeInst>(&*LLVMIt++); 4291 4292 sandboxir::Context Ctx(C); 4293 [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF); 4294 auto *UnwindBB = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMUnwindBB)); 4295 auto It = UnwindBB->begin(); 4296 auto *LPad = cast<sandboxir::LandingPadInst>(&*It++); 4297 auto *Resume = cast<sandboxir::ResumeInst>(&*It++); 4298 // Check getValue(). 4299 EXPECT_EQ(Resume->getValue(), LPad); 4300 EXPECT_EQ(Resume->getValue(), Ctx.getValue(LLVMResume->getValue())); 4301 // Check getNumSuccessors(). 4302 EXPECT_EQ(Resume->getNumSuccessors(), LLVMResume->getNumSuccessors()); 4303 // Check create(). 4304 auto *NewResume = 4305 sandboxir::ResumeInst::create(LPad, UnwindBB->end(), UnwindBB, Ctx); 4306 EXPECT_EQ(NewResume->getValue(), LPad); 4307 EXPECT_EQ(NewResume->getParent(), UnwindBB); 4308 EXPECT_EQ(NewResume->getNextNode(), nullptr); 4309 } 4310 4311 TEST_F(SandboxIRTest, SwitchInst) { 4312 parseIR(C, R"IR( 4313 define void @foo(i32 %cond0, i32 %cond1) { 4314 entry: 4315 switch i32 %cond0, label %default [ i32 0, label %bb0 4316 i32 1, label %bb1 ] 4317 bb0: 4318 ret void 4319 bb1: 4320 ret void 4321 default: 4322 ret void 4323 } 4324 )IR"); 4325 Function &LLVMF = *M->getFunction("foo"); 4326 auto *LLVMEntry = getBasicBlockByName(LLVMF, "entry"); 4327 auto *LLVMSwitch = cast<llvm::SwitchInst>(&*LLVMEntry->begin()); 4328 4329 sandboxir::Context Ctx(C); 4330 auto &F = *Ctx.createFunction(&LLVMF); 4331 auto *Cond1 = F.getArg(1); 4332 auto *Entry = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMEntry)); 4333 auto *Switch = cast<sandboxir::SwitchInst>(&*Entry->begin()); 4334 auto *BB0 = cast<sandboxir::BasicBlock>( 4335 Ctx.getValue(getBasicBlockByName(LLVMF, "bb0"))); 4336 auto *BB1 = cast<sandboxir::BasicBlock>( 4337 Ctx.getValue(getBasicBlockByName(LLVMF, "bb1"))); 4338 auto *Default = cast<sandboxir::BasicBlock>( 4339 Ctx.getValue(getBasicBlockByName(LLVMF, "default"))); 4340 4341 // Check getCondition(). 4342 EXPECT_EQ(Switch->getCondition(), Ctx.getValue(LLVMSwitch->getCondition())); 4343 // Check setCondition(). 4344 auto *OrigCond = Switch->getCondition(); 4345 auto *NewCond = Cond1; 4346 EXPECT_NE(NewCond, OrigCond); 4347 Switch->setCondition(NewCond); 4348 EXPECT_EQ(Switch->getCondition(), NewCond); 4349 Switch->setCondition(OrigCond); 4350 EXPECT_EQ(Switch->getCondition(), OrigCond); 4351 // Check getDefaultDest(). 4352 EXPECT_EQ(Switch->getDefaultDest(), 4353 Ctx.getValue(LLVMSwitch->getDefaultDest())); 4354 EXPECT_EQ(Switch->getDefaultDest(), Default); 4355 // Check defaultDestUndefined(). 4356 EXPECT_EQ(Switch->defaultDestUndefined(), LLVMSwitch->defaultDestUndefined()); 4357 // Check setDefaultDest(). 4358 auto *OrigDefaultDest = Switch->getDefaultDest(); 4359 auto *NewDefaultDest = Entry; 4360 EXPECT_NE(NewDefaultDest, OrigDefaultDest); 4361 Switch->setDefaultDest(NewDefaultDest); 4362 EXPECT_EQ(Switch->getDefaultDest(), NewDefaultDest); 4363 Switch->setDefaultDest(OrigDefaultDest); 4364 EXPECT_EQ(Switch->getDefaultDest(), OrigDefaultDest); 4365 // Check getNumCases(). 4366 EXPECT_EQ(Switch->getNumCases(), LLVMSwitch->getNumCases()); 4367 // Check getNumSuccessors(). 4368 EXPECT_EQ(Switch->getNumSuccessors(), LLVMSwitch->getNumSuccessors()); 4369 // Check getSuccessor(). 4370 for (auto SuccIdx : seq<unsigned>(0, Switch->getNumSuccessors())) 4371 EXPECT_EQ(Switch->getSuccessor(SuccIdx), 4372 Ctx.getValue(LLVMSwitch->getSuccessor(SuccIdx))); 4373 // Check setSuccessor(). 4374 auto *OrigSucc = Switch->getSuccessor(0); 4375 auto *NewSucc = Entry; 4376 EXPECT_NE(NewSucc, OrigSucc); 4377 Switch->setSuccessor(0, NewSucc); 4378 EXPECT_EQ(Switch->getSuccessor(0), NewSucc); 4379 Switch->setSuccessor(0, OrigSucc); 4380 EXPECT_EQ(Switch->getSuccessor(0), OrigSucc); 4381 // Check case_begin(), case_end(), CaseIt. 4382 auto *Zero = sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 0); 4383 auto *One = sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 1); 4384 auto CaseIt = Switch->case_begin(); 4385 { 4386 sandboxir::SwitchInst::CaseHandle Case = *CaseIt++; 4387 EXPECT_EQ(Case.getCaseValue(), Zero); 4388 EXPECT_EQ(Case.getCaseSuccessor(), BB0); 4389 EXPECT_EQ(Case.getCaseIndex(), 0u); 4390 EXPECT_EQ(Case.getSuccessorIndex(), 1u); 4391 } 4392 { 4393 sandboxir::SwitchInst::CaseHandle Case = *CaseIt++; 4394 EXPECT_EQ(Case.getCaseValue(), One); 4395 EXPECT_EQ(Case.getCaseSuccessor(), BB1); 4396 EXPECT_EQ(Case.getCaseIndex(), 1u); 4397 EXPECT_EQ(Case.getSuccessorIndex(), 2u); 4398 } 4399 EXPECT_EQ(CaseIt, Switch->case_end()); 4400 // Check cases(). 4401 unsigned CntCase = 0; 4402 for (auto &Case : Switch->cases()) { 4403 EXPECT_EQ(Case.getCaseIndex(), CntCase); 4404 ++CntCase; 4405 } 4406 EXPECT_EQ(CntCase, 2u); 4407 // Check case_default(). 4408 auto CaseDefault = *Switch->case_default(); 4409 EXPECT_EQ(CaseDefault.getCaseSuccessor(), Default); 4410 EXPECT_EQ(CaseDefault.getCaseIndex(), 4411 sandboxir::SwitchInst::DefaultPseudoIndex); 4412 // Check findCaseValue(). 4413 EXPECT_EQ(Switch->findCaseValue(Zero)->getCaseIndex(), 0u); 4414 EXPECT_EQ(Switch->findCaseValue(One)->getCaseIndex(), 1u); 4415 // Check findCaseDest(). 4416 EXPECT_EQ(Switch->findCaseDest(BB0), Zero); 4417 EXPECT_EQ(Switch->findCaseDest(BB1), One); 4418 EXPECT_EQ(Switch->findCaseDest(Entry), nullptr); 4419 // Check addCase(). 4420 auto *Two = sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 2); 4421 Switch->addCase(Two, Entry); 4422 auto CaseTwoIt = Switch->findCaseValue(Two); 4423 auto CaseTwo = *CaseTwoIt; 4424 EXPECT_EQ(CaseTwo.getCaseValue(), Two); 4425 EXPECT_EQ(CaseTwo.getCaseSuccessor(), Entry); 4426 EXPECT_EQ(Switch->getNumCases(), 3u); 4427 // Check removeCase(). 4428 auto RemovedIt = Switch->removeCase(CaseTwoIt); 4429 EXPECT_EQ(RemovedIt, Switch->case_end()); 4430 EXPECT_EQ(Switch->getNumCases(), 2u); 4431 // Check create(). 4432 auto NewSwitch = sandboxir::SwitchInst::create( 4433 Cond1, Default, 1, Default->begin(), Default, Ctx, "NewSwitch"); 4434 EXPECT_TRUE(isa<sandboxir::SwitchInst>(NewSwitch)); 4435 EXPECT_EQ(NewSwitch->getCondition(), Cond1); 4436 EXPECT_EQ(NewSwitch->getDefaultDest(), Default); 4437 } 4438 4439 TEST_F(SandboxIRTest, UnaryOperator) { 4440 parseIR(C, R"IR( 4441 define void @foo(float %arg0) { 4442 %fneg = fneg float %arg0 4443 %copyfrom = fadd reassoc float %arg0, 42.0 4444 ret void 4445 } 4446 )IR"); 4447 Function &LLVMF = *M->getFunction("foo"); 4448 sandboxir::Context Ctx(C); 4449 4450 auto &F = *Ctx.createFunction(&LLVMF); 4451 auto *Arg0 = F.getArg(0); 4452 auto *BB = &*F.begin(); 4453 auto It = BB->begin(); 4454 auto *I = cast<sandboxir::UnaryOperator>(&*It++); 4455 auto *CopyFrom = cast<sandboxir::BinaryOperator>(&*It++); 4456 auto *Ret = &*It++; 4457 EXPECT_EQ(I->getOpcode(), sandboxir::Instruction::Opcode::FNeg); 4458 EXPECT_EQ(I->getOperand(0), Arg0); 4459 4460 { 4461 // Check create() WhereIt, WhereBB. 4462 auto *NewI = 4463 cast<sandboxir::UnaryOperator>(sandboxir::UnaryOperator::create( 4464 sandboxir::Instruction::Opcode::FNeg, Arg0, 4465 /*WhereIt=*/Ret->getIterator(), /*WhereBB=*/Ret->getParent(), Ctx, 4466 "New1")); 4467 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::FNeg); 4468 EXPECT_EQ(NewI->getOperand(0), Arg0); 4469 #ifndef NDEBUG 4470 EXPECT_EQ(NewI->getName(), "New1"); 4471 #endif // NDEBUG 4472 EXPECT_EQ(NewI->getNextNode(), Ret); 4473 } 4474 { 4475 // Check create() InsertBefore. 4476 auto *NewI = 4477 cast<sandboxir::UnaryOperator>(sandboxir::UnaryOperator::create( 4478 sandboxir::Instruction::Opcode::FNeg, Arg0, 4479 /*InsertBefore=*/Ret, Ctx, "New2")); 4480 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::FNeg); 4481 EXPECT_EQ(NewI->getOperand(0), Arg0); 4482 #ifndef NDEBUG 4483 EXPECT_EQ(NewI->getName(), "New2"); 4484 #endif // NDEBUG 4485 EXPECT_EQ(NewI->getNextNode(), Ret); 4486 } 4487 { 4488 // Check create() InsertAtEnd. 4489 auto *NewI = 4490 cast<sandboxir::UnaryOperator>(sandboxir::UnaryOperator::create( 4491 sandboxir::Instruction::Opcode::FNeg, Arg0, 4492 /*InsertAtEnd=*/BB, Ctx, "New3")); 4493 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::FNeg); 4494 EXPECT_EQ(NewI->getOperand(0), Arg0); 4495 #ifndef NDEBUG 4496 EXPECT_EQ(NewI->getName(), "New3"); 4497 #endif // NDEBUG 4498 EXPECT_EQ(NewI->getParent(), BB); 4499 EXPECT_EQ(NewI->getNextNode(), nullptr); 4500 } 4501 { 4502 // Check create() when it gets folded. 4503 auto *FortyTwo = CopyFrom->getOperand(1); 4504 auto *NewV = sandboxir::UnaryOperator::create( 4505 sandboxir::Instruction::Opcode::FNeg, FortyTwo, 4506 /*WhereIt=*/Ret->getIterator(), /*WhereBB=*/Ret->getParent(), Ctx, 4507 "Folded"); 4508 EXPECT_TRUE(isa<sandboxir::Constant>(NewV)); 4509 } 4510 4511 { 4512 // Check createWithCopiedFlags() WhereIt, WhereBB. 4513 auto *NewI = cast<sandboxir::UnaryOperator>( 4514 sandboxir::UnaryOperator::createWithCopiedFlags( 4515 sandboxir::Instruction::Opcode::FNeg, Arg0, CopyFrom, 4516 /*WhereIt=*/Ret->getIterator(), /*WhereBB=*/Ret->getParent(), Ctx, 4517 "NewCopyFrom1")); 4518 EXPECT_EQ(NewI->hasAllowReassoc(), CopyFrom->hasAllowReassoc()); 4519 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::FNeg); 4520 EXPECT_EQ(NewI->getOperand(0), Arg0); 4521 #ifndef NDEBUG 4522 EXPECT_EQ(NewI->getName(), "NewCopyFrom1"); 4523 #endif // NDEBUG 4524 EXPECT_EQ(NewI->getNextNode(), Ret); 4525 } 4526 { 4527 // Check createWithCopiedFlags() InsertBefore, 4528 auto *NewI = cast<sandboxir::UnaryOperator>( 4529 sandboxir::UnaryOperator::createWithCopiedFlags( 4530 sandboxir::Instruction::Opcode::FNeg, Arg0, CopyFrom, 4531 /*InsertBefore=*/Ret, Ctx, "NewCopyFrom2")); 4532 EXPECT_EQ(NewI->hasAllowReassoc(), CopyFrom->hasAllowReassoc()); 4533 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::FNeg); 4534 EXPECT_EQ(NewI->getOperand(0), Arg0); 4535 #ifndef NDEBUG 4536 EXPECT_EQ(NewI->getName(), "NewCopyFrom2"); 4537 #endif // NDEBUG 4538 EXPECT_EQ(NewI->getNextNode(), Ret); 4539 } 4540 { 4541 // Check createWithCopiedFlags() InsertAtEnd, 4542 auto *NewI = cast<sandboxir::UnaryOperator>( 4543 sandboxir::UnaryOperator::createWithCopiedFlags( 4544 sandboxir::Instruction::Opcode::FNeg, Arg0, CopyFrom, 4545 /*InsertAtEnd=*/BB, Ctx, "NewCopyFrom3")); 4546 EXPECT_EQ(NewI->hasAllowReassoc(), CopyFrom->hasAllowReassoc()); 4547 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::FNeg); 4548 EXPECT_EQ(NewI->getOperand(0), Arg0); 4549 #ifndef NDEBUG 4550 EXPECT_EQ(NewI->getName(), "NewCopyFrom3"); 4551 #endif // NDEBUG 4552 EXPECT_EQ(NewI->getParent(), BB); 4553 EXPECT_EQ(NewI->getNextNode(), nullptr); 4554 } 4555 { 4556 // Check createWithCopiedFlags() when it gets folded. 4557 auto *FortyTwo = CopyFrom->getOperand(1); 4558 auto *NewV = sandboxir::UnaryOperator::createWithCopiedFlags( 4559 sandboxir::Instruction::Opcode::FNeg, FortyTwo, CopyFrom, 4560 /*InsertAtEnd=*/BB, Ctx, "Folded"); 4561 EXPECT_TRUE(isa<sandboxir::Constant>(NewV)); 4562 } 4563 } 4564 4565 TEST_F(SandboxIRTest, BinaryOperator) { 4566 parseIR(C, R"IR( 4567 define void @foo(i8 %arg0, i8 %arg1, float %farg0, float %farg1) { 4568 %add = add i8 %arg0, %arg1 4569 %fadd = fadd float %farg0, %farg1 4570 %sub = sub i8 %arg0, %arg1 4571 %fsub = fsub float %farg0, %farg1 4572 %mul = mul i8 %arg0, %arg1 4573 %fmul = fmul float %farg0, %farg1 4574 %udiv = udiv i8 %arg0, %arg1 4575 %sdiv = sdiv i8 %arg0, %arg1 4576 %fdiv = fdiv float %farg0, %farg1 4577 %urem = urem i8 %arg0, %arg1 4578 %srem = srem i8 %arg0, %arg1 4579 %frem = frem float %farg0, %farg1 4580 %shl = shl i8 %arg0, %arg1 4581 %lshr = lshr i8 %arg0, %arg1 4582 %ashr = ashr i8 %arg0, %arg1 4583 %and = and i8 %arg0, %arg1 4584 %or = or i8 %arg0, %arg1 4585 %xor = xor i8 %arg0, %arg1 4586 4587 %copyfrom = add nsw i8 %arg0, %arg1 4588 ret void 4589 } 4590 )IR"); 4591 Function &LLVMF = *M->getFunction("foo"); 4592 sandboxir::Context Ctx(C); 4593 4594 auto &F = *Ctx.createFunction(&LLVMF); 4595 auto *Arg0 = F.getArg(0); 4596 auto *Arg1 = F.getArg(1); 4597 auto *FArg0 = F.getArg(2); 4598 auto *FArg1 = F.getArg(3); 4599 auto *BB = &*F.begin(); 4600 auto It = BB->begin(); 4601 4602 #define CHECK_IBINOP(OPCODE) \ 4603 { \ 4604 auto *I = cast<sandboxir::BinaryOperator>(&*It++); \ 4605 EXPECT_EQ(I->getOpcode(), OPCODE); \ 4606 EXPECT_EQ(I->getOperand(0), Arg0); \ 4607 EXPECT_EQ(I->getOperand(1), Arg1); \ 4608 } 4609 #define CHECK_FBINOP(OPCODE) \ 4610 { \ 4611 auto *I = cast<sandboxir::BinaryOperator>(&*It++); \ 4612 EXPECT_EQ(I->getOpcode(), OPCODE); \ 4613 EXPECT_EQ(I->getOperand(0), FArg0); \ 4614 EXPECT_EQ(I->getOperand(1), FArg1); \ 4615 } 4616 4617 CHECK_IBINOP(sandboxir::Instruction::Opcode::Add); 4618 CHECK_FBINOP(sandboxir::Instruction::Opcode::FAdd); 4619 CHECK_IBINOP(sandboxir::Instruction::Opcode::Sub); 4620 CHECK_FBINOP(sandboxir::Instruction::Opcode::FSub); 4621 CHECK_IBINOP(sandboxir::Instruction::Opcode::Mul); 4622 CHECK_FBINOP(sandboxir::Instruction::Opcode::FMul); 4623 CHECK_IBINOP(sandboxir::Instruction::Opcode::UDiv); 4624 CHECK_IBINOP(sandboxir::Instruction::Opcode::SDiv); 4625 CHECK_FBINOP(sandboxir::Instruction::Opcode::FDiv); 4626 CHECK_IBINOP(sandboxir::Instruction::Opcode::URem); 4627 CHECK_IBINOP(sandboxir::Instruction::Opcode::SRem); 4628 CHECK_FBINOP(sandboxir::Instruction::Opcode::FRem); 4629 CHECK_IBINOP(sandboxir::Instruction::Opcode::Shl); 4630 CHECK_IBINOP(sandboxir::Instruction::Opcode::LShr); 4631 CHECK_IBINOP(sandboxir::Instruction::Opcode::AShr); 4632 CHECK_IBINOP(sandboxir::Instruction::Opcode::And); 4633 CHECK_IBINOP(sandboxir::Instruction::Opcode::Or); 4634 CHECK_IBINOP(sandboxir::Instruction::Opcode::Xor); 4635 4636 auto *CopyFrom = cast<sandboxir::BinaryOperator>(&*It++); 4637 auto *Ret = cast<sandboxir::ReturnInst>(&*It++); 4638 4639 { 4640 // Check create() WhereIt, WhereBB. 4641 auto *NewI = 4642 cast<sandboxir::BinaryOperator>(sandboxir::BinaryOperator::create( 4643 sandboxir::Instruction::Opcode::Add, Arg0, Arg1, 4644 /*WhereIt=*/Ret->getIterator(), /*WhereBB=*/Ret->getParent(), Ctx, 4645 "New1")); 4646 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Add); 4647 EXPECT_EQ(NewI->getOperand(0), Arg0); 4648 EXPECT_EQ(NewI->getOperand(1), Arg1); 4649 #ifndef NDEBUG 4650 EXPECT_EQ(NewI->getName(), "New1"); 4651 #endif // NDEBUG 4652 EXPECT_EQ(NewI->getNextNode(), Ret); 4653 } 4654 { 4655 // Check create() InsertBefore. 4656 auto *NewI = 4657 cast<sandboxir::BinaryOperator>(sandboxir::BinaryOperator::create( 4658 sandboxir::Instruction::Opcode::Add, Arg0, Arg1, 4659 /*InsertBefore=*/Ret, Ctx, "New2")); 4660 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Add); 4661 EXPECT_EQ(NewI->getOperand(0), Arg0); 4662 EXPECT_EQ(NewI->getOperand(1), Arg1); 4663 #ifndef NDEBUG 4664 EXPECT_EQ(NewI->getName(), "New2"); 4665 #endif // NDEBUG 4666 EXPECT_EQ(NewI->getNextNode(), Ret); 4667 } 4668 { 4669 // Check create() InsertAtEnd. 4670 auto *NewI = 4671 cast<sandboxir::BinaryOperator>(sandboxir::BinaryOperator::create( 4672 sandboxir::Instruction::Opcode::Add, Arg0, Arg1, 4673 /*InsertAtEnd=*/BB, Ctx, "New3")); 4674 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Add); 4675 EXPECT_EQ(NewI->getOperand(0), Arg0); 4676 EXPECT_EQ(NewI->getOperand(1), Arg1); 4677 #ifndef NDEBUG 4678 EXPECT_EQ(NewI->getName(), "New3"); 4679 #endif // NDEBUG 4680 EXPECT_EQ(NewI->getNextNode(), nullptr); 4681 EXPECT_EQ(NewI->getParent(), BB); 4682 } 4683 { 4684 // Check create() when it gets folded. 4685 auto *FortyTwo = 4686 sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 42); 4687 auto *NewV = sandboxir::BinaryOperator::create( 4688 sandboxir::Instruction::Opcode::Add, FortyTwo, FortyTwo, 4689 /*InsertBefore=*/Ret, Ctx, "Folded"); 4690 EXPECT_TRUE(isa<sandboxir::Constant>(NewV)); 4691 } 4692 4693 { 4694 // Check createWithCopiedFlags() WhereIt, WhereBB. 4695 auto *NewI = cast<sandboxir::BinaryOperator>( 4696 sandboxir::BinaryOperator::createWithCopiedFlags( 4697 sandboxir::Instruction::Opcode::Add, Arg0, Arg1, CopyFrom, 4698 /*WhereIt=*/Ret->getIterator(), /*WhereBB=*/Ret->getParent(), Ctx, 4699 "NewNSW1")); 4700 EXPECT_EQ(NewI->hasNoSignedWrap(), CopyFrom->hasNoSignedWrap()); 4701 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Add); 4702 EXPECT_EQ(NewI->getOperand(0), Arg0); 4703 EXPECT_EQ(NewI->getOperand(1), Arg1); 4704 #ifndef NDEBUG 4705 EXPECT_EQ(NewI->getName(), "NewNSW1"); 4706 #endif // NDEBUG 4707 EXPECT_EQ(NewI->getNextNode(), Ret); 4708 } 4709 { 4710 // Check createWithCopiedFlags() InsertBefore. 4711 auto *NewI = cast<sandboxir::BinaryOperator>( 4712 sandboxir::BinaryOperator::createWithCopiedFlags( 4713 sandboxir::Instruction::Opcode::Add, Arg0, Arg1, CopyFrom, 4714 /*InsertBefore=*/Ret, Ctx, "NewNSW2")); 4715 EXPECT_EQ(NewI->hasNoSignedWrap(), CopyFrom->hasNoSignedWrap()); 4716 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Add); 4717 EXPECT_EQ(NewI->getOperand(0), Arg0); 4718 EXPECT_EQ(NewI->getOperand(1), Arg1); 4719 #ifndef NDEBUG 4720 EXPECT_EQ(NewI->getName(), "NewNSW2"); 4721 #endif // NDEBUG 4722 EXPECT_EQ(NewI->getNextNode(), Ret); 4723 } 4724 { 4725 // Check createWithCopiedFlags() InsertAtEnd. 4726 auto *NewI = cast<sandboxir::BinaryOperator>( 4727 sandboxir::BinaryOperator::createWithCopiedFlags( 4728 sandboxir::Instruction::Opcode::Add, Arg0, Arg1, CopyFrom, 4729 /*InsertAtEnd=*/BB, Ctx, "NewNSW3")); 4730 EXPECT_EQ(NewI->hasNoSignedWrap(), CopyFrom->hasNoSignedWrap()); 4731 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Add); 4732 EXPECT_EQ(NewI->getOperand(0), Arg0); 4733 EXPECT_EQ(NewI->getOperand(1), Arg1); 4734 #ifndef NDEBUG 4735 EXPECT_EQ(NewI->getName(), "NewNSW3"); 4736 #endif // NDEBUG 4737 EXPECT_EQ(NewI->getParent(), BB); 4738 EXPECT_EQ(NewI->getNextNode(), nullptr); 4739 } 4740 { 4741 // Check createWithCopiedFlags() when it gets folded. 4742 auto *FortyTwo = 4743 sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 42); 4744 auto *NewV = sandboxir::BinaryOperator::createWithCopiedFlags( 4745 sandboxir::Instruction::Opcode::Add, FortyTwo, FortyTwo, CopyFrom, 4746 /*InsertBefore=*/Ret, Ctx, "Folded"); 4747 EXPECT_TRUE(isa<sandboxir::Constant>(NewV)); 4748 } 4749 } 4750 4751 TEST_F(SandboxIRTest, PossiblyDisjointInst) { 4752 parseIR(C, R"IR( 4753 define void @foo(i8 %arg0, i8 %arg1) { 4754 %or = or i8 %arg0, %arg1 4755 ret void 4756 } 4757 )IR"); 4758 Function &LLVMF = *M->getFunction("foo"); 4759 sandboxir::Context Ctx(C); 4760 4761 auto &F = *Ctx.createFunction(&LLVMF); 4762 auto *BB = &*F.begin(); 4763 auto It = BB->begin(); 4764 auto *PDI = cast<sandboxir::PossiblyDisjointInst>(&*It++); 4765 4766 // Check setIsDisjoint(), isDisjoint(). 4767 auto OrigIsDisjoint = PDI->isDisjoint(); 4768 auto NewIsDisjoint = true; 4769 EXPECT_NE(NewIsDisjoint, OrigIsDisjoint); 4770 PDI->setIsDisjoint(NewIsDisjoint); 4771 EXPECT_EQ(PDI->isDisjoint(), NewIsDisjoint); 4772 PDI->setIsDisjoint(OrigIsDisjoint); 4773 EXPECT_EQ(PDI->isDisjoint(), OrigIsDisjoint); 4774 } 4775 4776 TEST_F(SandboxIRTest, AtomicRMWInst) { 4777 parseIR(C, R"IR( 4778 define void @foo(ptr %ptr, i8 %arg) { 4779 %atomicrmw = atomicrmw add ptr %ptr, i8 %arg acquire, align 128 4780 ret void 4781 } 4782 )IR"); 4783 llvm::Function &LLVMF = *M->getFunction("foo"); 4784 llvm::BasicBlock *LLVMBB = &*LLVMF.begin(); 4785 auto LLVMIt = LLVMBB->begin(); 4786 auto *LLVMRMW = cast<llvm::AtomicRMWInst>(&*LLVMIt++); 4787 4788 sandboxir::Context Ctx(C); 4789 sandboxir::Function *F = Ctx.createFunction(&LLVMF); 4790 auto *Ptr = F->getArg(0); 4791 auto *Arg = F->getArg(1); 4792 auto *BB = &*F->begin(); 4793 auto It = BB->begin(); 4794 auto *RMW = cast<sandboxir::AtomicRMWInst>(&*It++); 4795 auto *Ret = cast<sandboxir::ReturnInst>(&*It++); 4796 4797 // Check getOperationName(). 4798 EXPECT_EQ( 4799 sandboxir::AtomicRMWInst::getOperationName( 4800 sandboxir::AtomicRMWInst::BinOp::Add), 4801 llvm::AtomicRMWInst::getOperationName(llvm::AtomicRMWInst::BinOp::Add)); 4802 // Check isFPOperation(). 4803 EXPECT_EQ( 4804 sandboxir::AtomicRMWInst::isFPOperation( 4805 sandboxir::AtomicRMWInst::BinOp::Add), 4806 llvm::AtomicRMWInst::isFPOperation(llvm::AtomicRMWInst::BinOp::Add)); 4807 EXPECT_FALSE(sandboxir::AtomicRMWInst::isFPOperation( 4808 sandboxir::AtomicRMWInst::BinOp::Add)); 4809 EXPECT_TRUE(sandboxir::AtomicRMWInst::isFPOperation( 4810 sandboxir::AtomicRMWInst::BinOp::FAdd)); 4811 // Check setOperation(), getOperation(). 4812 EXPECT_EQ(RMW->getOperation(), LLVMRMW->getOperation()); 4813 RMW->setOperation(sandboxir::AtomicRMWInst::BinOp::Sub); 4814 EXPECT_EQ(RMW->getOperation(), sandboxir::AtomicRMWInst::BinOp::Sub); 4815 RMW->setOperation(sandboxir::AtomicRMWInst::BinOp::Add); 4816 // Check getAlign(). 4817 EXPECT_EQ(RMW->getAlign(), LLVMRMW->getAlign()); 4818 auto OrigAlign = RMW->getAlign(); 4819 Align NewAlign(256); 4820 EXPECT_NE(NewAlign, OrigAlign); 4821 RMW->setAlignment(NewAlign); 4822 EXPECT_EQ(RMW->getAlign(), NewAlign); 4823 RMW->setAlignment(OrigAlign); 4824 EXPECT_EQ(RMW->getAlign(), OrigAlign); 4825 // Check isVolatile(), setVolatile(). 4826 EXPECT_EQ(RMW->isVolatile(), LLVMRMW->isVolatile()); 4827 bool OrigV = RMW->isVolatile(); 4828 bool NewV = true; 4829 EXPECT_NE(NewV, OrigV); 4830 RMW->setVolatile(NewV); 4831 EXPECT_EQ(RMW->isVolatile(), NewV); 4832 RMW->setVolatile(OrigV); 4833 EXPECT_EQ(RMW->isVolatile(), OrigV); 4834 // Check getOrdering(), setOrdering(). 4835 EXPECT_EQ(RMW->getOrdering(), LLVMRMW->getOrdering()); 4836 auto OldOrdering = RMW->getOrdering(); 4837 auto NewOrdering = AtomicOrdering::Monotonic; 4838 EXPECT_NE(NewOrdering, OldOrdering); 4839 RMW->setOrdering(NewOrdering); 4840 EXPECT_EQ(RMW->getOrdering(), NewOrdering); 4841 RMW->setOrdering(OldOrdering); 4842 EXPECT_EQ(RMW->getOrdering(), OldOrdering); 4843 // Check getSyncScopeID(), setSyncScopeID(). 4844 EXPECT_EQ(RMW->getSyncScopeID(), LLVMRMW->getSyncScopeID()); 4845 auto OrigSSID = RMW->getSyncScopeID(); 4846 SyncScope::ID NewSSID = SyncScope::SingleThread; 4847 EXPECT_NE(NewSSID, OrigSSID); 4848 RMW->setSyncScopeID(NewSSID); 4849 EXPECT_EQ(RMW->getSyncScopeID(), NewSSID); 4850 RMW->setSyncScopeID(OrigSSID); 4851 EXPECT_EQ(RMW->getSyncScopeID(), OrigSSID); 4852 // Check getPointerOperand(). 4853 EXPECT_EQ(RMW->getPointerOperand(), 4854 Ctx.getValue(LLVMRMW->getPointerOperand())); 4855 // Check getValOperand(). 4856 EXPECT_EQ(RMW->getValOperand(), Ctx.getValue(LLVMRMW->getValOperand())); 4857 // Check getPointerAddressSpace(). 4858 EXPECT_EQ(RMW->getPointerAddressSpace(), LLVMRMW->getPointerAddressSpace()); 4859 // Check isFloatingPointOperation(). 4860 EXPECT_EQ(RMW->isFloatingPointOperation(), 4861 LLVMRMW->isFloatingPointOperation()); 4862 4863 Align Align(1024); 4864 auto Ordering = AtomicOrdering::Acquire; 4865 auto SSID = SyncScope::System; 4866 { 4867 // Check create() WhereIt, WhereBB. 4868 auto *NewI = 4869 cast<sandboxir::AtomicRMWInst>(sandboxir::AtomicRMWInst::create( 4870 sandboxir::AtomicRMWInst::BinOp::Sub, Ptr, Arg, Align, Ordering, 4871 /*WhereIt=*/Ret->getIterator(), 4872 /*WhereBB=*/Ret->getParent(), Ctx, SSID, "NewAtomicRMW1")); 4873 // Check getOpcode(). 4874 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::AtomicRMW); 4875 // Check getAlign(). 4876 EXPECT_EQ(NewI->getAlign(), Align); 4877 // Check getSuccessOrdering(). 4878 EXPECT_EQ(NewI->getOrdering(), Ordering); 4879 // Check instr position. 4880 EXPECT_EQ(NewI->getNextNode(), Ret); 4881 // Check getPointerOperand(). 4882 EXPECT_EQ(NewI->getPointerOperand(), Ptr); 4883 // Check getValOperand(). 4884 EXPECT_EQ(NewI->getValOperand(), Arg); 4885 #ifndef NDEBUG 4886 // Check getName(). 4887 EXPECT_EQ(NewI->getName(), "NewAtomicRMW1"); 4888 #endif // NDEBUG 4889 } 4890 { 4891 // Check create() InsertBefore. 4892 auto *NewI = 4893 cast<sandboxir::AtomicRMWInst>(sandboxir::AtomicRMWInst::create( 4894 sandboxir::AtomicRMWInst::BinOp::Sub, Ptr, Arg, Align, Ordering, 4895 /*InsertBefore=*/Ret, Ctx, SSID, "NewAtomicRMW2")); 4896 // Check getOpcode(). 4897 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::AtomicRMW); 4898 // Check getAlign(). 4899 EXPECT_EQ(NewI->getAlign(), Align); 4900 // Check getSuccessOrdering(). 4901 EXPECT_EQ(NewI->getOrdering(), Ordering); 4902 // Check instr position. 4903 EXPECT_EQ(NewI->getNextNode(), Ret); 4904 // Check getPointerOperand(). 4905 EXPECT_EQ(NewI->getPointerOperand(), Ptr); 4906 // Check getValOperand(). 4907 EXPECT_EQ(NewI->getValOperand(), Arg); 4908 #ifndef NDEBUG 4909 // Check getName(). 4910 EXPECT_EQ(NewI->getName(), "NewAtomicRMW2"); 4911 #endif // NDEBUG 4912 } 4913 { 4914 // Check create() InsertAtEnd. 4915 auto *NewI = 4916 cast<sandboxir::AtomicRMWInst>(sandboxir::AtomicRMWInst::create( 4917 sandboxir::AtomicRMWInst::BinOp::Sub, Ptr, Arg, Align, Ordering, 4918 /*InsertAtEnd=*/BB, Ctx, SSID, "NewAtomicRMW3")); 4919 // Check getOpcode(). 4920 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::AtomicRMW); 4921 // Check getAlign(). 4922 EXPECT_EQ(NewI->getAlign(), Align); 4923 // Check getSuccessOrdering(). 4924 EXPECT_EQ(NewI->getOrdering(), Ordering); 4925 // Check instr position. 4926 EXPECT_EQ(NewI->getParent(), BB); 4927 EXPECT_EQ(NewI->getNextNode(), nullptr); 4928 // Check getPointerOperand(). 4929 EXPECT_EQ(NewI->getPointerOperand(), Ptr); 4930 // Check getValOperand(). 4931 EXPECT_EQ(NewI->getValOperand(), Arg); 4932 #ifndef NDEBUG 4933 // Check getName(). 4934 EXPECT_EQ(NewI->getName(), "NewAtomicRMW3"); 4935 #endif // NDEBUG 4936 } 4937 } 4938 4939 TEST_F(SandboxIRTest, AtomicCmpXchgInst) { 4940 parseIR(C, R"IR( 4941 define void @foo(ptr %ptr, i8 %cmp, i8 %new) { 4942 %cmpxchg = cmpxchg ptr %ptr, i8 %cmp, i8 %new monotonic monotonic, align 128 4943 ret void 4944 } 4945 )IR"); 4946 llvm::Function &LLVMF = *M->getFunction("foo"); 4947 llvm::BasicBlock *LLVMBB = &*LLVMF.begin(); 4948 auto LLVMIt = LLVMBB->begin(); 4949 auto *LLVMCmpXchg = cast<llvm::AtomicCmpXchgInst>(&*LLVMIt++); 4950 4951 sandboxir::Context Ctx(C); 4952 sandboxir::Function *F = Ctx.createFunction(&LLVMF); 4953 auto *Ptr = F->getArg(0); 4954 auto *Cmp = F->getArg(1); 4955 auto *New = F->getArg(2); 4956 auto *BB = &*F->begin(); 4957 auto It = BB->begin(); 4958 auto *CmpXchg = cast<sandboxir::AtomicCmpXchgInst>(&*It++); 4959 auto *Ret = cast<sandboxir::ReturnInst>(&*It++); 4960 4961 // Check getAlign(), setAlignment(). 4962 EXPECT_EQ(CmpXchg->getAlign(), LLVMCmpXchg->getAlign()); 4963 auto OrigAlign = CmpXchg->getAlign(); 4964 Align NewAlign(256); 4965 EXPECT_NE(NewAlign, OrigAlign); 4966 CmpXchg->setAlignment(NewAlign); 4967 EXPECT_EQ(CmpXchg->getAlign(), NewAlign); 4968 CmpXchg->setAlignment(OrigAlign); 4969 EXPECT_EQ(CmpXchg->getAlign(), OrigAlign); 4970 // Check isVolatile(), setVolatile(). 4971 EXPECT_EQ(CmpXchg->isVolatile(), LLVMCmpXchg->isVolatile()); 4972 bool OrigV = CmpXchg->isVolatile(); 4973 bool NewV = true; 4974 EXPECT_NE(NewV, OrigV); 4975 CmpXchg->setVolatile(NewV); 4976 EXPECT_EQ(CmpXchg->isVolatile(), NewV); 4977 CmpXchg->setVolatile(OrigV); 4978 EXPECT_EQ(CmpXchg->isVolatile(), OrigV); 4979 // Check isWeak(), setWeak(). 4980 EXPECT_EQ(CmpXchg->isWeak(), LLVMCmpXchg->isWeak()); 4981 bool OrigWeak = CmpXchg->isWeak(); 4982 bool NewWeak = true; 4983 EXPECT_NE(NewWeak, OrigWeak); 4984 CmpXchg->setWeak(NewWeak); 4985 EXPECT_EQ(CmpXchg->isWeak(), NewWeak); 4986 CmpXchg->setWeak(OrigWeak); 4987 EXPECT_EQ(CmpXchg->isWeak(), OrigWeak); 4988 // Check isValidSuccessOrdering(), isValidFailureOrdering(). 4989 SmallVector<AtomicOrdering> AllOrderings( 4990 {AtomicOrdering::NotAtomic, AtomicOrdering::Unordered, 4991 AtomicOrdering::Monotonic, AtomicOrdering::Acquire, 4992 AtomicOrdering::Release, AtomicOrdering::AcquireRelease, 4993 AtomicOrdering::SequentiallyConsistent}); 4994 for (auto Ordering : AllOrderings) { 4995 EXPECT_EQ(sandboxir::AtomicCmpXchgInst::isValidSuccessOrdering(Ordering), 4996 llvm::AtomicCmpXchgInst::isValidSuccessOrdering(Ordering)); 4997 EXPECT_EQ(sandboxir::AtomicCmpXchgInst::isValidFailureOrdering(Ordering), 4998 llvm::AtomicCmpXchgInst::isValidFailureOrdering(Ordering)); 4999 } 5000 // Check getSuccessOrdering(), setSuccessOrdering(). 5001 EXPECT_EQ(CmpXchg->getSuccessOrdering(), LLVMCmpXchg->getSuccessOrdering()); 5002 auto OldSuccOrdering = CmpXchg->getSuccessOrdering(); 5003 auto NewSuccOrdering = AtomicOrdering::Acquire; 5004 EXPECT_NE(NewSuccOrdering, OldSuccOrdering); 5005 CmpXchg->setSuccessOrdering(NewSuccOrdering); 5006 EXPECT_EQ(CmpXchg->getSuccessOrdering(), NewSuccOrdering); 5007 CmpXchg->setSuccessOrdering(OldSuccOrdering); 5008 EXPECT_EQ(CmpXchg->getSuccessOrdering(), OldSuccOrdering); 5009 // Check getFailureOrdering(), setFailureOrdering(). 5010 EXPECT_EQ(CmpXchg->getFailureOrdering(), LLVMCmpXchg->getFailureOrdering()); 5011 auto OldFailOrdering = CmpXchg->getFailureOrdering(); 5012 auto NewFailOrdering = AtomicOrdering::Acquire; 5013 EXPECT_NE(NewFailOrdering, OldFailOrdering); 5014 CmpXchg->setFailureOrdering(NewFailOrdering); 5015 EXPECT_EQ(CmpXchg->getFailureOrdering(), NewFailOrdering); 5016 CmpXchg->setFailureOrdering(OldFailOrdering); 5017 EXPECT_EQ(CmpXchg->getFailureOrdering(), OldFailOrdering); 5018 // Check getMergedOrdering(). 5019 EXPECT_EQ(CmpXchg->getMergedOrdering(), LLVMCmpXchg->getMergedOrdering()); 5020 // Check getSyncScopeID(), setSyncScopeID(). 5021 EXPECT_EQ(CmpXchg->getSyncScopeID(), LLVMCmpXchg->getSyncScopeID()); 5022 auto OrigSSID = CmpXchg->getSyncScopeID(); 5023 SyncScope::ID NewSSID = SyncScope::SingleThread; 5024 EXPECT_NE(NewSSID, OrigSSID); 5025 CmpXchg->setSyncScopeID(NewSSID); 5026 EXPECT_EQ(CmpXchg->getSyncScopeID(), NewSSID); 5027 CmpXchg->setSyncScopeID(OrigSSID); 5028 EXPECT_EQ(CmpXchg->getSyncScopeID(), OrigSSID); 5029 // Check getPointerOperand(). 5030 EXPECT_EQ(CmpXchg->getPointerOperand(), 5031 Ctx.getValue(LLVMCmpXchg->getPointerOperand())); 5032 // Check getCompareOperand(). 5033 EXPECT_EQ(CmpXchg->getCompareOperand(), 5034 Ctx.getValue(LLVMCmpXchg->getCompareOperand())); 5035 // Check getNewValOperand(). 5036 EXPECT_EQ(CmpXchg->getNewValOperand(), 5037 Ctx.getValue(LLVMCmpXchg->getNewValOperand())); 5038 // Check getPointerAddressSpace(). 5039 EXPECT_EQ(CmpXchg->getPointerAddressSpace(), 5040 LLVMCmpXchg->getPointerAddressSpace()); 5041 5042 Align Align(1024); 5043 auto SuccOrdering = AtomicOrdering::Acquire; 5044 auto FailOrdering = AtomicOrdering::Monotonic; 5045 auto SSID = SyncScope::System; 5046 { 5047 // Check create() WhereIt, WhereBB. 5048 auto *NewI = 5049 cast<sandboxir::AtomicCmpXchgInst>(sandboxir::AtomicCmpXchgInst::create( 5050 Ptr, Cmp, New, Align, SuccOrdering, FailOrdering, 5051 /*WhereIt=*/Ret->getIterator(), 5052 /*WhereBB=*/Ret->getParent(), Ctx, SSID, "NewAtomicCmpXchg1")); 5053 // Check getOpcode(). 5054 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::AtomicCmpXchg); 5055 // Check getAlign(). 5056 EXPECT_EQ(NewI->getAlign(), Align); 5057 // Check getSuccessOrdering(). 5058 EXPECT_EQ(NewI->getSuccessOrdering(), SuccOrdering); 5059 // Check getFailureOrdering(). 5060 EXPECT_EQ(NewI->getFailureOrdering(), FailOrdering); 5061 // Check instr position. 5062 EXPECT_EQ(NewI->getNextNode(), Ret); 5063 // Check getPointerOperand(). 5064 EXPECT_EQ(NewI->getPointerOperand(), Ptr); 5065 // Check getCompareOperand(). 5066 EXPECT_EQ(NewI->getCompareOperand(), Cmp); 5067 // Check getNewValOperand(). 5068 EXPECT_EQ(NewI->getNewValOperand(), New); 5069 #ifndef NDEBUG 5070 // Check getName(). 5071 EXPECT_EQ(NewI->getName(), "NewAtomicCmpXchg1"); 5072 #endif // NDEBUG 5073 } 5074 { 5075 // Check create() InsertBefore. 5076 auto *NewI = 5077 cast<sandboxir::AtomicCmpXchgInst>(sandboxir::AtomicCmpXchgInst::create( 5078 Ptr, Cmp, New, Align, SuccOrdering, FailOrdering, 5079 /*InsertBefore=*/Ret, Ctx, SSID, "NewAtomicCmpXchg2")); 5080 // Check getOpcode(). 5081 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::AtomicCmpXchg); 5082 // Check getAlign(). 5083 EXPECT_EQ(NewI->getAlign(), Align); 5084 // Check getSuccessOrdering(). 5085 EXPECT_EQ(NewI->getSuccessOrdering(), SuccOrdering); 5086 // Check getFailureOrdering(). 5087 EXPECT_EQ(NewI->getFailureOrdering(), FailOrdering); 5088 // Check instr position. 5089 EXPECT_EQ(NewI->getNextNode(), Ret); 5090 // Check getPointerOperand(). 5091 EXPECT_EQ(NewI->getPointerOperand(), Ptr); 5092 // Check getCompareOperand(). 5093 EXPECT_EQ(NewI->getCompareOperand(), Cmp); 5094 // Check getNewValOperand(). 5095 EXPECT_EQ(NewI->getNewValOperand(), New); 5096 #ifndef NDEBUG 5097 // Check getName(). 5098 EXPECT_EQ(NewI->getName(), "NewAtomicCmpXchg2"); 5099 #endif // NDEBUG 5100 } 5101 { 5102 // Check create() InsertAtEnd. 5103 auto *NewI = 5104 cast<sandboxir::AtomicCmpXchgInst>(sandboxir::AtomicCmpXchgInst::create( 5105 Ptr, Cmp, New, Align, SuccOrdering, FailOrdering, 5106 /*InsertAtEnd=*/BB, Ctx, SSID, "NewAtomicCmpXchg3")); 5107 // Check getOpcode(). 5108 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::AtomicCmpXchg); 5109 // Check getAlign(). 5110 EXPECT_EQ(NewI->getAlign(), Align); 5111 // Check getSuccessOrdering(). 5112 EXPECT_EQ(NewI->getSuccessOrdering(), SuccOrdering); 5113 // Check getFailureOrdering(). 5114 EXPECT_EQ(NewI->getFailureOrdering(), FailOrdering); 5115 // Check instr position. 5116 EXPECT_EQ(NewI->getParent(), BB); 5117 EXPECT_EQ(NewI->getNextNode(), nullptr); 5118 // Check getPointerOperand(). 5119 EXPECT_EQ(NewI->getPointerOperand(), Ptr); 5120 // Check getCompareOperand(). 5121 EXPECT_EQ(NewI->getCompareOperand(), Cmp); 5122 // Check getNewValOperand(). 5123 EXPECT_EQ(NewI->getNewValOperand(), New); 5124 #ifndef NDEBUG 5125 // Check getName(). 5126 EXPECT_EQ(NewI->getName(), "NewAtomicCmpXchg3"); 5127 #endif // NDEBUG 5128 } 5129 } 5130 5131 TEST_F(SandboxIRTest, AllocaInst) { 5132 parseIR(C, R"IR( 5133 define void @foo() { 5134 %allocaScalar = alloca i32, align 1024 5135 %allocaArray = alloca i32, i32 42 5136 ret void 5137 } 5138 )IR"); 5139 const DataLayout &DL = M->getDataLayout(); 5140 llvm::Function &LLVMF = *M->getFunction("foo"); 5141 llvm::BasicBlock *LLVMBB = &*LLVMF.begin(); 5142 auto LLVMIt = LLVMBB->begin(); 5143 auto *LLVMAllocaScalar = cast<llvm::AllocaInst>(&*LLVMIt++); 5144 auto *LLVMAllocaArray = cast<llvm::AllocaInst>(&*LLVMIt++); 5145 5146 sandboxir::Context Ctx(C); 5147 sandboxir::Function *F = Ctx.createFunction(&LLVMF); 5148 auto *BB = &*F->begin(); 5149 auto It = BB->begin(); 5150 auto *AllocaScalar = cast<sandboxir::AllocaInst>(&*It++); 5151 auto *AllocaArray = cast<sandboxir::AllocaInst>(&*It++); 5152 auto *Ret = cast<sandboxir::ReturnInst>(&*It++); 5153 5154 // Check isArrayAllocation(). 5155 EXPECT_EQ(AllocaScalar->isArrayAllocation(), 5156 LLVMAllocaScalar->isArrayAllocation()); 5157 EXPECT_EQ(AllocaArray->isArrayAllocation(), 5158 LLVMAllocaArray->isArrayAllocation()); 5159 // Check getArraySize(). 5160 EXPECT_EQ(AllocaScalar->getArraySize(), 5161 Ctx.getValue(LLVMAllocaScalar->getArraySize())); 5162 EXPECT_EQ(AllocaArray->getArraySize(), 5163 Ctx.getValue(LLVMAllocaArray->getArraySize())); 5164 // Check getType(). 5165 EXPECT_EQ(AllocaScalar->getType(), Ctx.getType(LLVMAllocaScalar->getType())); 5166 EXPECT_EQ(AllocaArray->getType(), Ctx.getType(LLVMAllocaArray->getType())); 5167 // Check getAddressSpace(). 5168 EXPECT_EQ(AllocaScalar->getAddressSpace(), 5169 LLVMAllocaScalar->getAddressSpace()); 5170 EXPECT_EQ(AllocaArray->getAddressSpace(), LLVMAllocaArray->getAddressSpace()); 5171 // Check getAllocationSize(). 5172 EXPECT_EQ(AllocaScalar->getAllocationSize(DL), 5173 LLVMAllocaScalar->getAllocationSize(DL)); 5174 EXPECT_EQ(AllocaArray->getAllocationSize(DL), 5175 LLVMAllocaArray->getAllocationSize(DL)); 5176 // Check getAllocationSizeInBits(). 5177 EXPECT_EQ(AllocaScalar->getAllocationSizeInBits(DL), 5178 LLVMAllocaScalar->getAllocationSizeInBits(DL)); 5179 EXPECT_EQ(AllocaArray->getAllocationSizeInBits(DL), 5180 LLVMAllocaArray->getAllocationSizeInBits(DL)); 5181 // Check getAllocatedType(). 5182 EXPECT_EQ(AllocaScalar->getAllocatedType(), 5183 Ctx.getType(LLVMAllocaScalar->getAllocatedType())); 5184 EXPECT_EQ(AllocaArray->getAllocatedType(), 5185 Ctx.getType(LLVMAllocaArray->getAllocatedType())); 5186 // Check setAllocatedType(). 5187 auto *OrigType = AllocaScalar->getAllocatedType(); 5188 auto *NewType = sandboxir::PointerType::get(Ctx, 0); 5189 EXPECT_NE(NewType, OrigType); 5190 AllocaScalar->setAllocatedType(NewType); 5191 EXPECT_EQ(AllocaScalar->getAllocatedType(), NewType); 5192 AllocaScalar->setAllocatedType(OrigType); 5193 EXPECT_EQ(AllocaScalar->getAllocatedType(), OrigType); 5194 // Check getAlign(). 5195 EXPECT_EQ(AllocaScalar->getAlign(), LLVMAllocaScalar->getAlign()); 5196 EXPECT_EQ(AllocaArray->getAlign(), LLVMAllocaArray->getAlign()); 5197 // Check setAlignment(). 5198 Align OrigAlign = AllocaScalar->getAlign(); 5199 Align NewAlign(16); 5200 EXPECT_NE(NewAlign, OrigAlign); 5201 AllocaScalar->setAlignment(NewAlign); 5202 EXPECT_EQ(AllocaScalar->getAlign(), NewAlign); 5203 AllocaScalar->setAlignment(OrigAlign); 5204 EXPECT_EQ(AllocaScalar->getAlign(), OrigAlign); 5205 // Check isStaticAlloca(). 5206 EXPECT_EQ(AllocaScalar->isStaticAlloca(), LLVMAllocaScalar->isStaticAlloca()); 5207 EXPECT_EQ(AllocaArray->isStaticAlloca(), LLVMAllocaArray->isStaticAlloca()); 5208 // Check isUsedWithInAlloca(), setUsedWithInAlloca(). 5209 EXPECT_EQ(AllocaScalar->isUsedWithInAlloca(), 5210 LLVMAllocaScalar->isUsedWithInAlloca()); 5211 bool OrigUsedWithInAlloca = AllocaScalar->isUsedWithInAlloca(); 5212 bool NewUsedWithInAlloca = true; 5213 EXPECT_NE(NewUsedWithInAlloca, OrigUsedWithInAlloca); 5214 AllocaScalar->setUsedWithInAlloca(NewUsedWithInAlloca); 5215 EXPECT_EQ(AllocaScalar->isUsedWithInAlloca(), NewUsedWithInAlloca); 5216 AllocaScalar->setUsedWithInAlloca(OrigUsedWithInAlloca); 5217 EXPECT_EQ(AllocaScalar->isUsedWithInAlloca(), OrigUsedWithInAlloca); 5218 5219 auto *Ty = sandboxir::Type::getInt32Ty(Ctx); 5220 unsigned AddrSpace = 42; 5221 auto *PtrTy = sandboxir::PointerType::get(Ctx, AddrSpace); 5222 auto *ArraySize = sandboxir::ConstantInt::get(Ty, 43); 5223 { 5224 // Check create() WhereIt, WhereBB. 5225 auto *NewI = cast<sandboxir::AllocaInst>(sandboxir::AllocaInst::create( 5226 Ty, AddrSpace, /*WhereIt=*/Ret->getIterator(), 5227 /*WhereBB=*/Ret->getParent(), Ctx, ArraySize, "NewAlloca1")); 5228 // Check getOpcode(). 5229 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Alloca); 5230 // Check getType(). 5231 EXPECT_EQ(NewI->getType(), PtrTy); 5232 // Check getArraySize(). 5233 EXPECT_EQ(NewI->getArraySize(), ArraySize); 5234 // Check getAddrSpace(). 5235 EXPECT_EQ(NewI->getAddressSpace(), AddrSpace); 5236 // Check instr position. 5237 EXPECT_EQ(NewI->getNextNode(), Ret); 5238 } 5239 { 5240 // Check create() InsertBefore. 5241 auto *NewI = cast<sandboxir::AllocaInst>(sandboxir::AllocaInst::create( 5242 Ty, AddrSpace, /*InsertBefore=*/Ret, Ctx, ArraySize, "NewAlloca2")); 5243 // Check getOpcode(). 5244 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Alloca); 5245 // Check getType(). 5246 EXPECT_EQ(NewI->getType(), PtrTy); 5247 // Check getArraySize(). 5248 EXPECT_EQ(NewI->getArraySize(), ArraySize); 5249 // Check getAddrSpace(). 5250 EXPECT_EQ(NewI->getAddressSpace(), AddrSpace); 5251 // Check instr position. 5252 EXPECT_EQ(NewI->getNextNode(), Ret); 5253 } 5254 { 5255 // Check create() InsertAtEnd. 5256 auto *NewI = cast<sandboxir::AllocaInst>(sandboxir::AllocaInst::create( 5257 Ty, AddrSpace, /*InsertAtEnd=*/BB, Ctx, ArraySize, "NewAlloca3")); 5258 // Check getOpcode(). 5259 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Alloca); 5260 // Check getType(). 5261 EXPECT_EQ(NewI->getType(), PtrTy); 5262 // Check getArraySize(). 5263 EXPECT_EQ(NewI->getArraySize(), ArraySize); 5264 // Check getAddrSpace(). 5265 EXPECT_EQ(NewI->getAddressSpace(), AddrSpace); 5266 // Check instr position. 5267 EXPECT_EQ(NewI->getParent(), BB); 5268 EXPECT_EQ(NewI->getNextNode(), nullptr); 5269 } 5270 } 5271 5272 TEST_F(SandboxIRTest, CastInst) { 5273 parseIR(C, R"IR( 5274 define void @foo(i32 %arg, float %farg, double %darg, ptr %ptr) { 5275 %zext = zext i32 %arg to i64 5276 %sext = sext i32 %arg to i64 5277 %fptoui = fptoui float %farg to i32 5278 %fptosi = fptosi float %farg to i32 5279 %fpext = fpext float %farg to double 5280 %ptrtoint = ptrtoint ptr %ptr to i32 5281 %inttoptr = inttoptr i32 %arg to ptr 5282 %sitofp = sitofp i32 %arg to float 5283 %uitofp = uitofp i32 %arg to float 5284 %trunc = trunc i32 %arg to i16 5285 %fptrunc = fptrunc double %darg to float 5286 %bitcast = bitcast i32 %arg to float 5287 %addrspacecast = addrspacecast ptr %ptr to ptr addrspace(1) 5288 ret void 5289 } 5290 )IR"); 5291 Function &LLVMF = *M->getFunction("foo"); 5292 sandboxir::Context Ctx(C); 5293 sandboxir::Function *F = Ctx.createFunction(&LLVMF); 5294 unsigned ArgIdx = 0; 5295 auto *Arg = F->getArg(ArgIdx++); 5296 auto *BB = &*F->begin(); 5297 auto It = BB->begin(); 5298 5299 auto *Ti64 = sandboxir::Type::getInt64Ty(Ctx); 5300 auto *Ti32 = sandboxir::Type::getInt32Ty(Ctx); 5301 auto *Ti16 = sandboxir::Type::getInt16Ty(Ctx); 5302 auto *Tdouble = sandboxir::Type::getDoubleTy(Ctx); 5303 auto *Tfloat = sandboxir::Type::getFloatTy(Ctx); 5304 auto *Tptr = sandboxir::PointerType::get(Tfloat, 0); 5305 auto *Tptr1 = sandboxir::PointerType::get(Tfloat, 1); 5306 5307 // Check classof(), getOpcode(), getSrcTy(), getDstTy() 5308 auto *ZExt = cast<sandboxir::CastInst>(&*It++); 5309 auto *ZExtI = cast<sandboxir::ZExtInst>(ZExt); 5310 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(ZExtI)); 5311 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(ZExtI)); 5312 EXPECT_EQ(ZExt->getOpcode(), sandboxir::Instruction::Opcode::ZExt); 5313 EXPECT_EQ(ZExt->getSrcTy(), Ti32); 5314 EXPECT_EQ(ZExt->getDestTy(), Ti64); 5315 5316 auto *SExt = cast<sandboxir::CastInst>(&*It++); 5317 auto *SExtI = cast<sandboxir::SExtInst>(SExt); 5318 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(SExt)); 5319 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(SExtI)); 5320 EXPECT_EQ(SExt->getOpcode(), sandboxir::Instruction::Opcode::SExt); 5321 EXPECT_EQ(SExt->getSrcTy(), Ti32); 5322 EXPECT_EQ(SExt->getDestTy(), Ti64); 5323 5324 auto *FPToUI = cast<sandboxir::CastInst>(&*It++); 5325 auto *FPToUII = cast<sandboxir::FPToUIInst>(FPToUI); 5326 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(FPToUI)); 5327 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(FPToUII)); 5328 EXPECT_EQ(FPToUI->getOpcode(), sandboxir::Instruction::Opcode::FPToUI); 5329 EXPECT_EQ(FPToUI->getSrcTy(), Tfloat); 5330 EXPECT_EQ(FPToUI->getDestTy(), Ti32); 5331 5332 auto *FPToSI = cast<sandboxir::CastInst>(&*It++); 5333 auto *FPToSII = cast<sandboxir::FPToSIInst>(FPToSI); 5334 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(FPToSI)); 5335 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(FPToSII)); 5336 EXPECT_EQ(FPToSI->getOpcode(), sandboxir::Instruction::Opcode::FPToSI); 5337 EXPECT_EQ(FPToSI->getSrcTy(), Tfloat); 5338 EXPECT_EQ(FPToSI->getDestTy(), Ti32); 5339 5340 auto *FPExt = cast<sandboxir::CastInst>(&*It++); 5341 auto *FPExtI = cast<sandboxir::FPExtInst>(FPExt); 5342 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(FPExt)); 5343 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(FPExtI)); 5344 EXPECT_EQ(FPExt->getOpcode(), sandboxir::Instruction::Opcode::FPExt); 5345 EXPECT_EQ(FPExt->getSrcTy(), Tfloat); 5346 EXPECT_EQ(FPExt->getDestTy(), Tdouble); 5347 5348 auto *PtrToInt = cast<sandboxir::CastInst>(&*It++); 5349 auto *PtrToIntI = cast<sandboxir::PtrToIntInst>(PtrToInt); 5350 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(PtrToInt)); 5351 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(PtrToIntI)); 5352 EXPECT_EQ(PtrToInt->getOpcode(), sandboxir::Instruction::Opcode::PtrToInt); 5353 EXPECT_EQ(PtrToInt->getSrcTy(), Tptr); 5354 EXPECT_EQ(PtrToInt->getDestTy(), Ti32); 5355 5356 auto *IntToPtr = cast<sandboxir::CastInst>(&*It++); 5357 auto *IntToPtrI = cast<sandboxir::IntToPtrInst>(IntToPtr); 5358 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(IntToPtr)); 5359 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(IntToPtrI)); 5360 EXPECT_EQ(IntToPtr->getOpcode(), sandboxir::Instruction::Opcode::IntToPtr); 5361 EXPECT_EQ(IntToPtr->getSrcTy(), Ti32); 5362 EXPECT_EQ(IntToPtr->getDestTy(), Tptr); 5363 5364 auto *SIToFP = cast<sandboxir::CastInst>(&*It++); 5365 auto *SIToFPI = cast<sandboxir::SIToFPInst>(SIToFP); 5366 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(SIToFP)); 5367 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(SIToFPI)); 5368 EXPECT_EQ(SIToFP->getOpcode(), sandboxir::Instruction::Opcode::SIToFP); 5369 EXPECT_EQ(SIToFP->getSrcTy(), Ti32); 5370 EXPECT_EQ(SIToFP->getDestTy(), Tfloat); 5371 5372 auto *UIToFP = cast<sandboxir::CastInst>(&*It++); 5373 auto *UIToFPI = cast<sandboxir::UIToFPInst>(UIToFP); 5374 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(UIToFP)); 5375 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(UIToFPI)); 5376 EXPECT_EQ(UIToFP->getOpcode(), sandboxir::Instruction::Opcode::UIToFP); 5377 EXPECT_EQ(UIToFP->getSrcTy(), Ti32); 5378 EXPECT_EQ(UIToFP->getDestTy(), Tfloat); 5379 5380 auto *Trunc = cast<sandboxir::CastInst>(&*It++); 5381 auto *TruncI = cast<sandboxir::TruncInst>(Trunc); 5382 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(Trunc)); 5383 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(TruncI)); 5384 EXPECT_EQ(Trunc->getOpcode(), sandboxir::Instruction::Opcode::Trunc); 5385 EXPECT_EQ(Trunc->getSrcTy(), Ti32); 5386 EXPECT_EQ(Trunc->getDestTy(), Ti16); 5387 5388 auto *FPTrunc = cast<sandboxir::CastInst>(&*It++); 5389 auto *FPTruncI = cast<sandboxir::FPTruncInst>(FPTrunc); 5390 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(FPTrunc)); 5391 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(FPTruncI)); 5392 EXPECT_EQ(FPTrunc->getOpcode(), sandboxir::Instruction::Opcode::FPTrunc); 5393 EXPECT_EQ(FPTrunc->getSrcTy(), Tdouble); 5394 EXPECT_EQ(FPTrunc->getDestTy(), Tfloat); 5395 5396 auto *BitCast = cast<sandboxir::CastInst>(&*It++); 5397 auto *BitCastI = cast<sandboxir::BitCastInst>(BitCast); 5398 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(BitCast)); 5399 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(BitCastI)); 5400 EXPECT_EQ(BitCast->getOpcode(), sandboxir::Instruction::Opcode::BitCast); 5401 EXPECT_EQ(BitCast->getSrcTy(), Ti32); 5402 EXPECT_EQ(BitCast->getDestTy(), Tfloat); 5403 5404 auto *AddrSpaceCast = cast<sandboxir::CastInst>(&*It++); 5405 auto *AddrSpaceCastI = cast<sandboxir::AddrSpaceCastInst>(AddrSpaceCast); 5406 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(AddrSpaceCast)); 5407 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(AddrSpaceCastI)); 5408 EXPECT_EQ(AddrSpaceCast->getOpcode(), 5409 sandboxir::Instruction::Opcode::AddrSpaceCast); 5410 EXPECT_EQ(AddrSpaceCast->getSrcTy(), Tptr); 5411 EXPECT_EQ(AddrSpaceCast->getDestTy(), Tptr1); 5412 5413 auto *Ret = cast<sandboxir::ReturnInst>(&*It++); 5414 5415 { 5416 // Check create() WhereIt, WhereBB 5417 auto *NewI = cast<sandboxir::CastInst>(sandboxir::CastInst::create( 5418 Ti64, sandboxir::Instruction::Opcode::SExt, Arg, /*WhereIt=*/BB->end(), 5419 /*WhereBB=*/BB, Ctx, "SExt")); 5420 // Check getOpcode(). 5421 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::SExt); 5422 // Check getSrcTy(). 5423 EXPECT_EQ(NewI->getSrcTy(), Arg->getType()); 5424 // Check getDestTy(). 5425 EXPECT_EQ(NewI->getDestTy(), Ti64); 5426 // Check instr position. 5427 EXPECT_EQ(NewI->getNextNode(), nullptr); 5428 EXPECT_EQ(NewI->getPrevNode(), Ret); 5429 } 5430 5431 { 5432 // Check create() InsertBefore. 5433 auto *NewI = cast<sandboxir::CastInst>( 5434 sandboxir::CastInst::create(Ti64, sandboxir::Instruction::Opcode::ZExt, 5435 Arg, /*InsertBefore=*/Ret, Ctx, "ZExt")); 5436 // Check getOpcode(). 5437 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::ZExt); 5438 // Check getSrcTy(). 5439 EXPECT_EQ(NewI->getSrcTy(), Arg->getType()); 5440 // Check getDestTy(). 5441 EXPECT_EQ(NewI->getDestTy(), Ti64); 5442 // Check instr position. 5443 EXPECT_EQ(NewI->getNextNode(), Ret); 5444 } 5445 { 5446 // Check create() InsertAtEnd. 5447 auto *NewI = cast<sandboxir::CastInst>( 5448 sandboxir::CastInst::create(Ti64, sandboxir::Instruction::Opcode::ZExt, 5449 Arg, /*InsertAtEnd=*/BB, Ctx, "ZExt")); 5450 // Check getOpcode(). 5451 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::ZExt); 5452 // Check getSrcTy(). 5453 EXPECT_EQ(NewI->getSrcTy(), Arg->getType()); 5454 // Check getDestTy(). 5455 EXPECT_EQ(NewI->getDestTy(), Ti64); 5456 // Check instr position. 5457 EXPECT_EQ(NewI->getNextNode(), nullptr); 5458 EXPECT_EQ(NewI->getParent(), BB); 5459 } 5460 5461 { 5462 #ifndef NDEBUG 5463 // Check that passing a non-cast opcode crashes. 5464 EXPECT_DEATH( 5465 sandboxir::CastInst::create(Ti64, sandboxir::Instruction::Opcode::Store, 5466 Arg, /*InsertBefore=*/Ret, Ctx, "Bad"), 5467 ".*Opcode.*"); 5468 #endif // NDEBUG 5469 } 5470 } 5471 5472 TEST_F(SandboxIRTest, PossiblyNonNegInst) { 5473 parseIR(C, R"IR( 5474 define void @foo(i32 %arg, float %farg, double %darg, ptr %ptr) { 5475 %zext = zext i32 %arg to i64 5476 %uitofp = uitofp i32 %arg to float 5477 5478 %sext = sext i32 %arg to i64 5479 %fptoui = fptoui float %farg to i32 5480 %fptosi = fptosi float %farg to i32 5481 %fpext = fpext float %farg to double 5482 %ptrtoint = ptrtoint ptr %ptr to i32 5483 %inttoptr = inttoptr i32 %arg to ptr 5484 %sitofp = sitofp i32 %arg to float 5485 %trunc = trunc i32 %arg to i16 5486 %fptrunc = fptrunc double %darg to float 5487 %bitcast = bitcast i32 %arg to float 5488 %addrspacecast = addrspacecast ptr %ptr to ptr addrspace(1) 5489 ret void 5490 } 5491 )IR"); 5492 Function &LLVMF = *M->getFunction("foo"); 5493 sandboxir::Context Ctx(C); 5494 sandboxir::Function *F = Ctx.createFunction(&LLVMF); 5495 auto *BB = &*F->begin(); 5496 auto It = BB->begin(); 5497 auto *PNNI0 = cast<sandboxir::PossiblyNonNegInst>(&*It++); 5498 auto *PNNI1 = cast<sandboxir::PossiblyNonNegInst>(&*It++); 5499 for (auto ItE = BB->end(); It != ItE; ++It) 5500 EXPECT_FALSE(isa<sandboxir::PossiblyNonNegInst>(&*It++)); 5501 5502 for (auto *PNNI : {PNNI0, PNNI1}) { 5503 // Check setNonNeg(), hasNonNeg(). 5504 auto OrigNonNeg = PNNI->hasNonNeg(); 5505 auto NewNonNeg = true; 5506 EXPECT_NE(NewNonNeg, OrigNonNeg); 5507 PNNI->setNonNeg(NewNonNeg); 5508 EXPECT_EQ(PNNI->hasNonNeg(), NewNonNeg); 5509 PNNI->setNonNeg(OrigNonNeg); 5510 EXPECT_EQ(PNNI->hasNonNeg(), OrigNonNeg); 5511 } 5512 } 5513 5514 /// CastInst's subclasses are very similar so we can use a common test function 5515 /// for them. 5516 template <typename SubclassT, sandboxir::Instruction::Opcode OpcodeT> 5517 void testCastInst(llvm::Module &M, llvm::Type *LLVMSrcTy, 5518 llvm::Type *LLVMDstTy) { 5519 Function &LLVMF = *M.getFunction("foo"); 5520 sandboxir::Context Ctx(M.getContext()); 5521 sandboxir::Function *F = Ctx.createFunction(&LLVMF); 5522 sandboxir::Type *SrcTy = Ctx.getType(LLVMSrcTy); 5523 sandboxir::Type *DstTy = Ctx.getType(LLVMDstTy); 5524 unsigned ArgIdx = 0; 5525 auto *Arg = F->getArg(ArgIdx++); 5526 auto *BB = &*F->begin(); 5527 auto It = BB->begin(); 5528 5529 auto *CI = cast<SubclassT>(&*It++); 5530 EXPECT_EQ(CI->getOpcode(), OpcodeT); 5531 EXPECT_EQ(CI->getSrcTy(), SrcTy); 5532 EXPECT_EQ(CI->getDestTy(), DstTy); 5533 auto *Ret = cast<sandboxir::ReturnInst>(&*It++); 5534 5535 { 5536 // Check create() WhereIt, WhereBB 5537 auto *NewI = 5538 cast<SubclassT>(SubclassT::create(Arg, DstTy, /*WhereIt=*/BB->end(), 5539 /*WhereBB=*/BB, Ctx, "NewCI")); 5540 // Check getOpcode(). 5541 EXPECT_EQ(NewI->getOpcode(), OpcodeT); 5542 // Check getSrcTy(). 5543 EXPECT_EQ(NewI->getSrcTy(), Arg->getType()); 5544 // Check getDestTy(). 5545 EXPECT_EQ(NewI->getDestTy(), DstTy); 5546 // Check instr position. 5547 EXPECT_EQ(NewI->getNextNode(), nullptr); 5548 EXPECT_EQ(NewI->getPrevNode(), Ret); 5549 // Check instr name. 5550 EXPECT_EQ(NewI->getName(), "NewCI"); 5551 } 5552 { 5553 // Check create() InsertBefore. 5554 auto *NewI = 5555 cast<SubclassT>(SubclassT::create(Arg, DstTy, 5556 /*InsertBefore=*/Ret, Ctx, "NewCI")); 5557 // Check getOpcode(). 5558 EXPECT_EQ(NewI->getOpcode(), OpcodeT); 5559 // Check getSrcTy(). 5560 EXPECT_EQ(NewI->getSrcTy(), Arg->getType()); 5561 // Check getDestTy(). 5562 EXPECT_EQ(NewI->getDestTy(), DstTy); 5563 // Check instr position. 5564 EXPECT_EQ(NewI->getNextNode(), Ret); 5565 } 5566 { 5567 // Check create() InsertAtEnd. 5568 auto *NewI = 5569 cast<SubclassT>(SubclassT::create(Arg, DstTy, 5570 /*InsertAtEnd=*/BB, Ctx, "NewCI")); 5571 // Check getOpcode(). 5572 EXPECT_EQ(NewI->getOpcode(), OpcodeT); 5573 // Check getSrcTy(). 5574 EXPECT_EQ(NewI->getSrcTy(), Arg->getType()); 5575 // Check getDestTy(). 5576 EXPECT_EQ(NewI->getDestTy(), DstTy); 5577 // Check instr position. 5578 EXPECT_EQ(NewI->getNextNode(), nullptr); 5579 EXPECT_EQ(NewI->getParent(), BB); 5580 } 5581 } 5582 5583 TEST_F(SandboxIRTest, TruncInst) { 5584 parseIR(C, R"IR( 5585 define void @foo(i64 %arg) { 5586 %trunc = trunc i64 %arg to i32 5587 ret void 5588 } 5589 )IR"); 5590 testCastInst<sandboxir::TruncInst, sandboxir::Instruction::Opcode::Trunc>( 5591 *M, 5592 /*SrcTy=*/Type::getInt64Ty(C), /*DstTy=*/Type::getInt32Ty(C)); 5593 } 5594 5595 TEST_F(SandboxIRTest, ZExtInst) { 5596 parseIR(C, R"IR( 5597 define void @foo(i32 %arg) { 5598 %zext = zext i32 %arg to i64 5599 ret void 5600 } 5601 )IR"); 5602 testCastInst<sandboxir::ZExtInst, sandboxir::Instruction::Opcode::ZExt>( 5603 *M, 5604 /*SrcTy=*/Type::getInt32Ty(C), /*DstTy=*/Type::getInt64Ty(C)); 5605 } 5606 5607 TEST_F(SandboxIRTest, SExtInst) { 5608 parseIR(C, R"IR( 5609 define void @foo(i32 %arg) { 5610 %sext = sext i32 %arg to i64 5611 ret void 5612 } 5613 )IR"); 5614 testCastInst<sandboxir::SExtInst, sandboxir::Instruction::Opcode::SExt>( 5615 *M, 5616 /*SrcTy=*/Type::getInt32Ty(C), /*DstTy=*/Type::getInt64Ty(C)); 5617 } 5618 5619 TEST_F(SandboxIRTest, FPTruncInst) { 5620 parseIR(C, R"IR( 5621 define void @foo(double %arg) { 5622 %fptrunc = fptrunc double %arg to float 5623 ret void 5624 } 5625 )IR"); 5626 testCastInst<sandboxir::FPTruncInst, sandboxir::Instruction::Opcode::FPTrunc>( 5627 *M, 5628 /*SrcTy=*/Type::getDoubleTy(C), /*DstTy=*/Type::getFloatTy(C)); 5629 } 5630 5631 TEST_F(SandboxIRTest, FPExtInst) { 5632 parseIR(C, R"IR( 5633 define void @foo(float %arg) { 5634 %fpext = fpext float %arg to double 5635 ret void 5636 } 5637 )IR"); 5638 testCastInst<sandboxir::FPExtInst, sandboxir::Instruction::Opcode::FPExt>( 5639 *M, 5640 /*SrcTy=*/Type::getFloatTy(C), /*DstTy=*/Type::getDoubleTy(C)); 5641 } 5642 5643 TEST_F(SandboxIRTest, UIToFPInst) { 5644 parseIR(C, R"IR( 5645 define void @foo(i32 %arg) { 5646 %uitofp = uitofp i32 %arg to float 5647 ret void 5648 } 5649 )IR"); 5650 testCastInst<sandboxir::UIToFPInst, sandboxir::Instruction::Opcode::UIToFP>( 5651 *M, 5652 /*SrcTy=*/Type::getInt32Ty(C), /*DstTy=*/Type::getFloatTy(C)); 5653 } 5654 5655 TEST_F(SandboxIRTest, SIToFPInst) { 5656 parseIR(C, R"IR( 5657 define void @foo(i32 %arg) { 5658 %sitofp = sitofp i32 %arg to float 5659 ret void 5660 } 5661 )IR"); 5662 testCastInst<sandboxir::SIToFPInst, sandboxir::Instruction::Opcode::SIToFP>( 5663 *M, 5664 /*SrcTy=*/Type::getInt32Ty(C), 5665 /*DstTy=*/Type::getFloatTy(C)); 5666 } 5667 5668 TEST_F(SandboxIRTest, FPToUIInst) { 5669 parseIR(C, R"IR( 5670 define void @foo(float %arg) { 5671 %fptoui = fptoui float %arg to i32 5672 ret void 5673 } 5674 )IR"); 5675 testCastInst<sandboxir::FPToUIInst, sandboxir::Instruction::Opcode::FPToUI>( 5676 5677 *M, /*SrcTy=*/Type::getFloatTy(C), /*DstTy=*/Type::getInt32Ty(C)); 5678 } 5679 5680 TEST_F(SandboxIRTest, FPToSIInst) { 5681 parseIR(C, R"IR( 5682 define void @foo(float %arg) { 5683 %fptosi = fptosi float %arg to i32 5684 ret void 5685 } 5686 )IR"); 5687 testCastInst<sandboxir::FPToSIInst, sandboxir::Instruction::Opcode::FPToSI>( 5688 *M, /*SrcTy=*/Type::getFloatTy(C), /*DstTy=*/Type::getInt32Ty(C)); 5689 } 5690 5691 TEST_F(SandboxIRTest, IntToPtrInst) { 5692 parseIR(C, R"IR( 5693 define void @foo(i32 %arg) { 5694 %inttoptr = inttoptr i32 %arg to ptr 5695 ret void 5696 } 5697 )IR"); 5698 testCastInst<sandboxir::IntToPtrInst, 5699 sandboxir::Instruction::Opcode::IntToPtr>( 5700 *M, 5701 /*SrcTy=*/Type::getInt32Ty(C), /*DstTy=*/PointerType::get(C, 0)); 5702 } 5703 5704 TEST_F(SandboxIRTest, PtrToIntInst) { 5705 parseIR(C, R"IR( 5706 define void @foo(ptr %ptr) { 5707 %ptrtoint = ptrtoint ptr %ptr to i32 5708 ret void 5709 } 5710 )IR"); 5711 testCastInst<sandboxir::PtrToIntInst, 5712 sandboxir::Instruction::Opcode::PtrToInt>( 5713 *M, /*SrcTy=*/PointerType::get(C, 0), /*DstTy=*/Type::getInt32Ty(C)); 5714 } 5715 5716 TEST_F(SandboxIRTest, BitCastInst) { 5717 parseIR(C, R"IR( 5718 define void @foo(i32 %arg) { 5719 %bitcast = bitcast i32 %arg to float 5720 ret void 5721 } 5722 )IR"); 5723 testCastInst<sandboxir::BitCastInst, sandboxir::Instruction::Opcode::BitCast>( 5724 *M, 5725 /*SrcTy=*/Type::getInt32Ty(C), /*DstTy=*/Type::getFloatTy(C)); 5726 } 5727 5728 TEST_F(SandboxIRTest, AddrSpaceCastInst) { 5729 parseIR(C, R"IR( 5730 define void @foo(ptr %ptr) { 5731 %addrspacecast = addrspacecast ptr %ptr to ptr addrspace(1) 5732 ret void 5733 } 5734 )IR"); 5735 Type *Tptr0 = PointerType::get(C, 0); 5736 Type *Tptr1 = PointerType::get(C, 1); 5737 testCastInst<sandboxir::AddrSpaceCastInst, 5738 sandboxir::Instruction::Opcode::AddrSpaceCast>(*M, 5739 /*SrcTy=*/Tptr0, 5740 /*DstTy=*/Tptr1); 5741 Function &LLVMF = *M->getFunction("foo"); 5742 sandboxir::Context Ctx(C); 5743 sandboxir::Function *F = Ctx.createFunction(&LLVMF); 5744 unsigned ArgIdx = 0; 5745 auto *Arg = F->getArg(ArgIdx++); 5746 auto *BB = &*F->begin(); 5747 auto It = BB->begin(); 5748 5749 auto *AddrSpaceCast = cast<sandboxir::AddrSpaceCastInst>(&*It++); 5750 EXPECT_EQ(AddrSpaceCast->getOpcode(), 5751 sandboxir::Instruction::Opcode::AddrSpaceCast); 5752 EXPECT_EQ(AddrSpaceCast->getPointerOperand(), Arg); 5753 EXPECT_EQ(sandboxir::AddrSpaceCastInst::getPointerOperandIndex(), 0u); 5754 EXPECT_EQ(AddrSpaceCast->getSrcAddressSpace(), 5755 cast<PointerType>(Tptr0)->getPointerAddressSpace()); 5756 EXPECT_EQ(AddrSpaceCast->getDestAddressSpace(), 5757 cast<PointerType>(Tptr1)->getPointerAddressSpace()); 5758 } 5759 5760 TEST_F(SandboxIRTest, PHINode) { 5761 parseIR(C, R"IR( 5762 define void @foo(i32 %arg) { 5763 bb1: 5764 br label %bb2 5765 5766 bb2: 5767 %phi = phi i32 [ %arg, %bb1 ], [ 0, %bb2 ], [ 1, %bb3 ], [ 2, %bb4 ], [ 3, %bb5 ] 5768 br label %bb2 5769 5770 bb3: 5771 br label %bb2 5772 5773 bb4: 5774 br label %bb2 5775 5776 bb5: 5777 br label %bb2 5778 ret void 5779 } 5780 )IR"); 5781 Function &LLVMF = *M->getFunction("foo"); 5782 auto *LLVMBB1 = getBasicBlockByName(LLVMF, "bb1"); 5783 auto *LLVMBB2 = getBasicBlockByName(LLVMF, "bb2"); 5784 auto *LLVMBB3 = getBasicBlockByName(LLVMF, "bb3"); 5785 auto LLVMIt = LLVMBB2->begin(); 5786 auto *LLVMPHI = cast<llvm::PHINode>(&*LLVMIt++); 5787 sandboxir::Context Ctx(C); 5788 sandboxir::Function *F = Ctx.createFunction(&LLVMF); 5789 auto *Arg = F->getArg(0); 5790 auto *BB1 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB1)); 5791 auto *BB2 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB2)); 5792 auto *BB3 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB3)); 5793 auto It = BB2->begin(); 5794 // Check classof(). 5795 auto *PHI = cast<sandboxir::PHINode>(&*It++); 5796 auto *Br = cast<sandboxir::BranchInst>(&*It++); 5797 // Check blocks(). 5798 EXPECT_EQ(range_size(PHI->blocks()), range_size(LLVMPHI->blocks())); 5799 auto BlockIt = PHI->block_begin(); 5800 for (llvm::BasicBlock *LLVMBB : LLVMPHI->blocks()) { 5801 sandboxir::BasicBlock *BB = *BlockIt++; 5802 EXPECT_EQ(BB, Ctx.getValue(LLVMBB)); 5803 } 5804 // Check incoming_values(). 5805 EXPECT_EQ(range_size(PHI->incoming_values()), 5806 range_size(LLVMPHI->incoming_values())); 5807 auto IncIt = PHI->incoming_values().begin(); 5808 for (llvm::Value *LLVMV : LLVMPHI->incoming_values()) { 5809 sandboxir::Value *IncV = *IncIt++; 5810 EXPECT_EQ(IncV, Ctx.getValue(LLVMV)); 5811 } 5812 // Check getNumIncomingValues(). 5813 EXPECT_EQ(PHI->getNumIncomingValues(), LLVMPHI->getNumIncomingValues()); 5814 // Check getIncomingValue(). 5815 EXPECT_EQ(PHI->getIncomingValue(0), 5816 Ctx.getValue(LLVMPHI->getIncomingValue(0))); 5817 EXPECT_EQ(PHI->getIncomingValue(1), 5818 Ctx.getValue(LLVMPHI->getIncomingValue(1))); 5819 // Check setIncomingValue(). 5820 auto *OrigV = PHI->getIncomingValue(0); 5821 PHI->setIncomingValue(0, PHI); 5822 EXPECT_EQ(PHI->getIncomingValue(0), PHI); 5823 PHI->setIncomingValue(0, OrigV); 5824 // Check getOperandNumForIncomingValue(). 5825 EXPECT_EQ(sandboxir::PHINode::getOperandNumForIncomingValue(0), 5826 llvm::PHINode::getOperandNumForIncomingValue(0)); 5827 // Check getIncomingValueNumForOperand(). 5828 EXPECT_EQ(sandboxir::PHINode::getIncomingValueNumForOperand(0), 5829 llvm::PHINode::getIncomingValueNumForOperand(0)); 5830 // Check getIncomingBlock(unsigned). 5831 EXPECT_EQ(PHI->getIncomingBlock(0), 5832 Ctx.getValue(LLVMPHI->getIncomingBlock(0))); 5833 // Check getIncomingBlock(Use). 5834 llvm::Use &LLVMUse = LLVMPHI->getOperandUse(0); 5835 sandboxir::Use Use = PHI->getOperandUse(0); 5836 EXPECT_EQ(PHI->getIncomingBlock(Use), 5837 Ctx.getValue(LLVMPHI->getIncomingBlock(LLVMUse))); 5838 // Check setIncomingBlock(). 5839 sandboxir::BasicBlock *OrigBB = PHI->getIncomingBlock(0); 5840 EXPECT_NE(OrigBB, BB2); 5841 PHI->setIncomingBlock(0, BB2); 5842 EXPECT_EQ(PHI->getIncomingBlock(0), BB2); 5843 PHI->setIncomingBlock(0, OrigBB); 5844 EXPECT_EQ(PHI->getIncomingBlock(0), OrigBB); 5845 // Check addIncoming(). 5846 unsigned OrigNumIncoming = PHI->getNumIncomingValues(); 5847 PHI->addIncoming(Arg, BB3); 5848 EXPECT_EQ(PHI->getNumIncomingValues(), LLVMPHI->getNumIncomingValues()); 5849 EXPECT_EQ(PHI->getNumIncomingValues(), OrigNumIncoming + 1); 5850 EXPECT_EQ(PHI->getIncomingValue(OrigNumIncoming), Arg); 5851 EXPECT_EQ(PHI->getIncomingBlock(OrigNumIncoming), BB3); 5852 // Check removeIncomingValue(unsigned). 5853 PHI->removeIncomingValue(OrigNumIncoming); 5854 EXPECT_EQ(PHI->getNumIncomingValues(), OrigNumIncoming); 5855 // Check removeIncomingValue(BasicBlock *). 5856 PHI->addIncoming(Arg, BB3); 5857 PHI->removeIncomingValue(BB3); 5858 EXPECT_EQ(PHI->getNumIncomingValues(), OrigNumIncoming); 5859 // Check getBasicBlockIndex(). 5860 EXPECT_EQ(PHI->getBasicBlockIndex(BB1), LLVMPHI->getBasicBlockIndex(LLVMBB1)); 5861 // Check getIncomingValueForBlock(). 5862 EXPECT_EQ(PHI->getIncomingValueForBlock(BB1), 5863 Ctx.getValue(LLVMPHI->getIncomingValueForBlock(LLVMBB1))); 5864 // Check hasConstantValue(). 5865 llvm::Value *ConstV = LLVMPHI->hasConstantValue(); 5866 EXPECT_EQ(PHI->hasConstantValue(), 5867 ConstV != nullptr ? Ctx.getValue(ConstV) : nullptr); 5868 // Check hasConstantOrUndefValue(). 5869 EXPECT_EQ(PHI->hasConstantOrUndefValue(), LLVMPHI->hasConstantOrUndefValue()); 5870 // Check isComplete(). 5871 EXPECT_EQ(PHI->isComplete(), LLVMPHI->isComplete()); 5872 // Check replaceIncomingValueIf 5873 EXPECT_EQ(PHI->getNumIncomingValues(), 5u); 5874 auto *RemainBB0 = PHI->getIncomingBlock(0); 5875 auto *RemoveBB0 = PHI->getIncomingBlock(1); 5876 auto *RemainBB1 = PHI->getIncomingBlock(2); 5877 auto *RemoveBB1 = PHI->getIncomingBlock(3); 5878 auto *RemainBB2 = PHI->getIncomingBlock(4); 5879 PHI->removeIncomingValueIf([&](unsigned Idx) { 5880 return PHI->getIncomingBlock(Idx) == RemoveBB0 || 5881 PHI->getIncomingBlock(Idx) == RemoveBB1; 5882 }); 5883 EXPECT_EQ(PHI->getNumIncomingValues(), 3u); 5884 EXPECT_EQ(PHI->getIncomingBlock(0), RemainBB0); 5885 EXPECT_EQ(PHI->getIncomingBlock(1), RemainBB1); 5886 EXPECT_EQ(PHI->getIncomingBlock(2), RemainBB2); 5887 // Check replaceIncomingBlockWith 5888 OrigBB = RemainBB0; 5889 auto *NewBB = RemainBB1; 5890 EXPECT_NE(NewBB, OrigBB); 5891 PHI->replaceIncomingBlockWith(OrigBB, NewBB); 5892 EXPECT_EQ(PHI->getIncomingBlock(0), NewBB); 5893 EXPECT_EQ(PHI->getIncomingBlock(1), RemainBB1); 5894 EXPECT_EQ(PHI->getIncomingBlock(2), RemainBB2); 5895 // Check create(). 5896 auto *NewPHI = cast<sandboxir::PHINode>( 5897 sandboxir::PHINode::create(PHI->getType(), 0, Br, Ctx, "NewPHI")); 5898 EXPECT_EQ(NewPHI->getType(), PHI->getType()); 5899 EXPECT_EQ(NewPHI->getNextNode(), Br); 5900 EXPECT_EQ(NewPHI->getName(), "NewPHI"); 5901 EXPECT_EQ(NewPHI->getNumIncomingValues(), 0u); 5902 for (auto [Idx, V] : enumerate(PHI->incoming_values())) { 5903 sandboxir::BasicBlock *IncBB = PHI->getIncomingBlock(Idx); 5904 NewPHI->addIncoming(V, IncBB); 5905 } 5906 EXPECT_EQ(NewPHI->getNumIncomingValues(), PHI->getNumIncomingValues()); 5907 } 5908 5909 static void checkSwapOperands(sandboxir::Context &Ctx, 5910 llvm::sandboxir::CmpInst *Cmp, 5911 llvm::CmpInst *LLVMCmp) { 5912 auto OrigOp0 = Cmp->getOperand(0); 5913 auto OrigOp1 = Cmp->getOperand(1); 5914 EXPECT_EQ(Ctx.getValue(LLVMCmp->getOperand(0)), OrigOp0); 5915 EXPECT_EQ(Ctx.getValue(LLVMCmp->getOperand(1)), OrigOp1); 5916 // This checks the dispatch mechanism in CmpInst, as well as 5917 // the specific implementations. 5918 Cmp->swapOperands(); 5919 EXPECT_EQ(Ctx.getValue(LLVMCmp->getOperand(1)), OrigOp0); 5920 EXPECT_EQ(Ctx.getValue(LLVMCmp->getOperand(0)), OrigOp1); 5921 EXPECT_EQ(Cmp->getOperand(0), OrigOp1); 5922 EXPECT_EQ(Cmp->getOperand(1), OrigOp0); 5923 // Undo it to keep the rest of the test consistent 5924 Cmp->swapOperands(); 5925 } 5926 5927 static void checkCommonPredicates(sandboxir::CmpInst *Cmp, 5928 llvm::CmpInst *LLVMCmp) { 5929 // Check proper creation 5930 auto Pred = Cmp->getPredicate(); 5931 auto LLVMPred = LLVMCmp->getPredicate(); 5932 EXPECT_EQ(Pred, LLVMPred); 5933 // Check setPredicate 5934 Cmp->setPredicate(llvm::CmpInst::FCMP_FALSE); 5935 EXPECT_EQ(Cmp->getPredicate(), llvm::CmpInst::FCMP_FALSE); 5936 EXPECT_EQ(LLVMCmp->getPredicate(), llvm::CmpInst::FCMP_FALSE); 5937 Cmp->setPredicate(Pred); 5938 EXPECT_EQ(LLVMCmp->getPredicate(), Pred); 5939 // Ensure the accessors properly forward to the underlying implementation 5940 EXPECT_STREQ(sandboxir::CmpInst::getPredicateName(Pred).data(), 5941 llvm::CmpInst::getPredicateName(LLVMPred).data()); 5942 EXPECT_EQ(Cmp->isFPPredicate(), LLVMCmp->isFPPredicate()); 5943 EXPECT_EQ(Cmp->isIntPredicate(), LLVMCmp->isIntPredicate()); 5944 EXPECT_EQ(Cmp->getInversePredicate(), LLVMCmp->getInversePredicate()); 5945 EXPECT_EQ(Cmp->getOrderedPredicate(), LLVMCmp->getOrderedPredicate()); 5946 EXPECT_EQ(Cmp->getUnorderedPredicate(), LLVMCmp->getUnorderedPredicate()); 5947 EXPECT_EQ(Cmp->getSwappedPredicate(), LLVMCmp->getSwappedPredicate()); 5948 EXPECT_EQ(Cmp->isStrictPredicate(), LLVMCmp->isStrictPredicate()); 5949 EXPECT_EQ(Cmp->isNonStrictPredicate(), LLVMCmp->isNonStrictPredicate()); 5950 EXPECT_EQ(Cmp->isRelational(), LLVMCmp->isRelational()); 5951 if (Cmp->isRelational()) { 5952 EXPECT_EQ(Cmp->getFlippedStrictnessPredicate(), 5953 LLVMCmp->getFlippedStrictnessPredicate()); 5954 } 5955 EXPECT_EQ(Cmp->isCommutative(), LLVMCmp->isCommutative()); 5956 EXPECT_EQ(Cmp->isTrueWhenEqual(), LLVMCmp->isTrueWhenEqual()); 5957 EXPECT_EQ(Cmp->isFalseWhenEqual(), LLVMCmp->isFalseWhenEqual()); 5958 EXPECT_EQ(sandboxir::CmpInst::isOrdered(Pred), 5959 llvm::CmpInst::isOrdered(LLVMPred)); 5960 EXPECT_EQ(sandboxir::CmpInst::isUnordered(Pred), 5961 llvm::CmpInst::isUnordered(LLVMPred)); 5962 } 5963 5964 TEST_F(SandboxIRTest, ICmpInst) { 5965 SCOPED_TRACE("SandboxIRTest sandboxir::ICmpInst tests"); 5966 parseIR(C, R"IR( 5967 define void @foo(i32 %i0, i32 %i1) { 5968 bb: 5969 %ine = icmp ne i32 %i0, %i1 5970 %iugt = icmp ugt i32 %i0, %i1 5971 %iuge = icmp uge i32 %i0, %i1 5972 %iult = icmp ult i32 %i0, %i1 5973 %iule = icmp ule i32 %i0, %i1 5974 %isgt = icmp sgt i32 %i0, %i1 5975 %isle = icmp sle i32 %i0, %i1 5976 %ieg = icmp eq i32 %i0, %i1 5977 ret void 5978 } 5979 )IR"); 5980 Function &LLVMF = *M->getFunction("foo"); 5981 sandboxir::Context Ctx(C); 5982 [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF); 5983 5984 auto *LLVMBB = getBasicBlockByName(LLVMF, "bb"); 5985 auto LLVMIt = LLVMBB->begin(); 5986 auto *BB = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB)); 5987 auto It = BB->begin(); 5988 // Check classof() 5989 while (auto *ICmp = dyn_cast<sandboxir::ICmpInst>(&*It++)) { 5990 auto *LLVMICmp = cast<llvm::ICmpInst>(&*LLVMIt++); 5991 checkSwapOperands(Ctx, ICmp, LLVMICmp); 5992 checkCommonPredicates(ICmp, LLVMICmp); 5993 EXPECT_EQ(ICmp->isSigned(), LLVMICmp->isSigned()); 5994 EXPECT_EQ(ICmp->isUnsigned(), LLVMICmp->isUnsigned()); 5995 EXPECT_EQ(ICmp->getSignedPredicate(), LLVMICmp->getSignedPredicate()); 5996 EXPECT_EQ(ICmp->getUnsignedPredicate(), LLVMICmp->getUnsignedPredicate()); 5997 } 5998 auto *NewCmp = 5999 sandboxir::CmpInst::create(llvm::CmpInst::ICMP_ULE, F.getArg(0), 6000 F.getArg(1), &*BB->begin(), Ctx, "NewCmp"); 6001 EXPECT_EQ(NewCmp, &*BB->begin()); 6002 EXPECT_EQ(NewCmp->getPredicate(), llvm::CmpInst::ICMP_ULE); 6003 EXPECT_EQ(NewCmp->getOperand(0), F.getArg(0)); 6004 EXPECT_EQ(NewCmp->getOperand(1), F.getArg(1)); 6005 #ifndef NDEBUG 6006 EXPECT_EQ(NewCmp->getName(), "NewCmp"); 6007 #endif // NDEBUG 6008 // TODO: Improve this test when sandboxir::VectorType is more completely 6009 // implemented. 6010 sandboxir::Type *RT = 6011 sandboxir::CmpInst::makeCmpResultType(F.getArg(0)->getType()); 6012 EXPECT_TRUE(RT->isIntegerTy(1)); // Only one bit in a single comparison 6013 } 6014 6015 TEST_F(SandboxIRTest, FCmpInst) { 6016 SCOPED_TRACE("SandboxIRTest sandboxir::FCmpInst tests"); 6017 parseIR(C, R"IR( 6018 define void @foo(float %f0, float %f1) { 6019 bb: 6020 %ffalse = fcmp false float %f0, %f1 6021 %foeq = fcmp oeq float %f0, %f1 6022 %fogt = fcmp ogt float %f0, %f1 6023 %folt = fcmp olt float %f0, %f1 6024 %fole = fcmp ole float %f0, %f1 6025 %fone = fcmp one float %f0, %f1 6026 %ford = fcmp ord float %f0, %f1 6027 %funo = fcmp uno float %f0, %f1 6028 %fueq = fcmp ueq float %f0, %f1 6029 %fugt = fcmp ugt float %f0, %f1 6030 %fuge = fcmp uge float %f0, %f1 6031 %fult = fcmp ult float %f0, %f1 6032 %fule = fcmp ule float %f0, %f1 6033 %fune = fcmp une float %f0, %f1 6034 %ftrue = fcmp true float %f0, %f1 6035 ret void 6036 bb1: 6037 %copyfrom = fadd reassoc float %f0, 42.0 6038 ret void 6039 } 6040 )IR"); 6041 Function &LLVMF = *M->getFunction("foo"); 6042 sandboxir::Context Ctx(C); 6043 [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF); 6044 6045 auto *LLVMBB = getBasicBlockByName(LLVMF, "bb"); 6046 auto LLVMIt = LLVMBB->begin(); 6047 auto *BB = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB)); 6048 auto It = BB->begin(); 6049 // Check classof() 6050 while (auto *FCmp = dyn_cast<sandboxir::ICmpInst>(&*It++)) { 6051 auto *LLVMFCmp = cast<llvm::ICmpInst>(&*LLVMIt++); 6052 checkSwapOperands(Ctx, FCmp, LLVMFCmp); 6053 checkCommonPredicates(FCmp, LLVMFCmp); 6054 } 6055 6056 auto *LLVMBB1 = getBasicBlockByName(LLVMF, "bb1"); 6057 auto *BB1 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB1)); 6058 auto It1 = BB1->begin(); 6059 auto *CopyFrom = &*It1++; 6060 CopyFrom->setFastMathFlags(FastMathFlags::getFast()); 6061 6062 // create with default flags 6063 auto *NewFCmp = sandboxir::CmpInst::create( 6064 llvm::CmpInst::FCMP_ONE, F.getArg(0), F.getArg(1), &*It1, Ctx, "NewFCmp"); 6065 EXPECT_EQ(NewFCmp->getPredicate(), llvm::CmpInst::FCMP_ONE); 6066 EXPECT_EQ(NewFCmp->getOperand(0), F.getArg(0)); 6067 EXPECT_EQ(NewFCmp->getOperand(1), F.getArg(1)); 6068 #ifndef NDEBUG 6069 EXPECT_EQ(NewFCmp->getName(), "NewFCmp"); 6070 #endif // NDEBUG 6071 FastMathFlags DefaultFMF = NewFCmp->getFastMathFlags(); 6072 EXPECT_TRUE(CopyFrom->getFastMathFlags() != DefaultFMF); 6073 // create with copied flags 6074 auto *NewFCmpFlags = sandboxir::CmpInst::createWithCopiedFlags( 6075 llvm::CmpInst::FCMP_ONE, F.getArg(0), F.getArg(1), CopyFrom, &*It1, Ctx, 6076 "NewFCmpFlags"); 6077 EXPECT_FALSE(NewFCmpFlags->getFastMathFlags() != 6078 CopyFrom->getFastMathFlags()); 6079 EXPECT_EQ(NewFCmpFlags->getPredicate(), llvm::CmpInst::FCMP_ONE); 6080 EXPECT_EQ(NewFCmpFlags->getOperand(0), F.getArg(0)); 6081 EXPECT_EQ(NewFCmpFlags->getOperand(1), F.getArg(1)); 6082 #ifndef NDEBUG 6083 EXPECT_EQ(NewFCmpFlags->getName(), "NewFCmpFlags"); 6084 #endif // NDEBUG 6085 } 6086 6087 TEST_F(SandboxIRTest, UnreachableInst) { 6088 parseIR(C, R"IR( 6089 define void @foo() { 6090 unreachable 6091 } 6092 )IR"); 6093 llvm::Function *LLVMF = &*M->getFunction("foo"); 6094 sandboxir::Context Ctx(C); 6095 sandboxir::Function *F = Ctx.createFunction(LLVMF); 6096 auto *BB = &*F->begin(); 6097 auto It = BB->begin(); 6098 auto *UI = cast<sandboxir::UnreachableInst>(&*It++); 6099 6100 EXPECT_EQ(UI->getNumSuccessors(), 0u); 6101 EXPECT_EQ(UI->getNumOfIRInstrs(), 1u); 6102 // Check create(InsertBefore) 6103 sandboxir::UnreachableInst *NewUI = 6104 sandboxir::UnreachableInst::create(/*InsertBefore=*/UI, Ctx); 6105 EXPECT_EQ(NewUI->getNextNode(), UI); 6106 // Check create(InsertAtEnd) 6107 sandboxir::UnreachableInst *NewUIEnd = 6108 sandboxir::UnreachableInst::create(/*InsertAtEnd=*/BB, Ctx); 6109 EXPECT_EQ(NewUIEnd->getParent(), BB); 6110 EXPECT_EQ(NewUIEnd->getNextNode(), nullptr); 6111 } 6112 6113 /// Makes sure that all Instruction sub-classes have a classof(). 6114 TEST_F(SandboxIRTest, CheckClassof) { 6115 #define DEF_INSTR(ID, OPC, CLASS) \ 6116 EXPECT_NE(&sandboxir::CLASS::classof, &sandboxir::Instruction::classof); 6117 #include "llvm/SandboxIR/SandboxIRValues.def" 6118 } 6119