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.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, RAUW_RUWIf) { 1474 parseIR(C, R"IR( 1475 define void @foo(ptr %ptr) { 1476 %ld0 = load float, ptr %ptr 1477 %ld1 = load float, ptr %ptr 1478 store float %ld0, ptr %ptr 1479 store float %ld0, ptr %ptr 1480 ret void 1481 } 1482 )IR"); 1483 llvm::Function &LLVMF = *M->getFunction("foo"); 1484 sandboxir::Context Ctx(C); 1485 llvm::BasicBlock *LLVMBB = &*LLVMF.begin(); 1486 1487 Ctx.createFunction(&LLVMF); 1488 auto *BB = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB)); 1489 auto It = BB->begin(); 1490 sandboxir::Instruction *Ld0 = &*It++; 1491 sandboxir::Instruction *Ld1 = &*It++; 1492 sandboxir::Instruction *St0 = &*It++; 1493 sandboxir::Instruction *St1 = &*It++; 1494 // Check RUWIf when the lambda returns false. 1495 Ld0->replaceUsesWithIf(Ld1, [](const sandboxir::Use &Use) { return false; }); 1496 EXPECT_EQ(St0->getOperand(0), Ld0); 1497 EXPECT_EQ(St1->getOperand(0), Ld0); 1498 // Check RUWIf when the lambda returns true. 1499 Ld0->replaceUsesWithIf(Ld1, [](const sandboxir::Use &Use) { return true; }); 1500 EXPECT_EQ(St0->getOperand(0), Ld1); 1501 EXPECT_EQ(St1->getOperand(0), Ld1); 1502 St0->setOperand(0, Ld0); 1503 St1->setOperand(0, Ld0); 1504 // Check RUWIf user == St0. 1505 Ld0->replaceUsesWithIf( 1506 Ld1, [St0](const sandboxir::Use &Use) { return Use.getUser() == St0; }); 1507 EXPECT_EQ(St0->getOperand(0), Ld1); 1508 EXPECT_EQ(St1->getOperand(0), Ld0); 1509 St0->setOperand(0, Ld0); 1510 // Check RUWIf user == St1. 1511 Ld0->replaceUsesWithIf( 1512 Ld1, [St1](const sandboxir::Use &Use) { return Use.getUser() == St1; }); 1513 EXPECT_EQ(St0->getOperand(0), Ld0); 1514 EXPECT_EQ(St1->getOperand(0), Ld1); 1515 St1->setOperand(0, Ld0); 1516 // Check RAUW. 1517 Ld1->replaceAllUsesWith(Ld0); 1518 EXPECT_EQ(St0->getOperand(0), Ld0); 1519 EXPECT_EQ(St1->getOperand(0), Ld0); 1520 } 1521 1522 // Check that the operands/users are counted correctly. 1523 // I1 1524 // / \ 1525 // \ / 1526 // I2 1527 TEST_F(SandboxIRTest, DuplicateUses) { 1528 parseIR(C, R"IR( 1529 define void @foo(i8 %v) { 1530 %I1 = add i8 %v, %v 1531 %I2 = add i8 %I1, %I1 1532 ret void 1533 } 1534 )IR"); 1535 Function &LLVMF = *M->getFunction("foo"); 1536 sandboxir::Context Ctx(C); 1537 auto *F = Ctx.createFunction(&LLVMF); 1538 auto *BB = &*F->begin(); 1539 auto It = BB->begin(); 1540 auto *I1 = &*It++; 1541 auto *I2 = &*It++; 1542 EXPECT_EQ(range_size(I1->users()), 2u); 1543 EXPECT_EQ(range_size(I2->operands()), 2u); 1544 } 1545 1546 TEST_F(SandboxIRTest, Function) { 1547 parseIR(C, R"IR( 1548 define void @foo0(i32 %arg0, i32 %arg1) { 1549 bb0: 1550 br label %bb1 1551 bb1: 1552 ret void 1553 } 1554 define void @foo1() { 1555 ret void 1556 } 1557 1558 )IR"); 1559 llvm::Function *LLVMF0 = &*M->getFunction("foo0"); 1560 llvm::Function *LLVMF1 = &*M->getFunction("foo1"); 1561 llvm::Argument *LLVMArg0 = LLVMF0->getArg(0); 1562 llvm::Argument *LLVMArg1 = LLVMF0->getArg(1); 1563 1564 sandboxir::Context Ctx(C); 1565 sandboxir::Function *F0 = Ctx.createFunction(LLVMF0); 1566 sandboxir::Function *F1 = Ctx.createFunction(LLVMF1); 1567 1568 // Check getIterator(). 1569 { 1570 auto It0 = F0->getIterator(); 1571 auto It1 = F1->getIterator(); 1572 EXPECT_EQ(&*It0, F0); 1573 EXPECT_EQ(&*It1, F1); 1574 EXPECT_EQ(std::next(It0), It1); 1575 EXPECT_EQ(std::prev(It1), It0); 1576 EXPECT_EQ(&*std::next(It0), F1); 1577 EXPECT_EQ(&*std::prev(It1), F0); 1578 } 1579 // Check getReverseIterator(). 1580 { 1581 auto RevIt0 = F0->getReverseIterator(); 1582 auto RevIt1 = F1->getReverseIterator(); 1583 EXPECT_EQ(&*RevIt0, F0); 1584 EXPECT_EQ(&*RevIt1, F1); 1585 EXPECT_EQ(std::prev(RevIt0), RevIt1); 1586 EXPECT_EQ(std::next(RevIt1), RevIt0); 1587 EXPECT_EQ(&*std::prev(RevIt0), F1); 1588 EXPECT_EQ(&*std::next(RevIt1), F0); 1589 } 1590 1591 // Check F arguments 1592 EXPECT_EQ(F0->arg_size(), 2u); 1593 EXPECT_FALSE(F0->arg_empty()); 1594 EXPECT_EQ(F0->getArg(0), Ctx.getValue(LLVMArg0)); 1595 EXPECT_EQ(F0->getArg(1), Ctx.getValue(LLVMArg1)); 1596 1597 // Check F.begin(), F.end(), Function::iterator 1598 llvm::BasicBlock *LLVMBB = &*LLVMF0->begin(); 1599 for (sandboxir::BasicBlock &BB : *F0) { 1600 EXPECT_EQ(&BB, Ctx.getValue(LLVMBB)); 1601 LLVMBB = LLVMBB->getNextNode(); 1602 } 1603 1604 #ifndef NDEBUG 1605 { 1606 // Check F.dumpNameAndArgs() 1607 std::string Buff; 1608 raw_string_ostream BS(Buff); 1609 F0->dumpNameAndArgs(BS); 1610 EXPECT_EQ(Buff, "void @foo0(i32 %arg0, i32 %arg1)"); 1611 } 1612 { 1613 // Check F.dump() 1614 std::string Buff; 1615 raw_string_ostream BS(Buff); 1616 BS << "\n"; 1617 F0->dumpOS(BS); 1618 EXPECT_EQ(Buff, R"IR( 1619 void @foo0(i32 %arg0, i32 %arg1) { 1620 bb0: 1621 br label %bb1 ; SB4. (Br) 1622 1623 bb1: 1624 ret void ; SB6. (Ret) 1625 } 1626 )IR"); 1627 } 1628 #endif // NDEBUG 1629 } 1630 1631 TEST_F(SandboxIRTest, Module) { 1632 parseIR(C, R"IR( 1633 @glob0 = global i32 42 1634 @glob1 = global i32 43 1635 @internal0 = internal global i32 42 1636 @const0 = constant i32 42 1637 @alias0 = dso_local alias void(), ptr @foo 1638 @ifunc = ifunc void(), ptr @foo 1639 define void @foo() { 1640 ret void 1641 } 1642 define void @bar() { 1643 ret void 1644 } 1645 )IR"); 1646 llvm::Module *LLVMM = &*M; 1647 llvm::Function *LLVMFFoo = &*M->getFunction("foo"); 1648 llvm::Function *LLVMFBar = &*M->getFunction("bar"); 1649 1650 sandboxir::Context Ctx(C); 1651 auto *M = Ctx.createModule(LLVMM); 1652 // Check getContext(). 1653 EXPECT_EQ(&M->getContext(), &Ctx); 1654 // Check getFunction(). 1655 auto *FFoo = M->getFunction("foo"); 1656 auto *FBar = M->getFunction("bar"); 1657 EXPECT_EQ(FFoo, Ctx.getValue(LLVMFFoo)); 1658 EXPECT_EQ(FBar, Ctx.getValue(LLVMFBar)); 1659 // Check getDataLayout(). 1660 EXPECT_EQ(&M->getDataLayout(), &LLVMM->getDataLayout()); 1661 // Check getSourceFileName(). 1662 EXPECT_EQ(M->getSourceFileName(), LLVMM->getSourceFileName()); 1663 // Check getGlobalVariable(). 1664 for (const char *Name : {"global0", "global1", "internal0"}) 1665 EXPECT_EQ(M->getGlobalVariable(Name), 1666 Ctx.getValue(LLVMM->getGlobalVariable(Name))); 1667 // Check getGlobalVariable(AllowInternal). 1668 { 1669 auto *Internal0 = M->getGlobalVariable("internal0", /*AllowInternal=*/true); 1670 EXPECT_TRUE(Internal0 != nullptr); 1671 EXPECT_EQ(Internal0, Ctx.getValue(LLVMM->getNamedGlobal("internal0"))); 1672 } 1673 // Check getNamedGlobal(). 1674 { 1675 auto *Internal = M->getNamedGlobal("internal0"); 1676 EXPECT_TRUE(Internal != nullptr); 1677 EXPECT_EQ(Internal, Ctx.getValue(LLVMM->getNamedGlobal("internal0"))); 1678 } 1679 // Check getNamedAlias(). 1680 auto *Alias0 = M->getNamedAlias("alias0"); 1681 EXPECT_EQ(Alias0, Ctx.getValue(LLVMM->getNamedAlias("alias0"))); 1682 EXPECT_EQ(M->getNamedAlias("aliasFOO"), nullptr); 1683 // Check getNamedIFunc(). 1684 auto *IFunc0 = M->getNamedIFunc("ifunc0"); 1685 EXPECT_EQ(IFunc0, Ctx.getValue(LLVMM->getNamedAlias("ifunc0"))); 1686 EXPECT_EQ(M->getNamedIFunc("ifuncFOO"), nullptr); 1687 } 1688 1689 TEST_F(SandboxIRTest, BasicBlock) { 1690 parseIR(C, R"IR( 1691 define void @foo(i32 %v1) { 1692 bb0: 1693 br label %bb1 1694 bb1: 1695 ret void 1696 } 1697 )IR"); 1698 llvm::Function *LLVMF = &*M->getFunction("foo"); 1699 llvm::BasicBlock *LLVMBB0 = getBasicBlockByName(*LLVMF, "bb0"); 1700 llvm::BasicBlock *LLVMBB1 = getBasicBlockByName(*LLVMF, "bb1"); 1701 1702 sandboxir::Context Ctx(C); 1703 sandboxir::Function *F = Ctx.createFunction(LLVMF); 1704 auto &BB0 = cast<sandboxir::BasicBlock>(*Ctx.getValue(LLVMBB0)); 1705 auto &BB1 = cast<sandboxir::BasicBlock>(*Ctx.getValue(LLVMBB1)); 1706 1707 // Check BB::classof() 1708 EXPECT_TRUE(isa<sandboxir::Value>(BB0)); 1709 EXPECT_FALSE(isa<sandboxir::User>(BB0)); 1710 EXPECT_FALSE(isa<sandboxir::Instruction>(BB0)); 1711 EXPECT_FALSE(isa<sandboxir::Constant>(BB0)); 1712 EXPECT_FALSE(isa<sandboxir::Argument>(BB0)); 1713 1714 // Check BB.getParent() 1715 EXPECT_EQ(BB0.getParent(), F); 1716 EXPECT_EQ(BB1.getParent(), F); 1717 1718 // Check BBIterator, BB.begin(), BB.end(). 1719 llvm::Instruction *LLVMI = &*LLVMBB0->begin(); 1720 for (sandboxir::Instruction &I : BB0) { 1721 EXPECT_EQ(&I, Ctx.getValue(LLVMI)); 1722 LLVMI = LLVMI->getNextNode(); 1723 // Check getNodeParent(). 1724 EXPECT_EQ(I.getIterator().getNodeParent(), &BB0); 1725 } 1726 LLVMI = &*LLVMBB1->begin(); 1727 for (sandboxir::Instruction &I : BB1) { 1728 EXPECT_EQ(&I, Ctx.getValue(LLVMI)); 1729 LLVMI = LLVMI->getNextNode(); 1730 } 1731 // Check NodeParent() for BB::end(). 1732 EXPECT_EQ(BB0.end().getNodeParent(), &BB0); 1733 1734 // Check BB.getTerminator() 1735 EXPECT_EQ(BB0.getTerminator(), Ctx.getValue(LLVMBB0->getTerminator())); 1736 EXPECT_EQ(BB1.getTerminator(), Ctx.getValue(LLVMBB1->getTerminator())); 1737 1738 // Check BB.rbegin(), BB.rend() 1739 EXPECT_EQ(&*BB0.rbegin(), BB0.getTerminator()); 1740 EXPECT_EQ(&*std::prev(BB0.rend()), &*BB0.begin()); 1741 1742 #ifndef NDEBUG 1743 { 1744 // Check BB.dump() 1745 std::string Buff; 1746 raw_string_ostream BS(Buff); 1747 BS << "\n"; 1748 BB0.dumpOS(BS); 1749 EXPECT_EQ(Buff, R"IR( 1750 bb0: 1751 br label %bb1 ; SB3. (Br) 1752 )IR"); 1753 } 1754 #endif // NDEBUG 1755 } 1756 1757 TEST_F(SandboxIRTest, Instruction) { 1758 parseIR(C, R"IR( 1759 define void @foo(i8 %v1, ptr %ptr) { 1760 bb0: 1761 %add0 = add i8 %v1, %v1 1762 %sub1 = sub i8 %add0, %v1 1763 ret void 1764 1765 bb1: 1766 %add1 = add i8 %v1, %v1 1767 %sub2 = sub i8 %add1, %v1 1768 %ld0 = load i8, ptr %ptr 1769 store i8 %ld0, ptr %ptr 1770 store volatile i8 %ld0, ptr %ptr 1771 %atomicrmw = atomicrmw add ptr %ptr, i8 %v1 acquire 1772 %udiv = udiv i8 %ld0, %v1 1773 %urem = urem i8 %ld0, %v1 1774 call void @foo(), !dbg !1 1775 ret void, !tbaa !2 1776 } 1777 1778 !1 = !{} 1779 !2 = !{} 1780 )IR"); 1781 llvm::Function *LLVMF = &*M->getFunction("foo"); 1782 llvm::BasicBlock *LLVMBB1 = getBasicBlockByName(*LLVMF, "bb1"); 1783 sandboxir::Context Ctx(C); 1784 sandboxir::Function *F = Ctx.createFunction(LLVMF); 1785 auto *Arg = F->getArg(0); 1786 auto *BB = cast<sandboxir::BasicBlock>( 1787 Ctx.getValue(getBasicBlockByName(*LLVMF, "bb0"))); 1788 auto It = BB->begin(); 1789 auto *I0 = &*It++; 1790 auto *I1 = &*It++; 1791 auto *Ret = cast<sandboxir::ReturnInst>(&*It++); 1792 1793 // Check getPrevNode(). 1794 EXPECT_EQ(Ret->getPrevNode(), I1); 1795 EXPECT_EQ(I1->getPrevNode(), I0); 1796 EXPECT_EQ(I0->getPrevNode(), nullptr); 1797 1798 // Check getNextNode(). 1799 EXPECT_EQ(I0->getNextNode(), I1); 1800 EXPECT_EQ(I1->getNextNode(), Ret); 1801 EXPECT_EQ(Ret->getNextNode(), nullptr); 1802 1803 // Check getIterator(). 1804 EXPECT_EQ(I0->getIterator(), std::next(BB->begin(), 0)); 1805 EXPECT_EQ(I1->getIterator(), std::next(BB->begin(), 1)); 1806 EXPECT_EQ(Ret->getIterator(), std::next(BB->begin(), 2)); 1807 1808 // Check getOpcode(). 1809 EXPECT_EQ(I0->getOpcode(), sandboxir::Instruction::Opcode::Add); 1810 EXPECT_EQ(I1->getOpcode(), sandboxir::Instruction::Opcode::Sub); 1811 EXPECT_EQ(Ret->getOpcode(), sandboxir::Instruction::Opcode::Ret); 1812 1813 // Check getOpcodeName(). 1814 EXPECT_STREQ(I0->getOpcodeName(), "Add"); 1815 EXPECT_STREQ(I1->getOpcodeName(), "Sub"); 1816 EXPECT_STREQ(Ret->getOpcodeName(), "Ret"); 1817 1818 EXPECT_STREQ(sandboxir::Instruction::getOpcodeName( 1819 sandboxir::Instruction::Opcode::Alloca), 1820 "Alloca"); 1821 1822 // Check moveBefore(I). 1823 I1->moveBefore(I0); 1824 EXPECT_EQ(I0->getPrevNode(), I1); 1825 EXPECT_EQ(I1->getNextNode(), I0); 1826 1827 // Check moveAfter(I). 1828 I1->moveAfter(I0); 1829 EXPECT_EQ(I0->getNextNode(), I1); 1830 EXPECT_EQ(I1->getPrevNode(), I0); 1831 1832 // Check comesBefore(I). 1833 EXPECT_TRUE(I0->comesBefore(I1)); 1834 EXPECT_FALSE(I1->comesBefore(I0)); 1835 1836 // Check moveBefore(BB, It). 1837 I1->moveBefore(*BB, BB->begin()); 1838 EXPECT_EQ(I1->getPrevNode(), nullptr); 1839 EXPECT_EQ(I1->getNextNode(), I0); 1840 I1->moveBefore(*BB, BB->end()); 1841 EXPECT_EQ(I1->getNextNode(), nullptr); 1842 EXPECT_EQ(Ret->getNextNode(), I1); 1843 I1->moveBefore(*BB, std::next(BB->begin())); 1844 EXPECT_EQ(I0->getNextNode(), I1); 1845 EXPECT_EQ(I1->getNextNode(), Ret); 1846 1847 // Check removeFromParent(). 1848 I0->removeFromParent(); 1849 #ifndef NDEBUG 1850 EXPECT_DEATH(I0->getPrevNode(), ".*Detached.*"); 1851 EXPECT_DEATH(I0->getNextNode(), ".*Detached.*"); 1852 #endif // NDEBUG 1853 EXPECT_EQ(I0->getParent(), nullptr); 1854 EXPECT_EQ(I1->getPrevNode(), nullptr); 1855 EXPECT_EQ(I0->getOperand(0), Arg); 1856 1857 // Check insertBefore(). 1858 I0->insertBefore(I1); 1859 EXPECT_EQ(I1->getPrevNode(), I0); 1860 1861 // Check insertInto(). 1862 I0->removeFromParent(); 1863 I0->insertInto(BB, BB->end()); 1864 EXPECT_EQ(Ret->getNextNode(), I0); 1865 I0->moveBefore(I1); 1866 EXPECT_EQ(I0->getNextNode(), I1); 1867 1868 // Check eraseFromParent(). 1869 #ifndef NDEBUG 1870 EXPECT_DEATH(I0->eraseFromParent(), "Still connected to users.*"); 1871 #endif 1872 I1->eraseFromParent(); 1873 EXPECT_EQ(I0->getNumUses(), 0u); 1874 EXPECT_EQ(I0->getNextNode(), Ret); 1875 1876 for (auto &LLVMI : *LLVMBB1) { 1877 auto &I = cast<sandboxir::Instruction>(*Ctx.getValue(&LLVMI)); 1878 // Check isTerminator(). 1879 EXPECT_EQ(LLVMI.isTerminator(), I.isTerminator()); 1880 // Check isUnaryOp(). 1881 EXPECT_EQ(LLVMI.isUnaryOp(), I.isUnaryOp()); 1882 // Check isBinaryOp(). 1883 EXPECT_EQ(LLVMI.isBinaryOp(), I.isBinaryOp()); 1884 // Check isIntDivRem(). 1885 EXPECT_EQ(LLVMI.isIntDivRem(), I.isIntDivRem()); 1886 // Check isShift(). 1887 EXPECT_EQ(LLVMI.isShift(), I.isShift()); 1888 // Check isCast(). 1889 EXPECT_EQ(LLVMI.isCast(), I.isCast()); 1890 // Check isFuncletPad(). 1891 EXPECT_EQ(LLVMI.isFuncletPad(), I.isFuncletPad()); 1892 // Check isSpecialTerminator(). 1893 EXPECT_EQ(LLVMI.isSpecialTerminator(), I.isSpecialTerminator()); 1894 // Check isOnlyUserOfAnyOperand(). 1895 EXPECT_EQ(LLVMI.isOnlyUserOfAnyOperand(), I.isOnlyUserOfAnyOperand()); 1896 // Check isLogicalShift(). 1897 EXPECT_EQ(LLVMI.isLogicalShift(), I.isLogicalShift()); 1898 // Check hasMetadata(). 1899 EXPECT_EQ(LLVMI.hasMetadata(), I.hasMetadata()); 1900 // Check hasMetadataOtherThanDebugLoc(). 1901 EXPECT_EQ(LLVMI.hasMetadataOtherThanDebugLoc(), 1902 I.hasMetadataOtherThanDebugLoc()); 1903 // Check isAssociative(). 1904 EXPECT_EQ(LLVMI.isAssociative(), I.isAssociative()); 1905 // Check isCommutative(). 1906 EXPECT_EQ(LLVMI.isCommutative(), I.isCommutative()); 1907 // Check isIdempotent(). 1908 EXPECT_EQ(LLVMI.isIdempotent(), I.isIdempotent()); 1909 // Check isNilpotent(). 1910 EXPECT_EQ(LLVMI.isNilpotent(), I.isNilpotent()); 1911 // Check mayWriteToMemory(). 1912 EXPECT_EQ(LLVMI.mayWriteToMemory(), I.mayWriteToMemory()); 1913 // Check mayReadFromMemory(). 1914 EXPECT_EQ(LLVMI.mayReadFromMemory(), I.mayReadFromMemory()); 1915 // Check mayReadOrWriteMemory(). 1916 EXPECT_EQ(LLVMI.mayReadOrWriteMemory(), I.mayReadOrWriteMemory()); 1917 // Check isAtomic(). 1918 EXPECT_EQ(LLVMI.isAtomic(), I.isAtomic()); 1919 if (I.isAtomic()) { 1920 // Check hasAtomicLoad(). 1921 EXPECT_EQ(LLVMI.hasAtomicLoad(), I.hasAtomicLoad()); 1922 // Check hasAtomicStore(). 1923 EXPECT_EQ(LLVMI.hasAtomicStore(), I.hasAtomicStore()); 1924 } 1925 // Check isVolatile(). 1926 EXPECT_EQ(LLVMI.isVolatile(), I.isVolatile()); 1927 // Check getAccessType(). 1928 EXPECT_EQ(Ctx.getType(LLVMI.getAccessType()), I.getAccessType()); 1929 // Check mayThrow(). 1930 EXPECT_EQ(LLVMI.mayThrow(), I.mayThrow()); 1931 // Check isFenceLike(). 1932 EXPECT_EQ(LLVMI.isFenceLike(), I.isFenceLike()); 1933 // Check mayHaveSideEffects(). 1934 EXPECT_EQ(LLVMI.mayHaveSideEffects(), I.mayHaveSideEffects()); 1935 } 1936 } 1937 1938 TEST_F(SandboxIRTest, VAArgInst) { 1939 parseIR(C, R"IR( 1940 define void @foo(ptr %va) { 1941 %va_arg = va_arg ptr %va, i32 1942 ret void 1943 } 1944 )IR"); 1945 llvm::Function *LLVMF = &*M->getFunction("foo"); 1946 1947 sandboxir::Context Ctx(C); 1948 sandboxir::Function *F = Ctx.createFunction(LLVMF); 1949 auto *Arg = F->getArg(0); 1950 auto *BB = &*F->begin(); 1951 auto It = BB->begin(); 1952 auto *VA = cast<sandboxir::VAArgInst>(&*It++); 1953 auto *Ret = cast<sandboxir::ReturnInst>(&*It++); 1954 1955 // Check getPointerOperand(). 1956 EXPECT_EQ(VA->getPointerOperand(), Arg); 1957 // Check getPOinterOperandIndex(). 1958 EXPECT_EQ(sandboxir::VAArgInst::getPointerOperandIndex(), 1959 llvm::VAArgInst::getPointerOperandIndex()); 1960 // Check create(). 1961 auto *NewVATy = sandboxir::Type::getInt8Ty(Ctx); 1962 auto *NewVA = sandboxir::VAArgInst::create(Arg, NewVATy, Ret->getIterator(), 1963 Ctx, "NewVA"); 1964 EXPECT_EQ(NewVA->getNextNode(), Ret); 1965 EXPECT_EQ(NewVA->getType(), NewVATy); 1966 #ifndef NDEBUG 1967 EXPECT_EQ(NewVA->getName(), "NewVA"); 1968 #endif // NDEBUG 1969 } 1970 1971 TEST_F(SandboxIRTest, FreezeInst) { 1972 parseIR(C, R"IR( 1973 define void @foo(i8 %arg) { 1974 freeze i8 %arg 1975 ret void 1976 } 1977 )IR"); 1978 llvm::Function *LLVMF = &*M->getFunction("foo"); 1979 1980 sandboxir::Context Ctx(C); 1981 sandboxir::Function *F = Ctx.createFunction(LLVMF); 1982 auto *Arg = F->getArg(0); 1983 auto *BB = &*F->begin(); 1984 auto It = BB->begin(); 1985 auto *Freeze = cast<sandboxir::FreezeInst>(&*It++); 1986 auto *Ret = cast<sandboxir::ReturnInst>(&*It++); 1987 1988 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(Freeze)); 1989 EXPECT_EQ(Freeze->getOperand(0), Arg); 1990 1991 // Check create(). 1992 auto *NewFreeze = 1993 sandboxir::FreezeInst::create(Arg, Ret->getIterator(), Ctx, "NewFreeze"); 1994 EXPECT_EQ(NewFreeze->getNextNode(), Ret); 1995 #ifndef NDEBUG 1996 EXPECT_EQ(NewFreeze->getName(), "NewFreeze"); 1997 #endif // NDEBUG 1998 } 1999 2000 TEST_F(SandboxIRTest, FenceInst) { 2001 parseIR(C, R"IR( 2002 define void @foo() { 2003 fence syncscope("singlethread") seq_cst 2004 ret void 2005 } 2006 )IR"); 2007 llvm::Function *LLVMF = &*M->getFunction("foo"); 2008 llvm::BasicBlock *LLVMBB = &*LLVMF->begin(); 2009 auto *LLVMFence = cast<llvm::FenceInst>(&*LLVMBB->begin()); 2010 sandboxir::Context Ctx(C); 2011 sandboxir::Function *F = Ctx.createFunction(LLVMF); 2012 auto *BB = &*F->begin(); 2013 auto It = BB->begin(); 2014 auto *Fence = cast<sandboxir::FenceInst>(&*It++); 2015 auto *Ret = cast<sandboxir::ReturnInst>(&*It++); 2016 2017 // Check getOrdering(). 2018 EXPECT_EQ(Fence->getOrdering(), LLVMFence->getOrdering()); 2019 // Check setOrdering(). 2020 auto OrigOrdering = Fence->getOrdering(); 2021 auto NewOrdering = AtomicOrdering::Release; 2022 EXPECT_NE(NewOrdering, OrigOrdering); 2023 Fence->setOrdering(NewOrdering); 2024 EXPECT_EQ(Fence->getOrdering(), NewOrdering); 2025 Fence->setOrdering(OrigOrdering); 2026 EXPECT_EQ(Fence->getOrdering(), OrigOrdering); 2027 // Check getSyncScopeID(). 2028 EXPECT_EQ(Fence->getSyncScopeID(), LLVMFence->getSyncScopeID()); 2029 // Check setSyncScopeID(). 2030 auto OrigSSID = Fence->getSyncScopeID(); 2031 auto NewSSID = SyncScope::System; 2032 EXPECT_NE(NewSSID, OrigSSID); 2033 Fence->setSyncScopeID(NewSSID); 2034 EXPECT_EQ(Fence->getSyncScopeID(), NewSSID); 2035 Fence->setSyncScopeID(OrigSSID); 2036 EXPECT_EQ(Fence->getSyncScopeID(), OrigSSID); 2037 // Check create(). 2038 auto *NewFence = 2039 sandboxir::FenceInst::create(AtomicOrdering::Release, Ret->getIterator(), 2040 Ctx, SyncScope::SingleThread); 2041 EXPECT_EQ(NewFence->getNextNode(), Ret); 2042 EXPECT_EQ(NewFence->getOrdering(), AtomicOrdering::Release); 2043 EXPECT_EQ(NewFence->getSyncScopeID(), SyncScope::SingleThread); 2044 } 2045 2046 TEST_F(SandboxIRTest, SelectInst) { 2047 parseIR(C, R"IR( 2048 define void @foo(i1 %c0, i8 %v0, i8 %v1, i1 %c1) { 2049 %sel = select i1 %c0, i8 %v0, i8 %v1 2050 ret void 2051 } 2052 )IR"); 2053 llvm::Function *LLVMF = &*M->getFunction("foo"); 2054 sandboxir::Context Ctx(C); 2055 sandboxir::Function *F = Ctx.createFunction(LLVMF); 2056 auto *Cond0 = F->getArg(0); 2057 auto *V0 = F->getArg(1); 2058 auto *V1 = F->getArg(2); 2059 auto *Cond1 = F->getArg(3); 2060 auto *BB = &*F->begin(); 2061 auto It = BB->begin(); 2062 auto *Select = cast<sandboxir::SelectInst>(&*It++); 2063 const auto *ConstSelect = Select; // To test the const getters. 2064 auto *Ret = &*It++; 2065 2066 // Check getCondition(). 2067 EXPECT_EQ(Select->getCondition(), Cond0); 2068 EXPECT_EQ(ConstSelect->getCondition(), Cond0); 2069 // Check getTrueValue(). 2070 EXPECT_EQ(Select->getTrueValue(), V0); 2071 EXPECT_EQ(ConstSelect->getTrueValue(), V0); 2072 // Check getFalseValue(). 2073 EXPECT_EQ(Select->getFalseValue(), V1); 2074 EXPECT_EQ(ConstSelect->getFalseValue(), V1); 2075 // Check setCondition(). 2076 Select->setCondition(Cond1); 2077 EXPECT_EQ(Select->getCondition(), Cond1); 2078 // Check setTrueValue(). 2079 Select->setTrueValue(V1); 2080 EXPECT_EQ(Select->getTrueValue(), V1); 2081 // Check setFalseValue(). 2082 Select->setFalseValue(V0); 2083 EXPECT_EQ(Select->getFalseValue(), V0); 2084 // Check swapValues(). 2085 Select->swapValues(); 2086 EXPECT_EQ(Select->getTrueValue(), V0); 2087 EXPECT_EQ(Select->getFalseValue(), V1); 2088 // Check areInvalidOperands. 2089 EXPECT_EQ(sandboxir::SelectInst::areInvalidOperands(Cond0, V0, V1), nullptr); 2090 EXPECT_NE(sandboxir::SelectInst::areInvalidOperands(V0, V1, Cond0), nullptr); 2091 2092 { 2093 // Check SelectInst::create() InsertBefore. 2094 auto *NewSel = cast<sandboxir::SelectInst>(sandboxir::SelectInst::create( 2095 Cond0, V0, V1, /*InsertBefore=*/Ret->getIterator(), Ctx)); 2096 EXPECT_EQ(NewSel->getCondition(), Cond0); 2097 EXPECT_EQ(NewSel->getTrueValue(), V0); 2098 EXPECT_EQ(NewSel->getFalseValue(), V1); 2099 EXPECT_EQ(NewSel->getNextNode(), Ret); 2100 } 2101 { 2102 // Check SelectInst::create() InsertAtEnd. 2103 auto *NewSel = cast<sandboxir::SelectInst>( 2104 sandboxir::SelectInst::create(Cond0, V0, V1, /*InsertAtEnd=*/BB, Ctx)); 2105 EXPECT_EQ(NewSel->getCondition(), Cond0); 2106 EXPECT_EQ(NewSel->getTrueValue(), V0); 2107 EXPECT_EQ(NewSel->getFalseValue(), V1); 2108 EXPECT_EQ(NewSel->getPrevNode(), Ret); 2109 } 2110 { 2111 // Check SelectInst::create() Folded. 2112 auto *False = sandboxir::ConstantInt::get(sandboxir::Type::getInt1Ty(Ctx), 2113 0, /*IsSigned=*/false); 2114 auto *FortyTwo = 2115 sandboxir::ConstantInt::get(sandboxir::Type::getInt1Ty(Ctx), 42, 2116 /*IsSigned=*/false); 2117 auto *NewSel = sandboxir::SelectInst::create(False, FortyTwo, FortyTwo, 2118 Ret->getIterator(), Ctx); 2119 EXPECT_TRUE(isa<sandboxir::Constant>(NewSel)); 2120 EXPECT_EQ(NewSel, FortyTwo); 2121 } 2122 } 2123 2124 TEST_F(SandboxIRTest, ExtractElementInst) { 2125 parseIR(C, R"IR( 2126 define void @foo(<2 x i8> %vec, i32 %idx) { 2127 %ins0 = extractelement <2 x i8> %vec, i32 %idx 2128 ret void 2129 } 2130 )IR"); 2131 Function &LLVMF = *M->getFunction("foo"); 2132 sandboxir::Context Ctx(C); 2133 auto &F = *Ctx.createFunction(&LLVMF); 2134 auto *ArgVec = F.getArg(0); 2135 auto *ArgIdx = F.getArg(1); 2136 auto *BB = &*F.begin(); 2137 auto It = BB->begin(); 2138 auto *EI = cast<sandboxir::ExtractElementInst>(&*It++); 2139 auto *Ret = &*It++; 2140 2141 EXPECT_EQ(EI->getOpcode(), sandboxir::Instruction::Opcode::ExtractElement); 2142 EXPECT_EQ(EI->getOperand(0), ArgVec); 2143 EXPECT_EQ(EI->getOperand(1), ArgIdx); 2144 EXPECT_EQ(EI->getVectorOperand(), ArgVec); 2145 EXPECT_EQ(EI->getIndexOperand(), ArgIdx); 2146 EXPECT_EQ(EI->getVectorOperandType(), ArgVec->getType()); 2147 2148 auto *NewI1 = 2149 cast<sandboxir::ExtractElementInst>(sandboxir::ExtractElementInst::create( 2150 ArgVec, ArgIdx, Ret->getIterator(), Ctx, "NewExtrBeforeRet")); 2151 EXPECT_EQ(NewI1->getOperand(0), ArgVec); 2152 EXPECT_EQ(NewI1->getOperand(1), ArgIdx); 2153 EXPECT_EQ(NewI1->getNextNode(), Ret); 2154 2155 auto *NewI2 = 2156 cast<sandboxir::ExtractElementInst>(sandboxir::ExtractElementInst::create( 2157 ArgVec, ArgIdx, BB, Ctx, "NewExtrAtEndOfBB")); 2158 EXPECT_EQ(NewI2->getPrevNode(), Ret); 2159 2160 auto *LLVMArgVec = LLVMF.getArg(0); 2161 auto *LLVMArgIdx = LLVMF.getArg(1); 2162 EXPECT_EQ(sandboxir::ExtractElementInst::isValidOperands(ArgVec, ArgIdx), 2163 llvm::ExtractElementInst::isValidOperands(LLVMArgVec, LLVMArgIdx)); 2164 EXPECT_EQ(sandboxir::ExtractElementInst::isValidOperands(ArgIdx, ArgVec), 2165 llvm::ExtractElementInst::isValidOperands(LLVMArgIdx, LLVMArgVec)); 2166 } 2167 2168 TEST_F(SandboxIRTest, InsertElementInst) { 2169 parseIR(C, R"IR( 2170 define void @foo(i8 %v0, i8 %v1, <2 x i8> %vec) { 2171 %ins0 = insertelement <2 x i8> poison, i8 %v0, i32 0 2172 %ins1 = insertelement <2 x i8> %ins0, i8 %v1, i32 1 2173 ret void 2174 } 2175 )IR"); 2176 Function &LLVMF = *M->getFunction("foo"); 2177 sandboxir::Context Ctx(C); 2178 auto &F = *Ctx.createFunction(&LLVMF); 2179 auto *Arg0 = F.getArg(0); 2180 auto *Arg1 = F.getArg(1); 2181 auto *ArgVec = F.getArg(2); 2182 auto *BB = &*F.begin(); 2183 auto It = BB->begin(); 2184 auto *Ins0 = cast<sandboxir::InsertElementInst>(&*It++); 2185 auto *Ins1 = cast<sandboxir::InsertElementInst>(&*It++); 2186 auto *Ret = &*It++; 2187 2188 EXPECT_EQ(Ins0->getOpcode(), sandboxir::Instruction::Opcode::InsertElement); 2189 EXPECT_EQ(Ins0->getOperand(1), Arg0); 2190 EXPECT_EQ(Ins1->getOperand(1), Arg1); 2191 EXPECT_EQ(Ins1->getOperand(0), Ins0); 2192 auto *Poison = Ins0->getOperand(0); 2193 auto *Idx = Ins0->getOperand(2); 2194 auto *NewI1 = 2195 cast<sandboxir::InsertElementInst>(sandboxir::InsertElementInst::create( 2196 Poison, Arg0, Idx, Ret->getIterator(), Ctx, "NewIns1")); 2197 EXPECT_EQ(NewI1->getOperand(0), Poison); 2198 EXPECT_EQ(NewI1->getNextNode(), Ret); 2199 2200 auto *NewI2 = 2201 cast<sandboxir::InsertElementInst>(sandboxir::InsertElementInst::create( 2202 Poison, Arg0, Idx, BB, Ctx, "NewIns2")); 2203 EXPECT_EQ(NewI2->getPrevNode(), Ret); 2204 2205 auto *LLVMArg0 = LLVMF.getArg(0); 2206 auto *LLVMArgVec = LLVMF.getArg(2); 2207 auto *Zero = sandboxir::ConstantInt::get(sandboxir::Type::getInt8Ty(Ctx), 0); 2208 auto *LLVMZero = llvm::ConstantInt::get(Type::getInt8Ty(C), 0); 2209 EXPECT_EQ( 2210 sandboxir::InsertElementInst::isValidOperands(ArgVec, Arg0, Zero), 2211 llvm::InsertElementInst::isValidOperands(LLVMArgVec, LLVMArg0, LLVMZero)); 2212 EXPECT_EQ( 2213 sandboxir::InsertElementInst::isValidOperands(Arg0, ArgVec, Zero), 2214 llvm::InsertElementInst::isValidOperands(LLVMArg0, LLVMArgVec, LLVMZero)); 2215 } 2216 2217 TEST_F(SandboxIRTest, ShuffleVectorInst) { 2218 parseIR(C, R"IR( 2219 define void @foo(<2 x i8> %v1, <2 x i8> %v2) { 2220 %shuf = shufflevector <2 x i8> %v1, <2 x i8> %v2, <2 x i32> <i32 0, i32 2> 2221 %extr = extractelement <2 x i8> <i8 0, i8 1>, i32 0 2222 ret void 2223 } 2224 )IR"); 2225 Function &LLVMF = *M->getFunction("foo"); 2226 sandboxir::Context Ctx(C); 2227 auto &F = *Ctx.createFunction(&LLVMF); 2228 auto *ArgV1 = F.getArg(0); 2229 auto *ArgV2 = F.getArg(1); 2230 auto *BB = &*F.begin(); 2231 auto It = BB->begin(); 2232 auto *SVI = cast<sandboxir::ShuffleVectorInst>(&*It++); 2233 auto *EEI = cast<sandboxir::ExtractElementInst>(&*It++); 2234 auto *Ret = &*It++; 2235 2236 EXPECT_EQ(SVI->getOpcode(), sandboxir::Instruction::Opcode::ShuffleVector); 2237 EXPECT_EQ(SVI->getOperand(0), ArgV1); 2238 EXPECT_EQ(SVI->getOperand(1), ArgV2); 2239 2240 // In order to test all the methods we need masks of different lengths, so we 2241 // can't simply reuse one of the instructions created above. This helper 2242 // creates a new `shufflevector %v1, %2, <mask>` with the given mask indices. 2243 auto CreateShuffleWithMask = [&](auto &&...Indices) { 2244 SmallVector<int, 4> Mask = {Indices...}; 2245 return cast<sandboxir::ShuffleVectorInst>( 2246 sandboxir::ShuffleVectorInst::create(ArgV1, ArgV2, Mask, 2247 Ret->getIterator(), Ctx)); 2248 }; 2249 2250 // create (InsertBefore) 2251 auto *NewI1 = 2252 cast<sandboxir::ShuffleVectorInst>(sandboxir::ShuffleVectorInst::create( 2253 ArgV1, ArgV2, ArrayRef<int>({0, 2, 1, 3}), Ret->getIterator(), Ctx, 2254 "NewShuffleBeforeRet")); 2255 EXPECT_EQ(NewI1->getOperand(0), ArgV1); 2256 EXPECT_EQ(NewI1->getOperand(1), ArgV2); 2257 EXPECT_EQ(NewI1->getNextNode(), Ret); 2258 #ifndef NDEBUG 2259 EXPECT_EQ(NewI1->getName(), "NewShuffleBeforeRet"); 2260 #endif 2261 2262 // create (InsertAtEnd) 2263 auto *NewI2 = 2264 cast<sandboxir::ShuffleVectorInst>(sandboxir::ShuffleVectorInst::create( 2265 ArgV1, ArgV2, ArrayRef<int>({0, 1}), BB, Ctx, "NewShuffleAtEndOfBB")); 2266 EXPECT_EQ(NewI2->getPrevNode(), Ret); 2267 2268 // Test the path that creates a folded constant. We're currently using an 2269 // extractelement instruction with a constant operand in the textual IR above 2270 // to obtain a constant vector to work with. 2271 // TODO: Refactor this once sandboxir::ConstantVector lands. 2272 auto *ShouldBeConstant = sandboxir::ShuffleVectorInst::create( 2273 EEI->getOperand(0), EEI->getOperand(0), ArrayRef<int>({0, 3}), BB, Ctx); 2274 EXPECT_TRUE(isa<sandboxir::Constant>(ShouldBeConstant)); 2275 2276 // isValidOperands 2277 auto *LLVMArgV1 = LLVMF.getArg(0); 2278 auto *LLVMArgV2 = LLVMF.getArg(1); 2279 SmallVector<int, 2> Mask({1, 2}); 2280 EXPECT_EQ( 2281 sandboxir::ShuffleVectorInst::isValidOperands(ArgV1, ArgV2, Mask), 2282 llvm::ShuffleVectorInst::isValidOperands(LLVMArgV1, LLVMArgV2, Mask)); 2283 EXPECT_EQ(sandboxir::ShuffleVectorInst::isValidOperands(ArgV1, ArgV1, ArgV1), 2284 llvm::ShuffleVectorInst::isValidOperands(LLVMArgV1, LLVMArgV1, 2285 LLVMArgV1)); 2286 2287 // commute 2288 { 2289 auto *I = CreateShuffleWithMask(0, 2); 2290 I->commute(); 2291 EXPECT_EQ(I->getOperand(0), ArgV2); 2292 EXPECT_EQ(I->getOperand(1), ArgV1); 2293 EXPECT_THAT(I->getShuffleMask(), testing::ElementsAre(2, 0)); 2294 } 2295 2296 // getType 2297 EXPECT_EQ(SVI->getType(), ArgV1->getType()); 2298 2299 // getMaskValue 2300 EXPECT_EQ(SVI->getMaskValue(0), 0); 2301 EXPECT_EQ(SVI->getMaskValue(1), 2); 2302 2303 // getShuffleMask / getShuffleMaskForBitcode 2304 { 2305 EXPECT_THAT(SVI->getShuffleMask(), testing::ElementsAre(0, 2)); 2306 2307 SmallVector<int, 2> Result; 2308 SVI->getShuffleMask(Result); 2309 EXPECT_THAT(Result, testing::ElementsAre(0, 2)); 2310 2311 Result.clear(); 2312 sandboxir::ShuffleVectorInst::getShuffleMask( 2313 SVI->getShuffleMaskForBitcode(), Result); 2314 EXPECT_THAT(Result, testing::ElementsAre(0, 2)); 2315 } 2316 2317 // convertShuffleMaskForBitcode 2318 { 2319 auto *C = sandboxir::ShuffleVectorInst::convertShuffleMaskForBitcode( 2320 ArrayRef<int>({2, 3}), ArgV1->getType()); 2321 SmallVector<int, 2> Result; 2322 sandboxir::ShuffleVectorInst::getShuffleMask(C, Result); 2323 EXPECT_THAT(Result, testing::ElementsAre(2, 3)); 2324 } 2325 2326 // setShuffleMask 2327 { 2328 auto *I = CreateShuffleWithMask(0, 1); 2329 I->setShuffleMask(ArrayRef<int>({2, 3})); 2330 EXPECT_THAT(I->getShuffleMask(), testing::ElementsAre(2, 3)); 2331 } 2332 2333 // The following functions check different mask properties. Note that most 2334 // of these come in three different flavors: a method that checks the mask 2335 // in the current instructions and two static member functions that check 2336 // a mask given as an ArrayRef<int> or Constant*, so there's quite a bit of 2337 // repetition in order to check all of them. 2338 2339 // changesLength / increasesLength 2340 { 2341 auto *I = CreateShuffleWithMask(1); 2342 EXPECT_TRUE(I->changesLength()); 2343 EXPECT_FALSE(I->increasesLength()); 2344 } 2345 { 2346 auto *I = CreateShuffleWithMask(1, 1); 2347 EXPECT_FALSE(I->changesLength()); 2348 EXPECT_FALSE(I->increasesLength()); 2349 } 2350 { 2351 auto *I = CreateShuffleWithMask(1, 1, 1); 2352 EXPECT_TRUE(I->changesLength()); 2353 EXPECT_TRUE(I->increasesLength()); 2354 } 2355 2356 // isSingleSource / isSingleSourceMask 2357 { 2358 auto *I = CreateShuffleWithMask(0, 1); 2359 EXPECT_TRUE(I->isSingleSource()); 2360 EXPECT_TRUE(sandboxir::ShuffleVectorInst::isSingleSourceMask( 2361 I->getShuffleMaskForBitcode(), 2)); 2362 EXPECT_TRUE(sandboxir::ShuffleVectorInst::isSingleSourceMask( 2363 I->getShuffleMask(), 2)); 2364 } 2365 { 2366 auto *I = CreateShuffleWithMask(0, 2); 2367 EXPECT_FALSE(I->isSingleSource()); 2368 EXPECT_FALSE(sandboxir::ShuffleVectorInst::isSingleSourceMask( 2369 I->getShuffleMaskForBitcode(), 2)); 2370 EXPECT_FALSE(sandboxir::ShuffleVectorInst::isSingleSourceMask( 2371 I->getShuffleMask(), 2)); 2372 } 2373 2374 // isIdentity / isIdentityMask 2375 { 2376 auto *I = CreateShuffleWithMask(0, 1); 2377 EXPECT_TRUE(I->isIdentity()); 2378 EXPECT_TRUE(sandboxir::ShuffleVectorInst::isIdentityMask( 2379 I->getShuffleMaskForBitcode(), 2)); 2380 EXPECT_TRUE( 2381 sandboxir::ShuffleVectorInst::isIdentityMask(I->getShuffleMask(), 2)); 2382 } 2383 { 2384 auto *I = CreateShuffleWithMask(1, 0); 2385 EXPECT_FALSE(I->isIdentity()); 2386 EXPECT_FALSE(sandboxir::ShuffleVectorInst::isIdentityMask( 2387 I->getShuffleMaskForBitcode(), 2)); 2388 EXPECT_FALSE( 2389 sandboxir::ShuffleVectorInst::isIdentityMask(I->getShuffleMask(), 2)); 2390 } 2391 2392 // isIdentityWithPadding 2393 EXPECT_TRUE(CreateShuffleWithMask(0, 1, -1, -1)->isIdentityWithPadding()); 2394 EXPECT_FALSE(CreateShuffleWithMask(0, 1)->isIdentityWithPadding()); 2395 2396 // isIdentityWithExtract 2397 EXPECT_TRUE(CreateShuffleWithMask(0)->isIdentityWithExtract()); 2398 EXPECT_FALSE(CreateShuffleWithMask(0, 1)->isIdentityWithExtract()); 2399 EXPECT_FALSE(CreateShuffleWithMask(0, 1, 2)->isIdentityWithExtract()); 2400 EXPECT_FALSE(CreateShuffleWithMask(1)->isIdentityWithExtract()); 2401 2402 // isConcat 2403 EXPECT_TRUE(CreateShuffleWithMask(0, 1, 2, 3)->isConcat()); 2404 EXPECT_FALSE(CreateShuffleWithMask(0, 3)->isConcat()); 2405 2406 // isSelect / isSelectMask 2407 { 2408 auto *I = CreateShuffleWithMask(0, 3); 2409 EXPECT_TRUE(I->isSelect()); 2410 EXPECT_TRUE(sandboxir::ShuffleVectorInst::isSelectMask( 2411 I->getShuffleMaskForBitcode(), 2)); 2412 EXPECT_TRUE( 2413 sandboxir::ShuffleVectorInst::isSelectMask(I->getShuffleMask(), 2)); 2414 } 2415 { 2416 auto *I = CreateShuffleWithMask(0, 2); 2417 EXPECT_FALSE(I->isSelect()); 2418 EXPECT_FALSE(sandboxir::ShuffleVectorInst::isSelectMask( 2419 I->getShuffleMaskForBitcode(), 2)); 2420 EXPECT_FALSE( 2421 sandboxir::ShuffleVectorInst::isSelectMask(I->getShuffleMask(), 2)); 2422 } 2423 2424 // isReverse / isReverseMask 2425 { 2426 auto *I = CreateShuffleWithMask(1, 0); 2427 EXPECT_TRUE(I->isReverse()); 2428 EXPECT_TRUE(sandboxir::ShuffleVectorInst::isReverseMask( 2429 I->getShuffleMaskForBitcode(), 2)); 2430 EXPECT_TRUE( 2431 sandboxir::ShuffleVectorInst::isReverseMask(I->getShuffleMask(), 2)); 2432 } 2433 { 2434 auto *I = CreateShuffleWithMask(1, 2); 2435 EXPECT_FALSE(I->isReverse()); 2436 EXPECT_FALSE(sandboxir::ShuffleVectorInst::isReverseMask( 2437 I->getShuffleMaskForBitcode(), 2)); 2438 EXPECT_FALSE( 2439 sandboxir::ShuffleVectorInst::isReverseMask(I->getShuffleMask(), 2)); 2440 } 2441 2442 // isZeroEltSplat / isZeroEltSplatMask 2443 { 2444 auto *I = CreateShuffleWithMask(0, 0); 2445 EXPECT_TRUE(I->isZeroEltSplat()); 2446 EXPECT_TRUE(sandboxir::ShuffleVectorInst::isZeroEltSplatMask( 2447 I->getShuffleMaskForBitcode(), 2)); 2448 EXPECT_TRUE(sandboxir::ShuffleVectorInst::isZeroEltSplatMask( 2449 I->getShuffleMask(), 2)); 2450 } 2451 { 2452 auto *I = CreateShuffleWithMask(1, 1); 2453 EXPECT_FALSE(I->isZeroEltSplat()); 2454 EXPECT_FALSE(sandboxir::ShuffleVectorInst::isZeroEltSplatMask( 2455 I->getShuffleMaskForBitcode(), 2)); 2456 EXPECT_FALSE(sandboxir::ShuffleVectorInst::isZeroEltSplatMask( 2457 I->getShuffleMask(), 2)); 2458 } 2459 2460 // isTranspose / isTransposeMask 2461 { 2462 auto *I = CreateShuffleWithMask(0, 2); 2463 EXPECT_TRUE(I->isTranspose()); 2464 EXPECT_TRUE(sandboxir::ShuffleVectorInst::isTransposeMask( 2465 I->getShuffleMaskForBitcode(), 2)); 2466 EXPECT_TRUE( 2467 sandboxir::ShuffleVectorInst::isTransposeMask(I->getShuffleMask(), 2)); 2468 } 2469 { 2470 auto *I = CreateShuffleWithMask(1, 1); 2471 EXPECT_FALSE(I->isTranspose()); 2472 EXPECT_FALSE(sandboxir::ShuffleVectorInst::isTransposeMask( 2473 I->getShuffleMaskForBitcode(), 2)); 2474 EXPECT_FALSE( 2475 sandboxir::ShuffleVectorInst::isTransposeMask(I->getShuffleMask(), 2)); 2476 } 2477 2478 // isSplice / isSpliceMask 2479 { 2480 auto *I = CreateShuffleWithMask(1, 2); 2481 int Index; 2482 EXPECT_TRUE(I->isSplice(Index)); 2483 EXPECT_EQ(Index, 1); 2484 EXPECT_TRUE(sandboxir::ShuffleVectorInst::isSpliceMask( 2485 I->getShuffleMaskForBitcode(), 2, Index)); 2486 EXPECT_TRUE(sandboxir::ShuffleVectorInst::isSpliceMask(I->getShuffleMask(), 2487 2, Index)); 2488 } 2489 { 2490 auto *I = CreateShuffleWithMask(2, 1); 2491 int Index; 2492 EXPECT_FALSE(I->isSplice(Index)); 2493 EXPECT_FALSE(sandboxir::ShuffleVectorInst::isSpliceMask( 2494 I->getShuffleMaskForBitcode(), 2, Index)); 2495 EXPECT_FALSE(sandboxir::ShuffleVectorInst::isSpliceMask(I->getShuffleMask(), 2496 2, Index)); 2497 } 2498 2499 // isExtractSubvectorMask 2500 { 2501 auto *I = CreateShuffleWithMask(1); 2502 int Index; 2503 EXPECT_TRUE(I->isExtractSubvectorMask(Index)); 2504 EXPECT_EQ(Index, 1); 2505 EXPECT_TRUE(sandboxir::ShuffleVectorInst::isExtractSubvectorMask( 2506 I->getShuffleMaskForBitcode(), 2, Index)); 2507 EXPECT_TRUE(sandboxir::ShuffleVectorInst::isExtractSubvectorMask( 2508 I->getShuffleMask(), 2, Index)); 2509 } 2510 { 2511 auto *I = CreateShuffleWithMask(1, 2); 2512 int Index; 2513 EXPECT_FALSE(I->isExtractSubvectorMask(Index)); 2514 EXPECT_FALSE(sandboxir::ShuffleVectorInst::isExtractSubvectorMask( 2515 I->getShuffleMaskForBitcode(), 2, Index)); 2516 EXPECT_FALSE(sandboxir::ShuffleVectorInst::isExtractSubvectorMask( 2517 I->getShuffleMask(), 2, Index)); 2518 } 2519 2520 // isInsertSubvectorMask 2521 { 2522 auto *I = CreateShuffleWithMask(0, 2); 2523 int NumSubElts, Index; 2524 EXPECT_TRUE(I->isInsertSubvectorMask(NumSubElts, Index)); 2525 EXPECT_EQ(Index, 1); 2526 EXPECT_EQ(NumSubElts, 1); 2527 EXPECT_TRUE(sandboxir::ShuffleVectorInst::isInsertSubvectorMask( 2528 I->getShuffleMaskForBitcode(), 2, NumSubElts, Index)); 2529 EXPECT_TRUE(sandboxir::ShuffleVectorInst::isInsertSubvectorMask( 2530 I->getShuffleMask(), 2, NumSubElts, Index)); 2531 } 2532 { 2533 auto *I = CreateShuffleWithMask(0, 1); 2534 int NumSubElts, Index; 2535 EXPECT_FALSE(I->isInsertSubvectorMask(NumSubElts, Index)); 2536 EXPECT_FALSE(sandboxir::ShuffleVectorInst::isInsertSubvectorMask( 2537 I->getShuffleMaskForBitcode(), 2, NumSubElts, Index)); 2538 EXPECT_FALSE(sandboxir::ShuffleVectorInst::isInsertSubvectorMask( 2539 I->getShuffleMask(), 2, NumSubElts, Index)); 2540 } 2541 2542 // isReplicationMask 2543 { 2544 auto *I = CreateShuffleWithMask(0, 0, 0, 1, 1, 1); 2545 int ReplicationFactor, VF; 2546 EXPECT_TRUE(I->isReplicationMask(ReplicationFactor, VF)); 2547 EXPECT_EQ(ReplicationFactor, 3); 2548 EXPECT_EQ(VF, 2); 2549 EXPECT_TRUE(sandboxir::ShuffleVectorInst::isReplicationMask( 2550 I->getShuffleMaskForBitcode(), ReplicationFactor, VF)); 2551 EXPECT_TRUE(sandboxir::ShuffleVectorInst::isReplicationMask( 2552 I->getShuffleMask(), ReplicationFactor, VF)); 2553 } 2554 { 2555 auto *I = CreateShuffleWithMask(1, 2); 2556 int ReplicationFactor, VF; 2557 EXPECT_FALSE(I->isReplicationMask(ReplicationFactor, VF)); 2558 EXPECT_FALSE(sandboxir::ShuffleVectorInst::isReplicationMask( 2559 I->getShuffleMaskForBitcode(), ReplicationFactor, VF)); 2560 EXPECT_FALSE(sandboxir::ShuffleVectorInst::isReplicationMask( 2561 I->getShuffleMask(), ReplicationFactor, VF)); 2562 } 2563 2564 // isOneUseSingleSourceMask 2565 { 2566 auto *I = CreateShuffleWithMask(0, 1, 1, 0); 2567 EXPECT_TRUE(I->isOneUseSingleSourceMask(2)); 2568 EXPECT_TRUE(sandboxir::ShuffleVectorInst::isOneUseSingleSourceMask( 2569 I->getShuffleMask(), 2)); 2570 } 2571 { 2572 auto *I = CreateShuffleWithMask(0, 1, 0, 0); 2573 EXPECT_FALSE(I->isOneUseSingleSourceMask(2)); 2574 EXPECT_FALSE(sandboxir::ShuffleVectorInst::isOneUseSingleSourceMask( 2575 I->getShuffleMask(), 2)); 2576 } 2577 2578 // commuteShuffleMask 2579 { 2580 SmallVector<int, 4> M = {0, 2, 1, 3}; 2581 ShuffleVectorInst::commuteShuffleMask(M, 2); 2582 EXPECT_THAT(M, testing::ElementsAre(2, 0, 3, 1)); 2583 } 2584 2585 // isInterleave / isInterleaveMask 2586 { 2587 auto *I = CreateShuffleWithMask(0, 2, 1, 3); 2588 EXPECT_TRUE(I->isInterleave(2)); 2589 EXPECT_TRUE(sandboxir::ShuffleVectorInst::isInterleaveMask( 2590 I->getShuffleMask(), 2, 4)); 2591 SmallVector<unsigned, 4> StartIndexes; 2592 EXPECT_TRUE(sandboxir::ShuffleVectorInst::isInterleaveMask( 2593 I->getShuffleMask(), 2, 4, StartIndexes)); 2594 EXPECT_THAT(StartIndexes, testing::ElementsAre(0, 2)); 2595 } 2596 { 2597 auto *I = CreateShuffleWithMask(0, 3, 1, 2); 2598 EXPECT_FALSE(I->isInterleave(2)); 2599 EXPECT_FALSE(sandboxir::ShuffleVectorInst::isInterleaveMask( 2600 I->getShuffleMask(), 2, 4)); 2601 } 2602 2603 // isDeInterleaveMaskOfFactor 2604 { 2605 EXPECT_TRUE(sandboxir::ShuffleVectorInst::isDeInterleaveMaskOfFactor( 2606 ArrayRef<int>({0, 2}), 2)); 2607 EXPECT_FALSE(sandboxir::ShuffleVectorInst::isDeInterleaveMaskOfFactor( 2608 ArrayRef<int>({0, 1}), 2)); 2609 2610 unsigned Index; 2611 EXPECT_TRUE(sandboxir::ShuffleVectorInst::isDeInterleaveMaskOfFactor( 2612 ArrayRef<int>({1, 3}), 2, Index)); 2613 EXPECT_EQ(Index, 1u); 2614 } 2615 2616 // isBitRotateMask 2617 { 2618 unsigned NumSubElts, RotateAmt; 2619 EXPECT_TRUE(sandboxir::ShuffleVectorInst::isBitRotateMask( 2620 ArrayRef<int>({1, 0, 3, 2, 5, 4, 7, 6}), 8, 2, 2, NumSubElts, 2621 RotateAmt)); 2622 EXPECT_EQ(NumSubElts, 2u); 2623 EXPECT_EQ(RotateAmt, 8u); 2624 2625 EXPECT_FALSE(sandboxir::ShuffleVectorInst::isBitRotateMask( 2626 ArrayRef<int>({0, 7, 1, 6, 2, 5, 3, 4}), 8, 2, 2, NumSubElts, 2627 RotateAmt)); 2628 } 2629 } 2630 2631 TEST_F(SandboxIRTest, ExtractValueInst) { 2632 parseIR(C, R"IR( 2633 define void @foo({i32, float} %agg) { 2634 %ext_simple = extractvalue {i32, float} %agg, 0 2635 %ext_nested = extractvalue {float, {i32}} undef, 1, 0 2636 %const1 = extractvalue {i32, float} {i32 0, float 99.0}, 0 2637 ret void 2638 } 2639 )IR"); 2640 Function &LLVMF = *M->getFunction("foo"); 2641 auto *LLVMBB = &*LLVMF.begin(); 2642 auto LLVMIt = LLVMBB->begin(); 2643 [[maybe_unused]] auto *LLVMExtSimple = 2644 cast<llvm::ExtractValueInst>(&*LLVMIt++); 2645 auto *LLVMExtNested = cast<llvm::ExtractValueInst>(&*LLVMIt++); 2646 2647 sandboxir::Context Ctx(C); 2648 auto &F = *Ctx.createFunction(&LLVMF); 2649 auto *ArgAgg = F.getArg(0); 2650 auto *BB = &*F.begin(); 2651 auto It = BB->begin(); 2652 auto *ExtSimple = cast<sandboxir::ExtractValueInst>(&*It++); 2653 auto *ExtNested = cast<sandboxir::ExtractValueInst>(&*It++); 2654 auto *Const1 = cast<sandboxir::ExtractValueInst>(&*It++); 2655 auto *Ret = &*It++; 2656 2657 EXPECT_EQ(ExtSimple->getOperand(0), ArgAgg); 2658 2659 // create before instruction 2660 auto *NewExtBeforeRet = 2661 cast<sandboxir::ExtractValueInst>(sandboxir::ExtractValueInst::create( 2662 ArgAgg, ArrayRef<unsigned>({0}), Ret->getIterator(), Ctx, 2663 "NewExtBeforeRet")); 2664 EXPECT_EQ(NewExtBeforeRet->getNextNode(), Ret); 2665 #ifndef NDEBUG 2666 EXPECT_EQ(NewExtBeforeRet->getName(), "NewExtBeforeRet"); 2667 #endif // NDEBUG 2668 2669 // create at end of BB 2670 auto *NewExtAtEnd = 2671 cast<sandboxir::ExtractValueInst>(sandboxir::ExtractValueInst::create( 2672 ArgAgg, ArrayRef<unsigned>({0}), BB->end(), Ctx, "NewExtAtEnd")); 2673 EXPECT_EQ(NewExtAtEnd->getPrevNode(), Ret); 2674 #ifndef NDEBUG 2675 EXPECT_EQ(NewExtAtEnd->getName(), "NewExtAtEnd"); 2676 #endif // NDEBUG 2677 2678 // Test the path that creates a folded constant. 2679 auto *ShouldBeConstant = sandboxir::ExtractValueInst::create( 2680 Const1->getOperand(0), ArrayRef<unsigned>({0}), BB->end(), Ctx); 2681 EXPECT_TRUE(isa<sandboxir::Constant>(ShouldBeConstant)); 2682 2683 auto *Zero = sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 0); 2684 EXPECT_EQ(ShouldBeConstant, Zero); 2685 2686 // getIndexedType 2687 sandboxir::Type *AggType = ExtNested->getAggregateOperand()->getType(); 2688 llvm::Type *LLVMAggType = LLVMExtNested->getAggregateOperand()->getType(); 2689 EXPECT_EQ(sandboxir::ExtractValueInst::getIndexedType( 2690 AggType, ArrayRef<unsigned>({1, 0})), 2691 Ctx.getType(llvm::ExtractValueInst::getIndexedType( 2692 LLVMAggType, ArrayRef<unsigned>({1, 0})))); 2693 2694 EXPECT_EQ(sandboxir::ExtractValueInst::getIndexedType( 2695 AggType, ArrayRef<unsigned>({2})), 2696 nullptr); 2697 2698 // idx_begin / idx_end 2699 { 2700 SmallVector<int, 2> IndicesSimple(ExtSimple->idx_begin(), 2701 ExtSimple->idx_end()); 2702 EXPECT_THAT(IndicesSimple, testing::ElementsAre(0u)); 2703 2704 SmallVector<int, 2> IndicesNested(ExtNested->idx_begin(), 2705 ExtNested->idx_end()); 2706 EXPECT_THAT(IndicesNested, testing::ElementsAre(1u, 0u)); 2707 } 2708 2709 // indices 2710 { 2711 SmallVector<int, 2> IndicesSimple(ExtSimple->indices()); 2712 EXPECT_THAT(IndicesSimple, testing::ElementsAre(0u)); 2713 2714 SmallVector<int, 2> IndicesNested(ExtNested->indices()); 2715 EXPECT_THAT(IndicesNested, testing::ElementsAre(1u, 0u)); 2716 } 2717 2718 // getAggregateOperand 2719 EXPECT_EQ(ExtSimple->getAggregateOperand(), ArgAgg); 2720 const auto *ConstExtSimple = ExtSimple; 2721 EXPECT_EQ(ConstExtSimple->getAggregateOperand(), ArgAgg); 2722 2723 // getAggregateOperandIndex 2724 EXPECT_EQ(sandboxir::ExtractValueInst::getAggregateOperandIndex(), 2725 llvm::ExtractValueInst::getAggregateOperandIndex()); 2726 2727 // getIndices 2728 EXPECT_EQ(ExtSimple->getIndices().size(), 1u); 2729 EXPECT_EQ(ExtSimple->getIndices()[0], 0u); 2730 2731 // getNumIndices 2732 EXPECT_EQ(ExtSimple->getNumIndices(), 1u); 2733 2734 // hasIndices 2735 EXPECT_EQ(ExtSimple->hasIndices(), true); 2736 } 2737 2738 TEST_F(SandboxIRTest, InsertValueInst) { 2739 parseIR(C, R"IR( 2740 define void @foo({i32, float} %agg, i32 %i) { 2741 %ins_simple = insertvalue {i32, float} %agg, i32 %i, 0 2742 %ins_nested = insertvalue {float, {i32}} undef, i32 %i, 1, 0 2743 %const1 = insertvalue {i32, float} {i32 99, float 99.0}, i32 %i, 0 2744 %const2 = insertvalue {i32, float} {i32 0, float 99.0}, i32 %i, 0 2745 ret void 2746 } 2747 )IR"); 2748 Function &LLVMF = *M->getFunction("foo"); 2749 sandboxir::Context Ctx(C); 2750 auto &F = *Ctx.createFunction(&LLVMF); 2751 auto *ArgAgg = F.getArg(0); 2752 auto *ArgInt = F.getArg(1); 2753 auto *BB = &*F.begin(); 2754 auto It = BB->begin(); 2755 auto *InsSimple = cast<sandboxir::InsertValueInst>(&*It++); 2756 auto *InsNested = cast<sandboxir::InsertValueInst>(&*It++); 2757 // These "const" instructions are helpers to create constant struct operands. 2758 // TODO: Remove them once sandboxir::ConstantStruct gets added. 2759 auto *Const1 = cast<sandboxir::InsertValueInst>(&*It++); 2760 auto *Const2 = cast<sandboxir::InsertValueInst>(&*It++); 2761 auto *Ret = &*It++; 2762 2763 EXPECT_EQ(InsSimple->getOperand(0), ArgAgg); 2764 EXPECT_EQ(InsSimple->getOperand(1), ArgInt); 2765 2766 // create before instruction 2767 auto *NewInsBeforeRet = 2768 cast<sandboxir::InsertValueInst>(sandboxir::InsertValueInst::create( 2769 ArgAgg, ArgInt, ArrayRef<unsigned>({0}), Ret->getIterator(), Ctx, 2770 "NewInsBeforeRet")); 2771 EXPECT_EQ(NewInsBeforeRet->getNextNode(), Ret); 2772 #ifndef NDEBUG 2773 EXPECT_EQ(NewInsBeforeRet->getName(), "NewInsBeforeRet"); 2774 #endif // NDEBUG 2775 2776 // create at end of BB 2777 auto *NewInsAtEnd = 2778 cast<sandboxir::InsertValueInst>(sandboxir::InsertValueInst::create( 2779 ArgAgg, ArgInt, ArrayRef<unsigned>({0}), BB, Ctx, "NewInsAtEnd")); 2780 EXPECT_EQ(NewInsAtEnd->getPrevNode(), Ret); 2781 #ifndef NDEBUG 2782 EXPECT_EQ(NewInsAtEnd->getName(), "NewInsAtEnd"); 2783 #endif // NDEBUG 2784 2785 // Test the path that creates a folded constant. 2786 auto *Zero = sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 0); 2787 auto *ShouldBeConstant = sandboxir::InsertValueInst::create( 2788 Const1->getOperand(0), Zero, ArrayRef<unsigned>({0}), BB, Ctx); 2789 auto *ExpectedConstant = Const2->getOperand(0); 2790 EXPECT_TRUE(isa<sandboxir::Constant>(ShouldBeConstant)); 2791 EXPECT_EQ(ShouldBeConstant, ExpectedConstant); 2792 2793 // idx_begin / idx_end 2794 { 2795 SmallVector<int, 2> IndicesSimple(InsSimple->idx_begin(), 2796 InsSimple->idx_end()); 2797 EXPECT_THAT(IndicesSimple, testing::ElementsAre(0u)); 2798 2799 SmallVector<int, 2> IndicesNested(InsNested->idx_begin(), 2800 InsNested->idx_end()); 2801 EXPECT_THAT(IndicesNested, testing::ElementsAre(1u, 0u)); 2802 } 2803 2804 // indices 2805 { 2806 SmallVector<int, 2> IndicesSimple(InsSimple->indices()); 2807 EXPECT_THAT(IndicesSimple, testing::ElementsAre(0u)); 2808 2809 SmallVector<int, 2> IndicesNested(InsNested->indices()); 2810 EXPECT_THAT(IndicesNested, testing::ElementsAre(1u, 0u)); 2811 } 2812 2813 // getAggregateOperand 2814 EXPECT_EQ(InsSimple->getAggregateOperand(), ArgAgg); 2815 const auto *ConstInsSimple = InsSimple; 2816 EXPECT_EQ(ConstInsSimple->getAggregateOperand(), ArgAgg); 2817 2818 // getAggregateOperandIndex 2819 EXPECT_EQ(sandboxir::InsertValueInst::getAggregateOperandIndex(), 2820 llvm::InsertValueInst::getAggregateOperandIndex()); 2821 2822 // getInsertedValueOperand 2823 EXPECT_EQ(InsSimple->getInsertedValueOperand(), ArgInt); 2824 EXPECT_EQ(ConstInsSimple->getInsertedValueOperand(), ArgInt); 2825 2826 // getInsertedValueOperandIndex 2827 EXPECT_EQ(sandboxir::InsertValueInst::getInsertedValueOperandIndex(), 2828 llvm::InsertValueInst::getInsertedValueOperandIndex()); 2829 2830 // getIndices 2831 EXPECT_EQ(InsSimple->getIndices().size(), 1u); 2832 EXPECT_EQ(InsSimple->getIndices()[0], 0u); 2833 2834 // getNumIndices 2835 EXPECT_EQ(InsSimple->getNumIndices(), 1u); 2836 2837 // hasIndices 2838 EXPECT_EQ(InsSimple->hasIndices(), true); 2839 } 2840 2841 TEST_F(SandboxIRTest, BranchInst) { 2842 parseIR(C, R"IR( 2843 define void @foo(i1 %cond0, i1 %cond2) { 2844 bb0: 2845 br i1 %cond0, label %bb1, label %bb2 2846 bb1: 2847 ret void 2848 bb2: 2849 ret void 2850 } 2851 )IR"); 2852 llvm::Function *LLVMF = &*M->getFunction("foo"); 2853 sandboxir::Context Ctx(C); 2854 sandboxir::Function *F = Ctx.createFunction(LLVMF); 2855 auto *Cond0 = F->getArg(0); 2856 auto *Cond1 = F->getArg(1); 2857 auto *BB0 = cast<sandboxir::BasicBlock>( 2858 Ctx.getValue(getBasicBlockByName(*LLVMF, "bb0"))); 2859 auto *BB1 = cast<sandboxir::BasicBlock>( 2860 Ctx.getValue(getBasicBlockByName(*LLVMF, "bb1"))); 2861 auto *Ret1 = BB1->getTerminator(); 2862 auto *BB2 = cast<sandboxir::BasicBlock>( 2863 Ctx.getValue(getBasicBlockByName(*LLVMF, "bb2"))); 2864 auto *Ret2 = BB2->getTerminator(); 2865 auto It = BB0->begin(); 2866 auto *Br0 = cast<sandboxir::BranchInst>(&*It++); 2867 // Check isUnconditional(). 2868 EXPECT_FALSE(Br0->isUnconditional()); 2869 // Check isConditional(). 2870 EXPECT_TRUE(Br0->isConditional()); 2871 // Check getCondition(). 2872 EXPECT_EQ(Br0->getCondition(), Cond0); 2873 // Check setCondition(). 2874 Br0->setCondition(Cond1); 2875 EXPECT_EQ(Br0->getCondition(), Cond1); 2876 // Check getNumSuccessors(). 2877 EXPECT_EQ(Br0->getNumSuccessors(), 2u); 2878 // Check getSuccessor(). 2879 EXPECT_EQ(Br0->getSuccessor(0), BB1); 2880 EXPECT_EQ(Br0->getSuccessor(1), BB2); 2881 // Check swapSuccessors(). 2882 Br0->swapSuccessors(); 2883 EXPECT_EQ(Br0->getSuccessor(0), BB2); 2884 EXPECT_EQ(Br0->getSuccessor(1), BB1); 2885 // Check successors(). 2886 EXPECT_EQ(range_size(Br0->successors()), 2u); 2887 unsigned SuccIdx = 0; 2888 SmallVector<sandboxir::BasicBlock *> ExpectedSuccs({BB1, BB2}); 2889 for (sandboxir::BasicBlock *Succ : Br0->successors()) 2890 EXPECT_EQ(Succ, ExpectedSuccs[SuccIdx++]); 2891 2892 { 2893 // Check unconditional BranchInst::create() InsertBefore. 2894 auto *Br = sandboxir::BranchInst::create(BB1, Ret1->getIterator(), Ctx); 2895 EXPECT_FALSE(Br->isConditional()); 2896 EXPECT_TRUE(Br->isUnconditional()); 2897 #ifndef NDEBUG 2898 EXPECT_DEATH(Br->getCondition(), ".*condition.*"); 2899 #endif // NDEBUG 2900 unsigned SuccIdx = 0; 2901 SmallVector<sandboxir::BasicBlock *> ExpectedSuccs({BB1}); 2902 for (sandboxir::BasicBlock *Succ : Br->successors()) 2903 EXPECT_EQ(Succ, ExpectedSuccs[SuccIdx++]); 2904 EXPECT_EQ(Br->getNextNode(), Ret1); 2905 } 2906 { 2907 // Check unconditional BranchInst::create() InsertAtEnd. 2908 auto *Br = sandboxir::BranchInst::create(BB1, /*InsertAtEnd=*/BB1, Ctx); 2909 EXPECT_FALSE(Br->isConditional()); 2910 EXPECT_TRUE(Br->isUnconditional()); 2911 #ifndef NDEBUG 2912 EXPECT_DEATH(Br->getCondition(), ".*condition.*"); 2913 #endif // NDEBUG 2914 unsigned SuccIdx = 0; 2915 SmallVector<sandboxir::BasicBlock *> ExpectedSuccs({BB1}); 2916 for (sandboxir::BasicBlock *Succ : Br->successors()) 2917 EXPECT_EQ(Succ, ExpectedSuccs[SuccIdx++]); 2918 EXPECT_EQ(Br->getPrevNode(), Ret1); 2919 } 2920 { 2921 // Check conditional BranchInst::create() InsertBefore. 2922 auto *Br = sandboxir::BranchInst::create(BB1, BB2, Cond0, 2923 Ret1->getIterator(), Ctx); 2924 EXPECT_TRUE(Br->isConditional()); 2925 EXPECT_EQ(Br->getCondition(), Cond0); 2926 unsigned SuccIdx = 0; 2927 SmallVector<sandboxir::BasicBlock *> ExpectedSuccs({BB2, BB1}); 2928 for (sandboxir::BasicBlock *Succ : Br->successors()) 2929 EXPECT_EQ(Succ, ExpectedSuccs[SuccIdx++]); 2930 EXPECT_EQ(Br->getNextNode(), Ret1); 2931 } 2932 { 2933 // Check conditional BranchInst::create() InsertAtEnd. 2934 auto *Br = sandboxir::BranchInst::create(BB1, BB2, Cond0, 2935 /*InsertAtEnd=*/BB2, Ctx); 2936 EXPECT_TRUE(Br->isConditional()); 2937 EXPECT_EQ(Br->getCondition(), Cond0); 2938 unsigned SuccIdx = 0; 2939 SmallVector<sandboxir::BasicBlock *> ExpectedSuccs({BB2, BB1}); 2940 for (sandboxir::BasicBlock *Succ : Br->successors()) 2941 EXPECT_EQ(Succ, ExpectedSuccs[SuccIdx++]); 2942 EXPECT_EQ(Br->getPrevNode(), Ret2); 2943 } 2944 } 2945 2946 TEST_F(SandboxIRTest, LoadInst) { 2947 parseIR(C, R"IR( 2948 define void @foo(ptr %arg0, ptr %arg1) { 2949 %ld = load i8, ptr %arg0, align 64 2950 %vld = load volatile i8, ptr %arg0, align 64 2951 ret void 2952 } 2953 )IR"); 2954 llvm::Function *LLVMF = &*M->getFunction("foo"); 2955 sandboxir::Context Ctx(C); 2956 sandboxir::Function *F = Ctx.createFunction(LLVMF); 2957 auto *Arg0 = F->getArg(0); 2958 auto *Arg1 = F->getArg(1); 2959 auto *BB = &*F->begin(); 2960 auto It = BB->begin(); 2961 auto *Ld = cast<sandboxir::LoadInst>(&*It++); 2962 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(Ld)); 2963 auto *VLd = cast<sandboxir::LoadInst>(&*It++); 2964 auto *Ret = cast<sandboxir::ReturnInst>(&*It++); 2965 bool OrigVolatileValue; 2966 2967 // Check isVolatile() 2968 EXPECT_FALSE(Ld->isVolatile()); 2969 // Check isVolatile() 2970 EXPECT_TRUE(VLd->isVolatile()); 2971 // Check getPointerOperand() 2972 EXPECT_EQ(Ld->getPointerOperand(), Arg0); 2973 // Check getAlign() 2974 EXPECT_EQ(Ld->getAlign(), 64); 2975 // Check create(InsertBefore) 2976 sandboxir::LoadInst *NewLd = sandboxir::LoadInst::create( 2977 Ld->getType(), Arg1, Align(8), Ret->getIterator(), Ctx, "NewLd"); 2978 EXPECT_FALSE(NewLd->isVolatile()); 2979 OrigVolatileValue = NewLd->isVolatile(); 2980 NewLd->setVolatile(true); 2981 EXPECT_TRUE(NewLd->isVolatile()); 2982 NewLd->setVolatile(OrigVolatileValue); 2983 EXPECT_FALSE(NewLd->isVolatile()); 2984 EXPECT_EQ(NewLd->getType(), Ld->getType()); 2985 EXPECT_EQ(NewLd->getPointerOperand(), Arg1); 2986 EXPECT_EQ(NewLd->getAlign(), 8); 2987 EXPECT_EQ(NewLd->getName(), "NewLd"); 2988 // Check create(InsertBefore, IsVolatile=true) 2989 sandboxir::LoadInst *NewVLd = sandboxir::LoadInst::create( 2990 VLd->getType(), Arg1, Align(8), Ret->getIterator(), 2991 /*IsVolatile=*/true, Ctx, "NewVLd"); 2992 2993 EXPECT_TRUE(NewVLd->isVolatile()); 2994 OrigVolatileValue = NewVLd->isVolatile(); 2995 NewVLd->setVolatile(false); 2996 EXPECT_FALSE(NewVLd->isVolatile()); 2997 NewVLd->setVolatile(OrigVolatileValue); 2998 EXPECT_TRUE(NewVLd->isVolatile()); 2999 EXPECT_EQ(NewVLd->getName(), "NewVLd"); 3000 // Check create(InsertAtEnd) 3001 sandboxir::LoadInst *NewLdEnd = 3002 sandboxir::LoadInst::create(Ld->getType(), Arg1, Align(8), 3003 /*InsertAtEnd=*/BB, Ctx, "NewLdEnd"); 3004 EXPECT_FALSE(NewLdEnd->isVolatile()); 3005 EXPECT_EQ(NewLdEnd->getName(), "NewLdEnd"); 3006 EXPECT_EQ(NewLdEnd->getType(), Ld->getType()); 3007 EXPECT_EQ(NewLdEnd->getPointerOperand(), Arg1); 3008 EXPECT_EQ(NewLdEnd->getAlign(), 8); 3009 EXPECT_EQ(NewLdEnd->getParent(), BB); 3010 EXPECT_EQ(NewLdEnd->getNextNode(), nullptr); 3011 // Check create(InsertAtEnd, IsVolatile=true) 3012 sandboxir::LoadInst *NewVLdEnd = 3013 sandboxir::LoadInst::create(VLd->getType(), Arg1, Align(8), 3014 /*InsertAtEnd=*/BB, 3015 /*IsVolatile=*/true, Ctx, "NewVLdEnd"); 3016 EXPECT_TRUE(NewVLdEnd->isVolatile()); 3017 EXPECT_EQ(NewVLdEnd->getName(), "NewVLdEnd"); 3018 EXPECT_EQ(NewVLdEnd->getType(), VLd->getType()); 3019 EXPECT_EQ(NewVLdEnd->getPointerOperand(), Arg1); 3020 EXPECT_EQ(NewVLdEnd->getAlign(), 8); 3021 EXPECT_EQ(NewVLdEnd->getParent(), BB); 3022 EXPECT_EQ(NewVLdEnd->getNextNode(), nullptr); 3023 } 3024 3025 TEST_F(SandboxIRTest, StoreInst) { 3026 parseIR(C, R"IR( 3027 define void @foo(i8 %val, ptr %ptr) { 3028 store i8 %val, ptr %ptr, align 64 3029 store volatile i8 %val, ptr %ptr, align 64 3030 ret void 3031 } 3032 )IR"); 3033 llvm::Function *LLVMF = &*M->getFunction("foo"); 3034 sandboxir::Context Ctx(C); 3035 sandboxir::Function *F = Ctx.createFunction(LLVMF); 3036 auto *Val = F->getArg(0); 3037 auto *Ptr = F->getArg(1); 3038 auto *BB = &*F->begin(); 3039 auto It = BB->begin(); 3040 auto *St = cast<sandboxir::StoreInst>(&*It++); 3041 auto *VSt = cast<sandboxir::StoreInst>(&*It++); 3042 auto *Ret = cast<sandboxir::ReturnInst>(&*It++); 3043 bool OrigVolatileValue; 3044 3045 // Check that the StoreInst has been created correctly. 3046 EXPECT_FALSE(St->isVolatile()); 3047 EXPECT_TRUE(VSt->isVolatile()); 3048 // Check getPointerOperand() 3049 EXPECT_EQ(St->getValueOperand(), Val); 3050 EXPECT_EQ(St->getPointerOperand(), Ptr); 3051 // Check getAlign() 3052 EXPECT_EQ(St->getAlign(), 64); 3053 // Check create(InsertBefore) 3054 sandboxir::StoreInst *NewSt = 3055 sandboxir::StoreInst::create(Val, Ptr, Align(8), Ret->getIterator(), Ctx); 3056 EXPECT_FALSE(NewSt->isVolatile()); 3057 OrigVolatileValue = NewSt->isVolatile(); 3058 NewSt->setVolatile(true); 3059 EXPECT_TRUE(NewSt->isVolatile()); 3060 NewSt->setVolatile(OrigVolatileValue); 3061 EXPECT_FALSE(NewSt->isVolatile()); 3062 EXPECT_EQ(NewSt->getType(), St->getType()); 3063 EXPECT_EQ(NewSt->getValueOperand(), Val); 3064 EXPECT_EQ(NewSt->getPointerOperand(), Ptr); 3065 EXPECT_EQ(NewSt->getAlign(), 8); 3066 EXPECT_EQ(NewSt->getNextNode(), Ret); 3067 // Check create(InsertBefore, IsVolatile=true) 3068 sandboxir::StoreInst *NewVSt = 3069 sandboxir::StoreInst::create(Val, Ptr, Align(8), Ret->getIterator(), 3070 /*IsVolatile=*/true, Ctx); 3071 EXPECT_TRUE(NewVSt->isVolatile()); 3072 OrigVolatileValue = NewVSt->isVolatile(); 3073 NewVSt->setVolatile(false); 3074 EXPECT_FALSE(NewVSt->isVolatile()); 3075 NewVSt->setVolatile(OrigVolatileValue); 3076 EXPECT_TRUE(NewVSt->isVolatile()); 3077 EXPECT_EQ(NewVSt->getType(), VSt->getType()); 3078 EXPECT_EQ(NewVSt->getValueOperand(), Val); 3079 EXPECT_EQ(NewVSt->getPointerOperand(), Ptr); 3080 EXPECT_EQ(NewVSt->getAlign(), 8); 3081 EXPECT_EQ(NewVSt->getNextNode(), Ret); 3082 // Check create(InsertAtEnd) 3083 sandboxir::StoreInst *NewStEnd = 3084 sandboxir::StoreInst::create(Val, Ptr, Align(8), 3085 /*InsertAtEnd=*/BB, Ctx); 3086 EXPECT_FALSE(NewStEnd->isVolatile()); 3087 EXPECT_EQ(NewStEnd->getType(), St->getType()); 3088 EXPECT_EQ(NewStEnd->getValueOperand(), Val); 3089 EXPECT_EQ(NewStEnd->getPointerOperand(), Ptr); 3090 EXPECT_EQ(NewStEnd->getAlign(), 8); 3091 EXPECT_EQ(NewStEnd->getParent(), BB); 3092 EXPECT_EQ(NewStEnd->getNextNode(), nullptr); 3093 // Check create(InsertAtEnd, IsVolatile=true) 3094 sandboxir::StoreInst *NewVStEnd = 3095 sandboxir::StoreInst::create(Val, Ptr, Align(8), 3096 /*InsertAtEnd=*/BB, 3097 /*IsVolatile=*/true, Ctx); 3098 EXPECT_TRUE(NewVStEnd->isVolatile()); 3099 EXPECT_EQ(NewVStEnd->getType(), VSt->getType()); 3100 EXPECT_EQ(NewVStEnd->getValueOperand(), Val); 3101 EXPECT_EQ(NewVStEnd->getPointerOperand(), Ptr); 3102 EXPECT_EQ(NewVStEnd->getAlign(), 8); 3103 EXPECT_EQ(NewVStEnd->getParent(), BB); 3104 EXPECT_EQ(NewVStEnd->getNextNode(), nullptr); 3105 } 3106 3107 TEST_F(SandboxIRTest, ReturnInst) { 3108 parseIR(C, R"IR( 3109 define i8 @foo(i8 %val) { 3110 %add = add i8 %val, 42 3111 ret i8 %val 3112 } 3113 )IR"); 3114 llvm::Function *LLVMF = &*M->getFunction("foo"); 3115 sandboxir::Context Ctx(C); 3116 sandboxir::Function *F = Ctx.createFunction(LLVMF); 3117 auto *Val = F->getArg(0); 3118 auto *BB = &*F->begin(); 3119 auto It = BB->begin(); 3120 It++; 3121 auto *Ret = cast<sandboxir::ReturnInst>(&*It++); 3122 3123 // Check that the ReturnInst has been created correctly. 3124 // Check getReturnValue(). 3125 EXPECT_EQ(Ret->getReturnValue(), Val); 3126 3127 // Check create(InsertBefore) a void ReturnInst. 3128 auto *NewRet1 = cast<sandboxir::ReturnInst>( 3129 sandboxir::ReturnInst::create(nullptr, Ret->getIterator(), Ctx)); 3130 EXPECT_EQ(NewRet1->getReturnValue(), nullptr); 3131 // Check create(InsertBefore) a non-void ReturnInst. 3132 auto *NewRet2 = cast<sandboxir::ReturnInst>( 3133 sandboxir::ReturnInst::create(Val, Ret->getIterator(), Ctx)); 3134 EXPECT_EQ(NewRet2->getReturnValue(), Val); 3135 3136 // Check create(InsertAtEnd) a void ReturnInst. 3137 auto *NewRet3 = cast<sandboxir::ReturnInst>( 3138 sandboxir::ReturnInst::create(nullptr, /*InsertAtEnd=*/BB, Ctx)); 3139 EXPECT_EQ(NewRet3->getReturnValue(), nullptr); 3140 // Check create(InsertAtEnd) a non-void ReturnInst. 3141 auto *NewRet4 = cast<sandboxir::ReturnInst>( 3142 sandboxir::ReturnInst::create(Val, /*InsertAtEnd=*/BB, Ctx)); 3143 EXPECT_EQ(NewRet4->getReturnValue(), Val); 3144 } 3145 3146 TEST_F(SandboxIRTest, CallBase) { 3147 parseIR(C, R"IR( 3148 declare void @bar1(i8) 3149 declare void @bar2() 3150 declare void @bar3() 3151 declare void @variadic(ptr, ...) 3152 3153 define i8 @foo(i8 %arg0, i32 %arg1, ptr %indirectFoo) { 3154 %call = call i8 @foo(i8 %arg0, i32 %arg1) 3155 call void @bar1(i8 %arg0) 3156 call void @bar2() 3157 call void %indirectFoo() 3158 call void @bar2() noreturn 3159 tail call fastcc void @bar2() 3160 call void (ptr, ...) @variadic(ptr %indirectFoo, i32 1) 3161 ret i8 %call 3162 } 3163 )IR"); 3164 llvm::Function &LLVMF = *M->getFunction("foo"); 3165 unsigned ArgIdx = 0; 3166 llvm::Argument *LLVMArg0 = LLVMF.getArg(ArgIdx++); 3167 llvm::Argument *LLVMArg1 = LLVMF.getArg(ArgIdx++); 3168 llvm::BasicBlock *LLVMBB = &*LLVMF.begin(); 3169 SmallVector<llvm::CallBase *, 8> LLVMCalls; 3170 auto LLVMIt = LLVMBB->begin(); 3171 while (isa<llvm::CallBase>(&*LLVMIt)) 3172 LLVMCalls.push_back(cast<llvm::CallBase>(&*LLVMIt++)); 3173 3174 sandboxir::Context Ctx(C); 3175 sandboxir::Function &F = *Ctx.createFunction(&LLVMF); 3176 3177 for (llvm::CallBase *LLVMCall : LLVMCalls) { 3178 // Check classof(Instruction *). 3179 auto *Call = cast<sandboxir::CallBase>(Ctx.getValue(LLVMCall)); 3180 // Check classof(Value *). 3181 EXPECT_TRUE(isa<sandboxir::CallBase>((sandboxir::Value *)Call)); 3182 // Check getFunctionType(). 3183 EXPECT_EQ(Call->getFunctionType(), 3184 Ctx.getType(LLVMCall->getFunctionType())); 3185 // Check data_ops(). 3186 EXPECT_EQ(range_size(Call->data_ops()), range_size(LLVMCall->data_ops())); 3187 auto DataOpIt = Call->data_operands_begin(); 3188 for (llvm::Use &LLVMUse : LLVMCall->data_ops()) { 3189 Value *LLVMOp = LLVMUse.get(); 3190 sandboxir::Use Use = *DataOpIt++; 3191 EXPECT_EQ(Ctx.getValue(LLVMOp), Use.get()); 3192 // Check isDataOperand(). 3193 EXPECT_EQ(Call->isDataOperand(Use), LLVMCall->isDataOperand(&LLVMUse)); 3194 // Check getDataOperandNo(). 3195 EXPECT_EQ(Call->getDataOperandNo(Use), 3196 LLVMCall->getDataOperandNo(&LLVMUse)); 3197 // Check isArgOperand(). 3198 EXPECT_EQ(Call->isArgOperand(Use), LLVMCall->isArgOperand(&LLVMUse)); 3199 // Check isCallee(). 3200 EXPECT_EQ(Call->isCallee(Use), LLVMCall->isCallee(&LLVMUse)); 3201 } 3202 // Check data_operands_empty(). 3203 EXPECT_EQ(Call->data_operands_empty(), LLVMCall->data_operands_empty()); 3204 // Check data_operands_size(). 3205 EXPECT_EQ(Call->data_operands_size(), LLVMCall->data_operands_size()); 3206 // Check getNumTotalBundleOperands(). 3207 EXPECT_EQ(Call->getNumTotalBundleOperands(), 3208 LLVMCall->getNumTotalBundleOperands()); 3209 // Check args(). 3210 EXPECT_EQ(range_size(Call->args()), range_size(LLVMCall->args())); 3211 auto ArgIt = Call->arg_begin(); 3212 for (llvm::Use &LLVMUse : LLVMCall->args()) { 3213 Value *LLVMArg = LLVMUse.get(); 3214 sandboxir::Use Use = *ArgIt++; 3215 EXPECT_EQ(Ctx.getValue(LLVMArg), Use.get()); 3216 } 3217 // Check arg_empty(). 3218 EXPECT_EQ(Call->arg_empty(), LLVMCall->arg_empty()); 3219 // Check arg_size(). 3220 EXPECT_EQ(Call->arg_size(), LLVMCall->arg_size()); 3221 for (unsigned ArgIdx = 0, E = Call->arg_size(); ArgIdx != E; ++ArgIdx) { 3222 // Check getArgOperand(). 3223 EXPECT_EQ(Call->getArgOperand(ArgIdx), 3224 Ctx.getValue(LLVMCall->getArgOperand(ArgIdx))); 3225 // Check getArgOperandUse(). 3226 sandboxir::Use Use = Call->getArgOperandUse(ArgIdx); 3227 llvm::Use &LLVMUse = LLVMCall->getArgOperandUse(ArgIdx); 3228 EXPECT_EQ(Use.get(), Ctx.getValue(LLVMUse.get())); 3229 // Check getArgOperandNo(). 3230 EXPECT_EQ(Call->getArgOperandNo(Use), 3231 LLVMCall->getArgOperandNo(&LLVMUse)); 3232 } 3233 // Check hasArgument(). 3234 SmallVector<llvm::Value *> TestArgs( 3235 {LLVMArg0, LLVMArg1, &LLVMF, LLVMBB, LLVMCall}); 3236 for (llvm::Value *LLVMV : TestArgs) { 3237 sandboxir::Value *V = Ctx.getValue(LLVMV); 3238 EXPECT_EQ(Call->hasArgument(V), LLVMCall->hasArgument(LLVMV)); 3239 } 3240 // Check getCalledOperand(). 3241 EXPECT_EQ(Call->getCalledOperand(), 3242 Ctx.getValue(LLVMCall->getCalledOperand())); 3243 // Check getCalledOperandUse(). 3244 EXPECT_EQ(Call->getCalledOperandUse().get(), 3245 Ctx.getValue(LLVMCall->getCalledOperandUse())); 3246 // Check getCalledFunction(). 3247 if (LLVMCall->getCalledFunction() == nullptr) 3248 EXPECT_EQ(Call->getCalledFunction(), nullptr); 3249 else { 3250 auto *LLVMCF = cast<llvm::Function>(LLVMCall->getCalledFunction()); 3251 (void)LLVMCF; 3252 EXPECT_EQ(Call->getCalledFunction(), 3253 cast<sandboxir::Function>( 3254 Ctx.getValue(LLVMCall->getCalledFunction()))); 3255 } 3256 // Check isIndirectCall(). 3257 EXPECT_EQ(Call->isIndirectCall(), LLVMCall->isIndirectCall()); 3258 // Check getCaller(). 3259 EXPECT_EQ(Call->getCaller(), Ctx.getValue(LLVMCall->getCaller())); 3260 // Check isMustTailCall(). 3261 EXPECT_EQ(Call->isMustTailCall(), LLVMCall->isMustTailCall()); 3262 // Check isTailCall(). 3263 EXPECT_EQ(Call->isTailCall(), LLVMCall->isTailCall()); 3264 // Check getIntrinsicID(). 3265 EXPECT_EQ(Call->getIntrinsicID(), LLVMCall->getIntrinsicID()); 3266 // Check getCallingConv(). 3267 EXPECT_EQ(Call->getCallingConv(), LLVMCall->getCallingConv()); 3268 // Check isInlineAsm(). 3269 EXPECT_EQ(Call->isInlineAsm(), LLVMCall->isInlineAsm()); 3270 } 3271 3272 auto *Arg0 = F.getArg(0); 3273 auto *Arg1 = F.getArg(1); 3274 auto *BB = &*F.begin(); 3275 auto It = BB->begin(); 3276 auto *Call0 = cast<sandboxir::CallBase>(&*It++); 3277 [[maybe_unused]] auto *Call1 = cast<sandboxir::CallBase>(&*It++); 3278 auto *Call2 = cast<sandboxir::CallBase>(&*It++); 3279 // Check setArgOperand 3280 Call0->setArgOperand(0, Arg1); 3281 EXPECT_EQ(Call0->getArgOperand(0), Arg1); 3282 Call0->setArgOperand(0, Arg0); 3283 EXPECT_EQ(Call0->getArgOperand(0), Arg0); 3284 3285 auto *Bar3F = Ctx.createFunction(M->getFunction("bar3")); 3286 3287 // Check setCalledOperand 3288 auto *SvOp = Call0->getCalledOperand(); 3289 Call0->setCalledOperand(Bar3F); 3290 EXPECT_EQ(Call0->getCalledOperand(), Bar3F); 3291 Call0->setCalledOperand(SvOp); 3292 // Check setCalledFunction 3293 Call2->setCalledFunction(Bar3F); 3294 EXPECT_EQ(Call2->getCalledFunction(), Bar3F); 3295 } 3296 3297 TEST_F(SandboxIRTest, CallInst) { 3298 parseIR(C, R"IR( 3299 define i8 @foo(i8 %arg) { 3300 %call = call i8 @foo(i8 %arg) 3301 ret i8 %call 3302 } 3303 )IR"); 3304 Function &LLVMF = *M->getFunction("foo"); 3305 sandboxir::Context Ctx(C); 3306 auto &F = *Ctx.createFunction(&LLVMF); 3307 unsigned ArgIdx = 0; 3308 auto *Arg0 = F.getArg(ArgIdx++); 3309 auto *BB = &*F.begin(); 3310 auto It = BB->begin(); 3311 auto *Call = cast<sandboxir::CallInst>(&*It++); 3312 auto *Ret = cast<sandboxir::ReturnInst>(&*It++); 3313 EXPECT_EQ(Call->getNumOperands(), 2u); 3314 EXPECT_EQ(Ret->getOpcode(), sandboxir::Instruction::Opcode::Ret); 3315 sandboxir::FunctionType *FTy = F.getFunctionType(); 3316 SmallVector<sandboxir::Value *, 1> Args; 3317 Args.push_back(Arg0); 3318 { 3319 // Check create() WhereIt. 3320 auto *Call = cast<sandboxir::CallInst>(sandboxir::CallInst::create( 3321 FTy, &F, Args, /*WhereIt=*/Ret->getIterator(), Ctx)); 3322 EXPECT_EQ(Call->getNextNode(), Ret); 3323 EXPECT_EQ(Call->getCalledFunction(), &F); 3324 EXPECT_EQ(range_size(Call->args()), 1u); 3325 EXPECT_EQ(Call->getArgOperand(0), Arg0); 3326 } 3327 { 3328 // Check create() InsertBefore. 3329 auto *Call = cast<sandboxir::CallInst>( 3330 sandboxir::CallInst::create(FTy, &F, Args, Ret->getIterator(), Ctx)); 3331 EXPECT_EQ(Call->getNextNode(), Ret); 3332 EXPECT_EQ(Call->getCalledFunction(), &F); 3333 EXPECT_EQ(range_size(Call->args()), 1u); 3334 EXPECT_EQ(Call->getArgOperand(0), Arg0); 3335 } 3336 { 3337 // Check create() InsertAtEnd. 3338 auto *Call = cast<sandboxir::CallInst>( 3339 sandboxir::CallInst::create(FTy, &F, Args, /*InsertAtEnd=*/BB, Ctx)); 3340 EXPECT_EQ(Call->getPrevNode(), Ret); 3341 EXPECT_EQ(Call->getCalledFunction(), &F); 3342 EXPECT_EQ(range_size(Call->args()), 1u); 3343 EXPECT_EQ(Call->getArgOperand(0), Arg0); 3344 } 3345 } 3346 3347 TEST_F(SandboxIRTest, InvokeInst) { 3348 parseIR(C, R"IR( 3349 define void @foo(i8 %arg) { 3350 bb0: 3351 invoke i8 @foo(i8 %arg) to label %normal_bb 3352 unwind label %exception_bb 3353 normal_bb: 3354 ret void 3355 exception_bb: 3356 %lpad = landingpad { ptr, i32} 3357 cleanup 3358 ret void 3359 other_bb: 3360 ret void 3361 } 3362 )IR"); 3363 Function &LLVMF = *M->getFunction("foo"); 3364 sandboxir::Context Ctx(C); 3365 auto &F = *Ctx.createFunction(&LLVMF); 3366 auto *Arg = F.getArg(0); 3367 auto *BB0 = cast<sandboxir::BasicBlock>( 3368 Ctx.getValue(getBasicBlockByName(LLVMF, "bb0"))); 3369 auto *NormalBB = cast<sandboxir::BasicBlock>( 3370 Ctx.getValue(getBasicBlockByName(LLVMF, "normal_bb"))); 3371 auto *ExceptionBB = cast<sandboxir::BasicBlock>( 3372 Ctx.getValue(getBasicBlockByName(LLVMF, "exception_bb"))); 3373 auto *LandingPad = &*ExceptionBB->begin(); 3374 auto *OtherBB = cast<sandboxir::BasicBlock>( 3375 Ctx.getValue(getBasicBlockByName(LLVMF, "other_bb"))); 3376 auto It = BB0->begin(); 3377 // Check classof(Instruction *). 3378 auto *Invoke = cast<sandboxir::InvokeInst>(&*It++); 3379 3380 // Check getNormalDest(). 3381 EXPECT_EQ(Invoke->getNormalDest(), NormalBB); 3382 // Check getUnwindDest(). 3383 EXPECT_EQ(Invoke->getUnwindDest(), ExceptionBB); 3384 // Check getSuccessor(). 3385 EXPECT_EQ(Invoke->getSuccessor(0), NormalBB); 3386 EXPECT_EQ(Invoke->getSuccessor(1), ExceptionBB); 3387 // Check setNormalDest(). 3388 Invoke->setNormalDest(OtherBB); 3389 EXPECT_EQ(Invoke->getNormalDest(), OtherBB); 3390 EXPECT_EQ(Invoke->getUnwindDest(), ExceptionBB); 3391 // Check setUnwindDest(). 3392 Invoke->setUnwindDest(OtherBB); 3393 EXPECT_EQ(Invoke->getNormalDest(), OtherBB); 3394 EXPECT_EQ(Invoke->getUnwindDest(), OtherBB); 3395 // Check setSuccessor(). 3396 Invoke->setSuccessor(0, NormalBB); 3397 EXPECT_EQ(Invoke->getNormalDest(), NormalBB); 3398 Invoke->setSuccessor(1, ExceptionBB); 3399 EXPECT_EQ(Invoke->getUnwindDest(), ExceptionBB); 3400 // Check getLandingPadInst(). 3401 EXPECT_EQ(Invoke->getLandingPadInst(), LandingPad); 3402 3403 { 3404 // Check create() WhereIt, WhereBB. 3405 SmallVector<sandboxir::Value *> Args({Arg}); 3406 auto *InsertBefore = &*BB0->begin(); 3407 auto *NewInvoke = cast<sandboxir::InvokeInst>(sandboxir::InvokeInst::create( 3408 F.getFunctionType(), &F, NormalBB, ExceptionBB, Args, 3409 InsertBefore->getIterator(), Ctx)); 3410 EXPECT_EQ(NewInvoke->getNormalDest(), NormalBB); 3411 EXPECT_EQ(NewInvoke->getUnwindDest(), ExceptionBB); 3412 EXPECT_EQ(NewInvoke->getNextNode(), InsertBefore); 3413 } 3414 { 3415 // Check create() InsertBefore. 3416 SmallVector<sandboxir::Value *> Args({Arg}); 3417 auto *InsertBefore = &*BB0->begin(); 3418 auto *NewInvoke = cast<sandboxir::InvokeInst>(sandboxir::InvokeInst::create( 3419 F.getFunctionType(), &F, NormalBB, ExceptionBB, Args, 3420 InsertBefore->getIterator(), Ctx)); 3421 EXPECT_EQ(NewInvoke->getNormalDest(), NormalBB); 3422 EXPECT_EQ(NewInvoke->getUnwindDest(), ExceptionBB); 3423 EXPECT_EQ(NewInvoke->getNextNode(), InsertBefore); 3424 } 3425 { 3426 // Check create() InsertAtEnd. 3427 SmallVector<sandboxir::Value *> Args({Arg}); 3428 auto *NewInvoke = cast<sandboxir::InvokeInst>(sandboxir::InvokeInst::create( 3429 F.getFunctionType(), &F, NormalBB, ExceptionBB, Args, BB0, Ctx)); 3430 EXPECT_EQ(NewInvoke->getNormalDest(), NormalBB); 3431 EXPECT_EQ(NewInvoke->getUnwindDest(), ExceptionBB); 3432 EXPECT_EQ(NewInvoke->getParent(), BB0); 3433 EXPECT_EQ(NewInvoke->getNextNode(), nullptr); 3434 } 3435 } 3436 3437 TEST_F(SandboxIRTest, CallBrInst) { 3438 parseIR(C, R"IR( 3439 define void @foo(i8 %arg) { 3440 bb0: 3441 callbr void asm "", ""() 3442 to label %bb1 [label %bb2] 3443 bb1: 3444 ret void 3445 bb2: 3446 ret void 3447 other_bb: 3448 ret void 3449 bb3: 3450 callbr void @foo(i8 %arg) 3451 to label %bb1 [label %bb2] 3452 } 3453 )IR"); 3454 Function &LLVMF = *M->getFunction("foo"); 3455 auto *LLVMBB0 = getBasicBlockByName(LLVMF, "bb0"); 3456 auto *LLVMCallBr = cast<llvm::CallBrInst>(&*LLVMBB0->begin()); 3457 sandboxir::Context Ctx(C); 3458 auto &F = *Ctx.createFunction(&LLVMF); 3459 auto *Arg = F.getArg(0); 3460 auto *BB0 = cast<sandboxir::BasicBlock>( 3461 Ctx.getValue(getBasicBlockByName(LLVMF, "bb0"))); 3462 auto *BB1 = cast<sandboxir::BasicBlock>( 3463 Ctx.getValue(getBasicBlockByName(LLVMF, "bb1"))); 3464 auto *BB2 = cast<sandboxir::BasicBlock>( 3465 Ctx.getValue(getBasicBlockByName(LLVMF, "bb2"))); 3466 auto *BB3 = cast<sandboxir::BasicBlock>( 3467 Ctx.getValue(getBasicBlockByName(LLVMF, "bb3"))); 3468 auto *OtherBB = cast<sandboxir::BasicBlock>( 3469 Ctx.getValue(getBasicBlockByName(LLVMF, "other_bb"))); 3470 auto It = BB0->begin(); 3471 // Check classof(Instruction *). 3472 auto *CallBr0 = cast<sandboxir::CallBrInst>(&*It++); 3473 3474 It = BB3->begin(); 3475 auto *CallBr1 = cast<sandboxir::CallBrInst>(&*It++); 3476 for (sandboxir::CallBrInst *CallBr : {CallBr0, CallBr1}) { 3477 // Check getNumIndirectDests(). 3478 EXPECT_EQ(CallBr->getNumIndirectDests(), 1u); 3479 // Check getIndirectDestLabel(). 3480 EXPECT_EQ(CallBr->getIndirectDestLabel(0), 3481 Ctx.getValue(LLVMCallBr->getIndirectDestLabel(0))); 3482 // Check getIndirectDestLabelUse(). 3483 EXPECT_EQ(CallBr->getIndirectDestLabelUse(0), 3484 Ctx.getValue(LLVMCallBr->getIndirectDestLabelUse(0))); 3485 // Check getDefaultDest(). 3486 EXPECT_EQ(CallBr->getDefaultDest(), 3487 Ctx.getValue(LLVMCallBr->getDefaultDest())); 3488 // Check getIndirectDest(). 3489 EXPECT_EQ(CallBr->getIndirectDest(0), 3490 Ctx.getValue(LLVMCallBr->getIndirectDest(0))); 3491 // Check getIndirectDests(). 3492 auto Dests = CallBr->getIndirectDests(); 3493 EXPECT_EQ(Dests.size(), LLVMCallBr->getIndirectDests().size()); 3494 EXPECT_EQ(Dests[0], Ctx.getValue(LLVMCallBr->getIndirectDests()[0])); 3495 // Check getNumSuccessors(). 3496 EXPECT_EQ(CallBr->getNumSuccessors(), LLVMCallBr->getNumSuccessors()); 3497 // Check getSuccessor(). 3498 for (unsigned SuccIdx = 0, E = CallBr->getNumSuccessors(); SuccIdx != E; 3499 ++SuccIdx) 3500 EXPECT_EQ(CallBr->getSuccessor(SuccIdx), 3501 Ctx.getValue(LLVMCallBr->getSuccessor(SuccIdx))); 3502 // Check setDefaultDest(). 3503 auto *SvDefaultDest = CallBr->getDefaultDest(); 3504 CallBr->setDefaultDest(OtherBB); 3505 EXPECT_EQ(CallBr->getDefaultDest(), OtherBB); 3506 CallBr->setDefaultDest(SvDefaultDest); 3507 // Check setIndirectDest(). 3508 auto *SvIndirectDest = CallBr->getIndirectDest(0); 3509 CallBr->setIndirectDest(0, OtherBB); 3510 EXPECT_EQ(CallBr->getIndirectDest(0), OtherBB); 3511 CallBr->setIndirectDest(0, SvIndirectDest); 3512 } 3513 3514 { 3515 // Check create() WhereIt, WhereBB. 3516 SmallVector<sandboxir::Value *> Args({Arg}); 3517 auto *NewCallBr = cast<sandboxir::CallBrInst>(sandboxir::CallBrInst::create( 3518 F.getFunctionType(), &F, BB1, {BB2}, Args, BB0->end(), Ctx)); 3519 EXPECT_EQ(NewCallBr->getDefaultDest(), BB1); 3520 EXPECT_EQ(NewCallBr->getIndirectDests().size(), 1u); 3521 EXPECT_EQ(NewCallBr->getIndirectDests()[0], BB2); 3522 EXPECT_EQ(NewCallBr->getNextNode(), nullptr); 3523 EXPECT_EQ(NewCallBr->getParent(), BB0); 3524 } 3525 { 3526 // Check create() InsertBefore 3527 SmallVector<sandboxir::Value *> Args({Arg}); 3528 auto *InsertBefore = &*BB0->rbegin(); 3529 auto *NewCallBr = cast<sandboxir::CallBrInst>( 3530 sandboxir::CallBrInst::create(F.getFunctionType(), &F, BB1, {BB2}, Args, 3531 InsertBefore->getIterator(), Ctx)); 3532 EXPECT_EQ(NewCallBr->getDefaultDest(), BB1); 3533 EXPECT_EQ(NewCallBr->getIndirectDests().size(), 1u); 3534 EXPECT_EQ(NewCallBr->getIndirectDests()[0], BB2); 3535 EXPECT_EQ(NewCallBr->getNextNode(), InsertBefore); 3536 } 3537 { 3538 // Check create() InsertAtEnd. 3539 SmallVector<sandboxir::Value *> Args({Arg}); 3540 auto *NewCallBr = cast<sandboxir::CallBrInst>(sandboxir::CallBrInst::create( 3541 F.getFunctionType(), &F, BB1, {BB2}, Args, BB0, Ctx)); 3542 EXPECT_EQ(NewCallBr->getDefaultDest(), BB1); 3543 EXPECT_EQ(NewCallBr->getIndirectDests().size(), 1u); 3544 EXPECT_EQ(NewCallBr->getIndirectDests()[0], BB2); 3545 EXPECT_EQ(NewCallBr->getNextNode(), nullptr); 3546 EXPECT_EQ(NewCallBr->getParent(), BB0); 3547 } 3548 } 3549 3550 TEST_F(SandboxIRTest, LandingPadInst) { 3551 parseIR(C, R"IR( 3552 define void @foo() { 3553 entry: 3554 invoke void @foo() 3555 to label %bb unwind label %unwind 3556 unwind: 3557 %lpad = landingpad { ptr, i32 } 3558 catch ptr null 3559 ret void 3560 bb: 3561 ret void 3562 } 3563 )IR"); 3564 Function &LLVMF = *M->getFunction("foo"); 3565 auto *LLVMUnwind = getBasicBlockByName(LLVMF, "unwind"); 3566 auto *LLVMLPad = cast<llvm::LandingPadInst>(&*LLVMUnwind->begin()); 3567 3568 sandboxir::Context Ctx(C); 3569 [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF); 3570 auto *Unwind = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMUnwind)); 3571 auto *BB = cast<sandboxir::BasicBlock>( 3572 Ctx.getValue(getBasicBlockByName(LLVMF, "bb"))); 3573 auto It = Unwind->begin(); 3574 auto *LPad = cast<sandboxir::LandingPadInst>(&*It++); 3575 [[maybe_unused]] auto *Ret = cast<sandboxir::ReturnInst>(&*It++); 3576 3577 // Check isCleanup(). 3578 EXPECT_EQ(LPad->isCleanup(), LLVMLPad->isCleanup()); 3579 // Check setCleanup(). 3580 auto OrigIsCleanup = LPad->isCleanup(); 3581 auto NewIsCleanup = true; 3582 EXPECT_NE(NewIsCleanup, OrigIsCleanup); 3583 LPad->setCleanup(NewIsCleanup); 3584 EXPECT_EQ(LPad->isCleanup(), NewIsCleanup); 3585 LPad->setCleanup(OrigIsCleanup); 3586 EXPECT_EQ(LPad->isCleanup(), OrigIsCleanup); 3587 // Check getNumClauses(). 3588 EXPECT_EQ(LPad->getNumClauses(), LLVMLPad->getNumClauses()); 3589 // Check getClause(). 3590 for (auto Idx : seq<unsigned>(0, LPad->getNumClauses())) 3591 EXPECT_EQ(LPad->getClause(Idx), Ctx.getValue(LLVMLPad->getClause(Idx))); 3592 // Check isCatch(). 3593 for (auto Idx : seq<unsigned>(0, LPad->getNumClauses())) 3594 EXPECT_EQ(LPad->isCatch(Idx), LLVMLPad->isCatch(Idx)); 3595 // Check isFilter(). 3596 for (auto Idx : seq<unsigned>(0, LPad->getNumClauses())) 3597 EXPECT_EQ(LPad->isFilter(Idx), LLVMLPad->isFilter(Idx)); 3598 // Check create(). 3599 auto *BBRet = &*BB->begin(); 3600 auto *NewLPad = cast<sandboxir::LandingPadInst>( 3601 sandboxir::LandingPadInst::create(sandboxir::Type::getInt8Ty(Ctx), 0, 3602 BBRet->getIterator(), Ctx, "NewLPad")); 3603 EXPECT_EQ(NewLPad->getNextNode(), BBRet); 3604 EXPECT_FALSE(NewLPad->isCleanup()); 3605 #ifndef NDEBUG 3606 EXPECT_EQ(NewLPad->getName(), "NewLPad"); 3607 #endif // NDEBUG 3608 } 3609 3610 TEST_F(SandboxIRTest, FuncletPadInst_CatchPadInst_CleanupPadInst) { 3611 parseIR(C, R"IR( 3612 define void @foo() { 3613 dispatch: 3614 %cs = catchswitch within none [label %handler0] unwind to caller 3615 handler0: 3616 %catchpad = catchpad within %cs [ptr @foo] 3617 ret void 3618 handler1: 3619 %cleanuppad = cleanuppad within %cs [ptr @foo] 3620 ret void 3621 bb: 3622 ret void 3623 } 3624 )IR"); 3625 Function &LLVMF = *M->getFunction("foo"); 3626 BasicBlock *LLVMDispatch = getBasicBlockByName(LLVMF, "dispatch"); 3627 BasicBlock *LLVMHandler0 = getBasicBlockByName(LLVMF, "handler0"); 3628 BasicBlock *LLVMHandler1 = getBasicBlockByName(LLVMF, "handler1"); 3629 auto *LLVMCP = cast<llvm::CatchPadInst>(&*LLVMHandler0->begin()); 3630 auto *LLVMCLP = cast<llvm::CleanupPadInst>(&*LLVMHandler1->begin()); 3631 3632 sandboxir::Context Ctx(C); 3633 [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF); 3634 auto *Dispatch = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMDispatch)); 3635 auto *Handler0 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMHandler0)); 3636 auto *Handler1 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMHandler1)); 3637 auto *BB = cast<sandboxir::BasicBlock>( 3638 Ctx.getValue(getBasicBlockByName(LLVMF, "bb"))); 3639 auto *BBRet = cast<sandboxir::ReturnInst>(&*BB->begin()); 3640 auto *CS = cast<sandboxir::CatchSwitchInst>(&*Dispatch->begin()); 3641 [[maybe_unused]] auto *CP = 3642 cast<sandboxir::CatchPadInst>(&*Handler0->begin()); 3643 [[maybe_unused]] auto *CLP = 3644 cast<sandboxir::CleanupPadInst>(&*Handler1->begin()); 3645 3646 // Check getCatchSwitch(). 3647 EXPECT_EQ(CP->getCatchSwitch(), CS); 3648 EXPECT_EQ(CP->getCatchSwitch(), Ctx.getValue(LLVMCP->getCatchSwitch())); 3649 3650 for (llvm::FuncletPadInst *LLVMFPI : 3651 {static_cast<llvm::FuncletPadInst *>(LLVMCP), 3652 static_cast<llvm::FuncletPadInst *>(LLVMCLP)}) { 3653 auto *FPI = cast<sandboxir::FuncletPadInst>(Ctx.getValue(LLVMFPI)); 3654 // Check arg_size(). 3655 EXPECT_EQ(FPI->arg_size(), LLVMFPI->arg_size()); 3656 // Check getParentPad(). 3657 EXPECT_EQ(FPI->getParentPad(), Ctx.getValue(LLVMFPI->getParentPad())); 3658 // Check setParentPad(). 3659 auto *OrigParentPad = FPI->getParentPad(); 3660 auto *NewParentPad = Dispatch; 3661 EXPECT_NE(NewParentPad, OrigParentPad); 3662 FPI->setParentPad(NewParentPad); 3663 EXPECT_EQ(FPI->getParentPad(), NewParentPad); 3664 FPI->setParentPad(OrigParentPad); 3665 EXPECT_EQ(FPI->getParentPad(), OrigParentPad); 3666 // Check getArgOperand(). 3667 for (auto Idx : seq<unsigned>(0, FPI->arg_size())) 3668 EXPECT_EQ(FPI->getArgOperand(Idx), 3669 Ctx.getValue(LLVMFPI->getArgOperand(Idx))); 3670 // Check setArgOperand(). 3671 auto *OrigArgOperand = FPI->getArgOperand(0); 3672 auto *NewArgOperand = Dispatch; 3673 EXPECT_NE(NewArgOperand, OrigArgOperand); 3674 FPI->setArgOperand(0, NewArgOperand); 3675 EXPECT_EQ(FPI->getArgOperand(0), NewArgOperand); 3676 FPI->setArgOperand(0, OrigArgOperand); 3677 EXPECT_EQ(FPI->getArgOperand(0), OrigArgOperand); 3678 } 3679 // Check CatchPadInst::create(). 3680 auto *NewCPI = cast<sandboxir::CatchPadInst>(sandboxir::CatchPadInst::create( 3681 CS, {}, BBRet->getIterator(), Ctx, "NewCPI")); 3682 EXPECT_EQ(NewCPI->getCatchSwitch(), CS); 3683 EXPECT_EQ(NewCPI->arg_size(), 0u); 3684 EXPECT_EQ(NewCPI->getNextNode(), BBRet); 3685 #ifndef NDEBUG 3686 EXPECT_EQ(NewCPI->getName(), "NewCPI"); 3687 #endif // NDEBUG 3688 // Check CleanupPadInst::create(). 3689 auto *NewCLPI = 3690 cast<sandboxir::CleanupPadInst>(sandboxir::CleanupPadInst::create( 3691 CS, {}, BBRet->getIterator(), Ctx, "NewCLPI")); 3692 EXPECT_EQ(NewCLPI->getParentPad(), CS); 3693 EXPECT_EQ(NewCLPI->arg_size(), 0u); 3694 EXPECT_EQ(NewCLPI->getNextNode(), BBRet); 3695 #ifndef NDEBUG 3696 EXPECT_EQ(NewCLPI->getName(), "NewCLPI"); 3697 #endif // NDEBUG 3698 } 3699 3700 TEST_F(SandboxIRTest, CatchReturnInst) { 3701 parseIR(C, R"IR( 3702 define void @foo() { 3703 dispatch: 3704 %cs = catchswitch within none [label %catch] unwind to caller 3705 catch: 3706 %catchpad = catchpad within %cs [ptr @foo] 3707 catchret from %catchpad to label %continue 3708 continue: 3709 ret void 3710 catch2: 3711 %catchpad2 = catchpad within %cs [ptr @foo] 3712 ret void 3713 } 3714 )IR"); 3715 Function &LLVMF = *M->getFunction("foo"); 3716 BasicBlock *LLVMCatch = getBasicBlockByName(LLVMF, "catch"); 3717 auto LLVMIt = LLVMCatch->begin(); 3718 [[maybe_unused]] auto *LLVMCP = cast<llvm::CatchPadInst>(&*LLVMIt++); 3719 auto *LLVMCR = cast<llvm::CatchReturnInst>(&*LLVMIt++); 3720 3721 sandboxir::Context Ctx(C); 3722 [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF); 3723 auto *Catch = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMCatch)); 3724 auto *Catch2 = cast<sandboxir::BasicBlock>( 3725 Ctx.getValue(getBasicBlockByName(LLVMF, "catch2"))); 3726 auto It = Catch->begin(); 3727 [[maybe_unused]] auto *CP = cast<sandboxir::CatchPadInst>(&*It++); 3728 auto *CR = cast<sandboxir::CatchReturnInst>(&*It++); 3729 auto *CP2 = cast<sandboxir::CatchPadInst>(&*Catch2->begin()); 3730 3731 // Check getCatchPad(). 3732 EXPECT_EQ(CR->getCatchPad(), Ctx.getValue(LLVMCR->getCatchPad())); 3733 // Check setCatchPad(). 3734 auto *OrigCP = CR->getCatchPad(); 3735 auto *NewCP = CP2; 3736 EXPECT_NE(NewCP, OrigCP); 3737 CR->setCatchPad(NewCP); 3738 EXPECT_EQ(CR->getCatchPad(), NewCP); 3739 CR->setCatchPad(OrigCP); 3740 EXPECT_EQ(CR->getCatchPad(), OrigCP); 3741 // Check getSuccessor(). 3742 EXPECT_EQ(CR->getSuccessor(), Ctx.getValue(LLVMCR->getSuccessor())); 3743 // Check setSuccessor(). 3744 auto *OrigSucc = CR->getSuccessor(); 3745 auto *NewSucc = Catch; 3746 EXPECT_NE(NewSucc, OrigSucc); 3747 CR->setSuccessor(NewSucc); 3748 EXPECT_EQ(CR->getSuccessor(), NewSucc); 3749 CR->setSuccessor(OrigSucc); 3750 EXPECT_EQ(CR->getSuccessor(), OrigSucc); 3751 // Check getNumSuccessors(). 3752 EXPECT_EQ(CR->getNumSuccessors(), LLVMCR->getNumSuccessors()); 3753 // Check getCatchSwitchParentPad(). 3754 EXPECT_EQ(CR->getCatchSwitchParentPad(), 3755 Ctx.getValue(LLVMCR->getCatchSwitchParentPad())); 3756 // Check create(). 3757 auto *CRI = cast<sandboxir::CatchReturnInst>( 3758 sandboxir::CatchReturnInst::create(CP, Catch, CP->getIterator(), Ctx)); 3759 EXPECT_EQ(CRI->getNextNode(), CP); 3760 EXPECT_EQ(CRI->getCatchPad(), CP); 3761 EXPECT_EQ(CRI->getSuccessor(), Catch); 3762 } 3763 3764 TEST_F(SandboxIRTest, CleanupReturnInst) { 3765 parseIR(C, R"IR( 3766 define void @foo() { 3767 dispatch: 3768 invoke void @foo() 3769 to label %throw unwind label %cleanup 3770 throw: 3771 ret void 3772 cleanup: 3773 %cleanuppad = cleanuppad within none [] 3774 cleanupret from %cleanuppad unwind label %cleanup2 3775 cleanup2: 3776 %cleanuppad2 = cleanuppad within none [] 3777 ret void 3778 } 3779 )IR"); 3780 Function &LLVMF = *M->getFunction("foo"); 3781 BasicBlock *LLVMCleanup = getBasicBlockByName(LLVMF, "cleanup"); 3782 auto LLVMIt = LLVMCleanup->begin(); 3783 [[maybe_unused]] auto *LLVMCP = cast<llvm::CleanupPadInst>(&*LLVMIt++); 3784 auto *LLVMCRI = cast<llvm::CleanupReturnInst>(&*LLVMIt++); 3785 3786 sandboxir::Context Ctx(C); 3787 [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF); 3788 auto *Throw = cast<sandboxir::BasicBlock>( 3789 Ctx.getValue(getBasicBlockByName(LLVMF, "throw"))); 3790 auto *Cleanup = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMCleanup)); 3791 auto *Cleanup2 = cast<sandboxir::BasicBlock>( 3792 Ctx.getValue(getBasicBlockByName(LLVMF, "cleanup2"))); 3793 auto It = Cleanup->begin(); 3794 [[maybe_unused]] auto *CP = cast<sandboxir::CleanupPadInst>(&*It++); 3795 auto *CRI = cast<sandboxir::CleanupReturnInst>(&*It++); 3796 It = Cleanup2->begin(); 3797 auto *CP2 = cast<sandboxir::CleanupPadInst>(&*It++); 3798 auto *Ret = cast<sandboxir::ReturnInst>(&*It++); 3799 3800 // Check hasUnwindDest(). 3801 EXPECT_EQ(CRI->hasUnwindDest(), LLVMCRI->hasUnwindDest()); 3802 // Check unwindsToCaller(). 3803 EXPECT_EQ(CRI->unwindsToCaller(), LLVMCRI->unwindsToCaller()); 3804 // Check getCleanupPad(). 3805 EXPECT_EQ(CRI->getCleanupPad(), Ctx.getValue(LLVMCRI->getCleanupPad())); 3806 // Check setCleanupPad(). 3807 auto *OrigCleanupPad = CRI->getCleanupPad(); 3808 auto *NewCleanupPad = CP2; 3809 EXPECT_NE(NewCleanupPad, OrigCleanupPad); 3810 CRI->setCleanupPad(NewCleanupPad); 3811 EXPECT_EQ(CRI->getCleanupPad(), NewCleanupPad); 3812 CRI->setCleanupPad(OrigCleanupPad); 3813 EXPECT_EQ(CRI->getCleanupPad(), OrigCleanupPad); 3814 // Check setNumSuccessors(). 3815 EXPECT_EQ(CRI->getNumSuccessors(), LLVMCRI->getNumSuccessors()); 3816 // Check getUnwindDest(). 3817 EXPECT_EQ(CRI->getUnwindDest(), Ctx.getValue(LLVMCRI->getUnwindDest())); 3818 // Check setUnwindDest(). 3819 auto *OrigUnwindDest = CRI->getUnwindDest(); 3820 auto *NewUnwindDest = Throw; 3821 EXPECT_NE(NewUnwindDest, OrigUnwindDest); 3822 CRI->setUnwindDest(NewUnwindDest); 3823 EXPECT_EQ(CRI->getUnwindDest(), NewUnwindDest); 3824 CRI->setUnwindDest(OrigUnwindDest); 3825 EXPECT_EQ(CRI->getUnwindDest(), OrigUnwindDest); 3826 // Check create(). 3827 auto *UnwindBB = Cleanup; 3828 auto *NewCRI = sandboxir::CleanupReturnInst::create(CP2, UnwindBB, 3829 Ret->getIterator(), Ctx); 3830 EXPECT_EQ(NewCRI->getCleanupPad(), CP2); 3831 EXPECT_EQ(NewCRI->getUnwindDest(), UnwindBB); 3832 EXPECT_EQ(NewCRI->getNextNode(), Ret); 3833 } 3834 3835 TEST_F(SandboxIRTest, GetElementPtrInstruction) { 3836 parseIR(C, R"IR( 3837 define void @foo(ptr %ptr, <2 x ptr> %ptrs) { 3838 %gep0 = getelementptr i8, ptr %ptr, i32 0 3839 %gep1 = getelementptr nusw i8, ptr %ptr, i32 0 3840 %gep2 = getelementptr nuw i8, ptr %ptr, i32 0 3841 %gep3 = getelementptr inbounds {i32, {i32, i8}}, ptr %ptr, i32 1, i32 0 3842 %gep4 = getelementptr inbounds {i8, i8, {i32, i16}}, <2 x ptr> %ptrs, i32 2, <2 x i32> <i32 0, i32 0> 3843 ret void 3844 } 3845 )IR"); 3846 Function &LLVMF = *M->getFunction("foo"); 3847 BasicBlock *LLVMBB = &*LLVMF.begin(); 3848 auto LLVMIt = LLVMBB->begin(); 3849 SmallVector<llvm::GetElementPtrInst *, 4> LLVMGEPs; 3850 while (isa<llvm::GetElementPtrInst>(&*LLVMIt)) 3851 LLVMGEPs.push_back(cast<llvm::GetElementPtrInst>(&*LLVMIt++)); 3852 auto *LLVMRet = cast<llvm::ReturnInst>(&*LLVMIt++); 3853 sandboxir::Context Ctx(C); 3854 [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF); 3855 3856 for (llvm::GetElementPtrInst *LLVMGEP : LLVMGEPs) { 3857 // Check classof(). 3858 auto *GEP = cast<sandboxir::GetElementPtrInst>(Ctx.getValue(LLVMGEP)); 3859 // Check getSourceElementType(). 3860 EXPECT_EQ(GEP->getSourceElementType(), 3861 Ctx.getType(LLVMGEP->getSourceElementType())); 3862 // Check getResultElementType(). 3863 EXPECT_EQ(GEP->getResultElementType(), 3864 Ctx.getType(LLVMGEP->getResultElementType())); 3865 // Check getAddressSpace(). 3866 EXPECT_EQ(GEP->getAddressSpace(), LLVMGEP->getAddressSpace()); 3867 // Check indices(). 3868 EXPECT_EQ(range_size(GEP->indices()), range_size(LLVMGEP->indices())); 3869 auto IdxIt = GEP->idx_begin(); 3870 for (llvm::Value *LLVMIdxV : LLVMGEP->indices()) { 3871 sandboxir::Value *IdxV = *IdxIt++; 3872 EXPECT_EQ(IdxV, Ctx.getValue(LLVMIdxV)); 3873 } 3874 // Check getPointerOperand(). 3875 EXPECT_EQ(GEP->getPointerOperand(), 3876 Ctx.getValue(LLVMGEP->getPointerOperand())); 3877 // Check getPointerOperandIndex(). 3878 EXPECT_EQ(GEP->getPointerOperandIndex(), LLVMGEP->getPointerOperandIndex()); 3879 // Check getPointerOperandType(). 3880 EXPECT_EQ(GEP->getPointerOperandType(), 3881 Ctx.getType(LLVMGEP->getPointerOperandType())); 3882 // Check getPointerAddressSpace(). 3883 EXPECT_EQ(GEP->getPointerAddressSpace(), LLVMGEP->getPointerAddressSpace()); 3884 // Check getNumIndices(). 3885 EXPECT_EQ(GEP->getNumIndices(), LLVMGEP->getNumIndices()); 3886 // Check hasIndices(). 3887 EXPECT_EQ(GEP->hasIndices(), LLVMGEP->hasIndices()); 3888 // Check hasAllConstantIndices(). 3889 EXPECT_EQ(GEP->hasAllConstantIndices(), LLVMGEP->hasAllConstantIndices()); 3890 // Check getNoWrapFlags(). 3891 EXPECT_EQ(GEP->getNoWrapFlags(), LLVMGEP->getNoWrapFlags()); 3892 // Check isInBounds(). 3893 EXPECT_EQ(GEP->isInBounds(), LLVMGEP->isInBounds()); 3894 // Check hasNoUnsignedWrap(). 3895 EXPECT_EQ(GEP->hasNoUnsignedWrap(), LLVMGEP->hasNoUnsignedWrap()); 3896 // Check accumulateConstantOffset(). 3897 const DataLayout &DL = M->getDataLayout(); 3898 APInt Offset1 = 3899 APInt::getZero(DL.getIndexSizeInBits(GEP->getPointerAddressSpace())); 3900 APInt Offset2 = 3901 APInt::getZero(DL.getIndexSizeInBits(GEP->getPointerAddressSpace())); 3902 EXPECT_EQ(GEP->accumulateConstantOffset(DL, Offset1), 3903 LLVMGEP->accumulateConstantOffset(DL, Offset2)); 3904 EXPECT_EQ(Offset1, Offset2); 3905 } 3906 3907 auto *BB = &*F.begin(); 3908 auto *GEP0 = cast<sandboxir::GetElementPtrInst>(&*BB->begin()); 3909 auto *Ret = cast<sandboxir::ReturnInst>(Ctx.getValue(LLVMRet)); 3910 SmallVector<sandboxir::Value *> Indices(GEP0->indices()); 3911 3912 // Check create() WhereIt, WhereBB. 3913 auto *NewGEP0 = 3914 cast<sandboxir::GetElementPtrInst>(sandboxir::GetElementPtrInst::create( 3915 GEP0->getType(), GEP0->getPointerOperand(), Indices, 3916 Ret->getIterator(), Ctx, "NewGEP0")); 3917 EXPECT_EQ(NewGEP0->getName(), "NewGEP0"); 3918 EXPECT_EQ(NewGEP0->getType(), GEP0->getType()); 3919 EXPECT_EQ(NewGEP0->getPointerOperand(), GEP0->getPointerOperand()); 3920 EXPECT_EQ(range_size(NewGEP0->indices()), range_size(GEP0->indices())); 3921 for (auto NewIt = NewGEP0->idx_begin(), NewItE = NewGEP0->idx_end(), 3922 OldIt = GEP0->idx_begin(); 3923 NewIt != NewItE; ++NewIt) { 3924 sandboxir::Value *NewIdxV = *NewIt; 3925 sandboxir::Value *OldIdxV = *OldIt; 3926 EXPECT_EQ(NewIdxV, OldIdxV); 3927 } 3928 EXPECT_EQ(NewGEP0->getNextNode(), Ret); 3929 3930 // Check create() InsertBefore. 3931 auto *NewGEP1 = 3932 cast<sandboxir::GetElementPtrInst>(sandboxir::GetElementPtrInst::create( 3933 GEP0->getType(), GEP0->getPointerOperand(), Indices, 3934 Ret->getIterator(), Ctx, "NewGEP1")); 3935 EXPECT_EQ(NewGEP1->getName(), "NewGEP1"); 3936 EXPECT_EQ(NewGEP1->getType(), GEP0->getType()); 3937 EXPECT_EQ(NewGEP1->getPointerOperand(), GEP0->getPointerOperand()); 3938 EXPECT_EQ(range_size(NewGEP1->indices()), range_size(GEP0->indices())); 3939 for (auto NewIt = NewGEP0->idx_begin(), NewItE = NewGEP0->idx_end(), 3940 OldIt = GEP0->idx_begin(); 3941 NewIt != NewItE; ++NewIt) { 3942 sandboxir::Value *NewIdxV = *NewIt; 3943 sandboxir::Value *OldIdxV = *OldIt; 3944 EXPECT_EQ(NewIdxV, OldIdxV); 3945 } 3946 EXPECT_EQ(NewGEP1->getNextNode(), Ret); 3947 3948 // Check create() InsertAtEnd. 3949 auto *NewGEP2 = 3950 cast<sandboxir::GetElementPtrInst>(sandboxir::GetElementPtrInst::create( 3951 GEP0->getType(), GEP0->getPointerOperand(), Indices, BB, Ctx, 3952 "NewGEP2")); 3953 EXPECT_EQ(NewGEP2->getName(), "NewGEP2"); 3954 EXPECT_EQ(NewGEP2->getType(), GEP0->getType()); 3955 EXPECT_EQ(NewGEP2->getPointerOperand(), GEP0->getPointerOperand()); 3956 EXPECT_EQ(range_size(NewGEP2->indices()), range_size(GEP0->indices())); 3957 for (auto NewIt = NewGEP0->idx_begin(), NewItE = NewGEP0->idx_end(), 3958 OldIt = GEP0->idx_begin(); 3959 NewIt != NewItE; ++NewIt) { 3960 sandboxir::Value *NewIdxV = *NewIt; 3961 sandboxir::Value *OldIdxV = *OldIt; 3962 EXPECT_EQ(NewIdxV, OldIdxV); 3963 } 3964 EXPECT_EQ(NewGEP2->getPrevNode(), Ret); 3965 EXPECT_EQ(NewGEP2->getNextNode(), nullptr); 3966 } 3967 3968 TEST_F(SandboxIRTest, Flags) { 3969 parseIR(C, R"IR( 3970 define void @foo(i32 %arg, float %farg) { 3971 %add = add i32 %arg, %arg 3972 %fadd = fadd float %farg, %farg 3973 %udiv = udiv i32 %arg, %arg 3974 ret void 3975 } 3976 )IR"); 3977 Function &LLVMF = *M->getFunction("foo"); 3978 BasicBlock *LLVMBB = &*LLVMF.begin(); 3979 auto LLVMIt = LLVMBB->begin(); 3980 auto *LLVMAdd = &*LLVMIt++; 3981 auto *LLVMFAdd = &*LLVMIt++; 3982 auto *LLVMUDiv = &*LLVMIt++; 3983 3984 sandboxir::Context Ctx(C); 3985 auto &F = *Ctx.createFunction(&LLVMF); 3986 auto *BB = &*F.begin(); 3987 auto It = BB->begin(); 3988 auto *Add = &*It++; 3989 auto *FAdd = &*It++; 3990 auto *UDiv = &*It++; 3991 3992 #define CHECK_FLAG(I, LLVMI, GETTER, SETTER) \ 3993 { \ 3994 EXPECT_EQ(I->GETTER(), LLVMI->GETTER()); \ 3995 bool NewFlagVal = !I->GETTER(); \ 3996 I->SETTER(NewFlagVal); \ 3997 EXPECT_EQ(I->GETTER(), NewFlagVal); \ 3998 EXPECT_EQ(I->GETTER(), LLVMI->GETTER()); \ 3999 } 4000 4001 CHECK_FLAG(Add, LLVMAdd, hasNoUnsignedWrap, setHasNoUnsignedWrap); 4002 CHECK_FLAG(Add, LLVMAdd, hasNoSignedWrap, setHasNoSignedWrap); 4003 CHECK_FLAG(FAdd, LLVMFAdd, isFast, setFast); 4004 CHECK_FLAG(FAdd, LLVMFAdd, hasAllowReassoc, setHasAllowReassoc); 4005 CHECK_FLAG(UDiv, LLVMUDiv, isExact, setIsExact); 4006 CHECK_FLAG(FAdd, LLVMFAdd, hasNoNaNs, setHasNoNaNs); 4007 CHECK_FLAG(FAdd, LLVMFAdd, hasNoInfs, setHasNoInfs); 4008 CHECK_FLAG(FAdd, LLVMFAdd, hasNoSignedZeros, setHasNoSignedZeros); 4009 CHECK_FLAG(FAdd, LLVMFAdd, hasAllowReciprocal, setHasAllowReciprocal); 4010 CHECK_FLAG(FAdd, LLVMFAdd, hasAllowContract, setHasAllowContract); 4011 CHECK_FLAG(FAdd, LLVMFAdd, hasApproxFunc, setHasApproxFunc); 4012 4013 // Check getFastMathFlags(), copyFastMathFlags(). 4014 FAdd->setFastMathFlags(FastMathFlags::getFast()); 4015 EXPECT_FALSE(FAdd->getFastMathFlags() != LLVMFAdd->getFastMathFlags()); 4016 FastMathFlags OrigFMF = FAdd->getFastMathFlags(); 4017 FastMathFlags NewFMF; 4018 NewFMF.setAllowReassoc(true); 4019 EXPECT_TRUE(NewFMF != OrigFMF); 4020 FAdd->setFastMathFlags(NewFMF); 4021 EXPECT_FALSE(FAdd->getFastMathFlags() != OrigFMF); 4022 FAdd->copyFastMathFlags(NewFMF); 4023 EXPECT_FALSE(FAdd->getFastMathFlags() != NewFMF); 4024 EXPECT_FALSE(FAdd->getFastMathFlags() != LLVMFAdd->getFastMathFlags()); 4025 } 4026 4027 TEST_F(SandboxIRTest, CatchSwitchInst) { 4028 parseIR(C, R"IR( 4029 define void @foo(i32 %cond0, i32 %cond1) { 4030 bb0: 4031 %cs0 = catchswitch within none [label %handler0, label %handler1] unwind to caller 4032 bb1: 4033 %cs1 = catchswitch within %cs0 [label %handler0, label %handler1] unwind label %cleanup 4034 handler0: 4035 ret void 4036 handler1: 4037 ret void 4038 cleanup: 4039 ret void 4040 } 4041 )IR"); 4042 Function &LLVMF = *M->getFunction("foo"); 4043 auto *LLVMBB0 = getBasicBlockByName(LLVMF, "bb0"); 4044 auto *LLVMBB1 = getBasicBlockByName(LLVMF, "bb1"); 4045 auto *LLVMHandler0 = getBasicBlockByName(LLVMF, "handler0"); 4046 auto *LLVMHandler1 = getBasicBlockByName(LLVMF, "handler1"); 4047 auto *LLVMCleanup = getBasicBlockByName(LLVMF, "cleanup"); 4048 auto *LLVMCS0 = cast<llvm::CatchSwitchInst>(&*LLVMBB0->begin()); 4049 auto *LLVMCS1 = cast<llvm::CatchSwitchInst>(&*LLVMBB1->begin()); 4050 4051 sandboxir::Context Ctx(C); 4052 [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF); 4053 auto *BB0 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB0)); 4054 auto *BB1 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB1)); 4055 auto *Handler0 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMHandler0)); 4056 auto *Handler1 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMHandler1)); 4057 auto *Cleanup = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMCleanup)); 4058 auto *CS0 = cast<sandboxir::CatchSwitchInst>(&*BB0->begin()); 4059 auto *CS1 = cast<sandboxir::CatchSwitchInst>(&*BB1->begin()); 4060 4061 // Check getParentPad(). 4062 EXPECT_EQ(CS0->getParentPad(), Ctx.getValue(LLVMCS0->getParentPad())); 4063 EXPECT_EQ(CS1->getParentPad(), Ctx.getValue(LLVMCS1->getParentPad())); 4064 // Check setParentPad(). 4065 auto *OrigPad = CS0->getParentPad(); 4066 auto *NewPad = CS1; 4067 EXPECT_NE(NewPad, OrigPad); 4068 CS0->setParentPad(NewPad); 4069 EXPECT_EQ(CS0->getParentPad(), NewPad); 4070 CS0->setParentPad(OrigPad); 4071 EXPECT_EQ(CS0->getParentPad(), OrigPad); 4072 // Check hasUnwindDest(). 4073 EXPECT_EQ(CS0->hasUnwindDest(), LLVMCS0->hasUnwindDest()); 4074 EXPECT_EQ(CS1->hasUnwindDest(), LLVMCS1->hasUnwindDest()); 4075 // Check unwindsToCaller(). 4076 EXPECT_EQ(CS0->unwindsToCaller(), LLVMCS0->unwindsToCaller()); 4077 EXPECT_EQ(CS1->unwindsToCaller(), LLVMCS1->unwindsToCaller()); 4078 // Check getUnwindDest(). 4079 EXPECT_EQ(CS0->getUnwindDest(), Ctx.getValue(LLVMCS0->getUnwindDest())); 4080 EXPECT_EQ(CS1->getUnwindDest(), Ctx.getValue(LLVMCS1->getUnwindDest())); 4081 // Check setUnwindDest(). 4082 auto *OrigUnwindDest = CS1->getUnwindDest(); 4083 auto *NewUnwindDest = BB0; 4084 EXPECT_NE(NewUnwindDest, OrigUnwindDest); 4085 CS1->setUnwindDest(NewUnwindDest); 4086 EXPECT_EQ(CS1->getUnwindDest(), NewUnwindDest); 4087 CS1->setUnwindDest(OrigUnwindDest); 4088 EXPECT_EQ(CS1->getUnwindDest(), OrigUnwindDest); 4089 // Check getNumHandlers(). 4090 EXPECT_EQ(CS0->getNumHandlers(), LLVMCS0->getNumHandlers()); 4091 EXPECT_EQ(CS1->getNumHandlers(), LLVMCS1->getNumHandlers()); 4092 // Check handler_begin(), handler_end(). 4093 auto It = CS0->handler_begin(); 4094 EXPECT_EQ(*It++, Handler0); 4095 EXPECT_EQ(*It++, Handler1); 4096 EXPECT_EQ(It, CS0->handler_end()); 4097 // Check handlers(). 4098 SmallVector<sandboxir::BasicBlock *, 2> Handlers; 4099 for (sandboxir::BasicBlock *Handler : CS0->handlers()) 4100 Handlers.push_back(Handler); 4101 EXPECT_EQ(Handlers.size(), 2u); 4102 EXPECT_EQ(Handlers[0], Handler0); 4103 EXPECT_EQ(Handlers[1], Handler1); 4104 // Check addHandler(). 4105 CS0->addHandler(BB0); 4106 EXPECT_EQ(CS0->getNumHandlers(), 3u); 4107 EXPECT_EQ(*std::next(CS0->handler_begin(), 2), BB0); 4108 // Check getNumSuccessors(). 4109 EXPECT_EQ(CS0->getNumSuccessors(), LLVMCS0->getNumSuccessors()); 4110 EXPECT_EQ(CS1->getNumSuccessors(), LLVMCS1->getNumSuccessors()); 4111 // Check getSuccessor(). 4112 for (auto SuccIdx : seq<unsigned>(0, CS0->getNumSuccessors())) 4113 EXPECT_EQ(CS0->getSuccessor(SuccIdx), 4114 Ctx.getValue(LLVMCS0->getSuccessor(SuccIdx))); 4115 // Check setSuccessor(). 4116 auto *OrigSuccessor = CS0->getSuccessor(0); 4117 auto *NewSuccessor = BB0; 4118 EXPECT_NE(NewSuccessor, OrigSuccessor); 4119 CS0->setSuccessor(0, NewSuccessor); 4120 EXPECT_EQ(CS0->getSuccessor(0), NewSuccessor); 4121 CS0->setSuccessor(0, OrigSuccessor); 4122 EXPECT_EQ(CS0->getSuccessor(0), OrigSuccessor); 4123 // Check create(). 4124 CS1->eraseFromParent(); 4125 auto *NewCSI = sandboxir::CatchSwitchInst::create( 4126 CS0, Cleanup, 2, BB1->begin(), Ctx, "NewCSI"); 4127 EXPECT_TRUE(isa<sandboxir::CatchSwitchInst>(NewCSI)); 4128 EXPECT_EQ(NewCSI->getParentPad(), CS0); 4129 } 4130 4131 TEST_F(SandboxIRTest, ResumeInst) { 4132 parseIR(C, R"IR( 4133 define void @foo() { 4134 entry: 4135 invoke void @foo() 4136 to label %bb unwind label %unwind 4137 bb: 4138 ret void 4139 unwind: 4140 %lpad = landingpad { ptr, i32 } 4141 cleanup 4142 resume { ptr, i32 } %lpad 4143 } 4144 )IR"); 4145 Function &LLVMF = *M->getFunction("foo"); 4146 auto *LLVMUnwindBB = getBasicBlockByName(LLVMF, "unwind"); 4147 auto LLVMIt = LLVMUnwindBB->begin(); 4148 [[maybe_unused]] auto *LLVMLPad = cast<llvm::LandingPadInst>(&*LLVMIt++); 4149 auto *LLVMResume = cast<llvm::ResumeInst>(&*LLVMIt++); 4150 4151 sandboxir::Context Ctx(C); 4152 [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF); 4153 auto *UnwindBB = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMUnwindBB)); 4154 auto It = UnwindBB->begin(); 4155 auto *LPad = cast<sandboxir::LandingPadInst>(&*It++); 4156 auto *Resume = cast<sandboxir::ResumeInst>(&*It++); 4157 // Check getValue(). 4158 EXPECT_EQ(Resume->getValue(), LPad); 4159 EXPECT_EQ(Resume->getValue(), Ctx.getValue(LLVMResume->getValue())); 4160 // Check getNumSuccessors(). 4161 EXPECT_EQ(Resume->getNumSuccessors(), LLVMResume->getNumSuccessors()); 4162 // Check create(). 4163 auto *NewResume = sandboxir::ResumeInst::create(LPad, UnwindBB->end(), Ctx); 4164 EXPECT_EQ(NewResume->getValue(), LPad); 4165 EXPECT_EQ(NewResume->getParent(), UnwindBB); 4166 EXPECT_EQ(NewResume->getNextNode(), nullptr); 4167 } 4168 4169 TEST_F(SandboxIRTest, SwitchInst) { 4170 parseIR(C, R"IR( 4171 define void @foo(i32 %cond0, i32 %cond1) { 4172 entry: 4173 switch i32 %cond0, label %default [ i32 0, label %bb0 4174 i32 1, label %bb1 ] 4175 bb0: 4176 ret void 4177 bb1: 4178 ret void 4179 default: 4180 ret void 4181 } 4182 )IR"); 4183 Function &LLVMF = *M->getFunction("foo"); 4184 auto *LLVMEntry = getBasicBlockByName(LLVMF, "entry"); 4185 auto *LLVMSwitch = cast<llvm::SwitchInst>(&*LLVMEntry->begin()); 4186 4187 sandboxir::Context Ctx(C); 4188 auto &F = *Ctx.createFunction(&LLVMF); 4189 auto *Cond1 = F.getArg(1); 4190 auto *Entry = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMEntry)); 4191 auto *Switch = cast<sandboxir::SwitchInst>(&*Entry->begin()); 4192 auto *BB0 = cast<sandboxir::BasicBlock>( 4193 Ctx.getValue(getBasicBlockByName(LLVMF, "bb0"))); 4194 auto *BB1 = cast<sandboxir::BasicBlock>( 4195 Ctx.getValue(getBasicBlockByName(LLVMF, "bb1"))); 4196 auto *Default = cast<sandboxir::BasicBlock>( 4197 Ctx.getValue(getBasicBlockByName(LLVMF, "default"))); 4198 4199 // Check getCondition(). 4200 EXPECT_EQ(Switch->getCondition(), Ctx.getValue(LLVMSwitch->getCondition())); 4201 // Check setCondition(). 4202 auto *OrigCond = Switch->getCondition(); 4203 auto *NewCond = Cond1; 4204 EXPECT_NE(NewCond, OrigCond); 4205 Switch->setCondition(NewCond); 4206 EXPECT_EQ(Switch->getCondition(), NewCond); 4207 Switch->setCondition(OrigCond); 4208 EXPECT_EQ(Switch->getCondition(), OrigCond); 4209 // Check getDefaultDest(). 4210 EXPECT_EQ(Switch->getDefaultDest(), 4211 Ctx.getValue(LLVMSwitch->getDefaultDest())); 4212 EXPECT_EQ(Switch->getDefaultDest(), Default); 4213 // Check defaultDestUndefined(). 4214 EXPECT_EQ(Switch->defaultDestUndefined(), LLVMSwitch->defaultDestUndefined()); 4215 // Check setDefaultDest(). 4216 auto *OrigDefaultDest = Switch->getDefaultDest(); 4217 auto *NewDefaultDest = Entry; 4218 EXPECT_NE(NewDefaultDest, OrigDefaultDest); 4219 Switch->setDefaultDest(NewDefaultDest); 4220 EXPECT_EQ(Switch->getDefaultDest(), NewDefaultDest); 4221 Switch->setDefaultDest(OrigDefaultDest); 4222 EXPECT_EQ(Switch->getDefaultDest(), OrigDefaultDest); 4223 // Check getNumCases(). 4224 EXPECT_EQ(Switch->getNumCases(), LLVMSwitch->getNumCases()); 4225 // Check getNumSuccessors(). 4226 EXPECT_EQ(Switch->getNumSuccessors(), LLVMSwitch->getNumSuccessors()); 4227 // Check getSuccessor(). 4228 for (auto SuccIdx : seq<unsigned>(0, Switch->getNumSuccessors())) 4229 EXPECT_EQ(Switch->getSuccessor(SuccIdx), 4230 Ctx.getValue(LLVMSwitch->getSuccessor(SuccIdx))); 4231 // Check setSuccessor(). 4232 auto *OrigSucc = Switch->getSuccessor(0); 4233 auto *NewSucc = Entry; 4234 EXPECT_NE(NewSucc, OrigSucc); 4235 Switch->setSuccessor(0, NewSucc); 4236 EXPECT_EQ(Switch->getSuccessor(0), NewSucc); 4237 Switch->setSuccessor(0, OrigSucc); 4238 EXPECT_EQ(Switch->getSuccessor(0), OrigSucc); 4239 // Check case_begin(), case_end(), CaseIt. 4240 auto *Zero = sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 0); 4241 auto *One = sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 1); 4242 auto CaseIt = Switch->case_begin(); 4243 { 4244 sandboxir::SwitchInst::CaseHandle Case = *CaseIt++; 4245 EXPECT_EQ(Case.getCaseValue(), Zero); 4246 EXPECT_EQ(Case.getCaseSuccessor(), BB0); 4247 EXPECT_EQ(Case.getCaseIndex(), 0u); 4248 EXPECT_EQ(Case.getSuccessorIndex(), 1u); 4249 } 4250 { 4251 sandboxir::SwitchInst::CaseHandle Case = *CaseIt++; 4252 EXPECT_EQ(Case.getCaseValue(), One); 4253 EXPECT_EQ(Case.getCaseSuccessor(), BB1); 4254 EXPECT_EQ(Case.getCaseIndex(), 1u); 4255 EXPECT_EQ(Case.getSuccessorIndex(), 2u); 4256 } 4257 EXPECT_EQ(CaseIt, Switch->case_end()); 4258 // Check cases(). 4259 unsigned CntCase = 0; 4260 for (auto &Case : Switch->cases()) { 4261 EXPECT_EQ(Case.getCaseIndex(), CntCase); 4262 ++CntCase; 4263 } 4264 EXPECT_EQ(CntCase, 2u); 4265 // Check case_default(). 4266 auto CaseDefault = *Switch->case_default(); 4267 EXPECT_EQ(CaseDefault.getCaseSuccessor(), Default); 4268 EXPECT_EQ(CaseDefault.getCaseIndex(), 4269 sandboxir::SwitchInst::DefaultPseudoIndex); 4270 // Check findCaseValue(). 4271 EXPECT_EQ(Switch->findCaseValue(Zero)->getCaseIndex(), 0u); 4272 EXPECT_EQ(Switch->findCaseValue(One)->getCaseIndex(), 1u); 4273 // Check findCaseDest(). 4274 EXPECT_EQ(Switch->findCaseDest(BB0), Zero); 4275 EXPECT_EQ(Switch->findCaseDest(BB1), One); 4276 EXPECT_EQ(Switch->findCaseDest(Entry), nullptr); 4277 // Check addCase(). 4278 auto *Two = sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 2); 4279 Switch->addCase(Two, Entry); 4280 auto CaseTwoIt = Switch->findCaseValue(Two); 4281 auto CaseTwo = *CaseTwoIt; 4282 EXPECT_EQ(CaseTwo.getCaseValue(), Two); 4283 EXPECT_EQ(CaseTwo.getCaseSuccessor(), Entry); 4284 EXPECT_EQ(Switch->getNumCases(), 3u); 4285 // Check removeCase(). 4286 auto RemovedIt = Switch->removeCase(CaseTwoIt); 4287 EXPECT_EQ(RemovedIt, Switch->case_end()); 4288 EXPECT_EQ(Switch->getNumCases(), 2u); 4289 // Check create(). 4290 auto NewSwitch = sandboxir::SwitchInst::create( 4291 Cond1, Default, 1, Default->begin(), Ctx, "NewSwitch"); 4292 EXPECT_TRUE(isa<sandboxir::SwitchInst>(NewSwitch)); 4293 EXPECT_EQ(NewSwitch->getCondition(), Cond1); 4294 EXPECT_EQ(NewSwitch->getDefaultDest(), Default); 4295 } 4296 4297 TEST_F(SandboxIRTest, UnaryOperator) { 4298 parseIR(C, R"IR( 4299 define void @foo(float %arg0) { 4300 %fneg = fneg float %arg0 4301 %copyfrom = fadd reassoc float %arg0, 42.0 4302 ret void 4303 } 4304 )IR"); 4305 Function &LLVMF = *M->getFunction("foo"); 4306 sandboxir::Context Ctx(C); 4307 4308 auto &F = *Ctx.createFunction(&LLVMF); 4309 auto *Arg0 = F.getArg(0); 4310 auto *BB = &*F.begin(); 4311 auto It = BB->begin(); 4312 auto *I = cast<sandboxir::UnaryOperator>(&*It++); 4313 auto *CopyFrom = cast<sandboxir::BinaryOperator>(&*It++); 4314 auto *Ret = &*It++; 4315 EXPECT_EQ(I->getOpcode(), sandboxir::Instruction::Opcode::FNeg); 4316 EXPECT_EQ(I->getOperand(0), Arg0); 4317 4318 { 4319 // Check create() WhereIt, WhereBB. 4320 auto *NewI = 4321 cast<sandboxir::UnaryOperator>(sandboxir::UnaryOperator::create( 4322 sandboxir::Instruction::Opcode::FNeg, Arg0, Ret->getIterator(), Ctx, 4323 "New1")); 4324 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::FNeg); 4325 EXPECT_EQ(NewI->getOperand(0), Arg0); 4326 #ifndef NDEBUG 4327 EXPECT_EQ(NewI->getName(), "New1"); 4328 #endif // NDEBUG 4329 EXPECT_EQ(NewI->getNextNode(), Ret); 4330 } 4331 { 4332 // Check create() InsertBefore. 4333 auto *NewI = 4334 cast<sandboxir::UnaryOperator>(sandboxir::UnaryOperator::create( 4335 sandboxir::Instruction::Opcode::FNeg, Arg0, Ret->getIterator(), Ctx, 4336 "New2")); 4337 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::FNeg); 4338 EXPECT_EQ(NewI->getOperand(0), Arg0); 4339 #ifndef NDEBUG 4340 EXPECT_EQ(NewI->getName(), "New2"); 4341 #endif // NDEBUG 4342 EXPECT_EQ(NewI->getNextNode(), Ret); 4343 } 4344 { 4345 // Check create() InsertAtEnd. 4346 auto *NewI = 4347 cast<sandboxir::UnaryOperator>(sandboxir::UnaryOperator::create( 4348 sandboxir::Instruction::Opcode::FNeg, Arg0, BB, Ctx, "New3")); 4349 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::FNeg); 4350 EXPECT_EQ(NewI->getOperand(0), Arg0); 4351 #ifndef NDEBUG 4352 EXPECT_EQ(NewI->getName(), "New3"); 4353 #endif // NDEBUG 4354 EXPECT_EQ(NewI->getParent(), BB); 4355 EXPECT_EQ(NewI->getNextNode(), nullptr); 4356 } 4357 { 4358 // Check create() when it gets folded. 4359 auto *FortyTwo = CopyFrom->getOperand(1); 4360 auto *NewV = sandboxir::UnaryOperator::create( 4361 sandboxir::Instruction::Opcode::FNeg, FortyTwo, Ret->getIterator(), Ctx, 4362 "Folded"); 4363 EXPECT_TRUE(isa<sandboxir::Constant>(NewV)); 4364 } 4365 4366 { 4367 // Check createWithCopiedFlags() WhereIt, WhereBB. 4368 auto *NewI = cast<sandboxir::UnaryOperator>( 4369 sandboxir::UnaryOperator::createWithCopiedFlags( 4370 sandboxir::Instruction::Opcode::FNeg, Arg0, CopyFrom, 4371 Ret->getIterator(), Ctx, "NewCopyFrom1")); 4372 EXPECT_EQ(NewI->hasAllowReassoc(), CopyFrom->hasAllowReassoc()); 4373 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::FNeg); 4374 EXPECT_EQ(NewI->getOperand(0), Arg0); 4375 #ifndef NDEBUG 4376 EXPECT_EQ(NewI->getName(), "NewCopyFrom1"); 4377 #endif // NDEBUG 4378 EXPECT_EQ(NewI->getNextNode(), Ret); 4379 } 4380 { 4381 // Check createWithCopiedFlags() InsertBefore, 4382 auto *NewI = cast<sandboxir::UnaryOperator>( 4383 sandboxir::UnaryOperator::createWithCopiedFlags( 4384 sandboxir::Instruction::Opcode::FNeg, Arg0, CopyFrom, 4385 Ret->getIterator(), Ctx, "NewCopyFrom2")); 4386 EXPECT_EQ(NewI->hasAllowReassoc(), CopyFrom->hasAllowReassoc()); 4387 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::FNeg); 4388 EXPECT_EQ(NewI->getOperand(0), Arg0); 4389 #ifndef NDEBUG 4390 EXPECT_EQ(NewI->getName(), "NewCopyFrom2"); 4391 #endif // NDEBUG 4392 EXPECT_EQ(NewI->getNextNode(), Ret); 4393 } 4394 { 4395 // Check createWithCopiedFlags() InsertAtEnd, 4396 auto *NewI = cast<sandboxir::UnaryOperator>( 4397 sandboxir::UnaryOperator::createWithCopiedFlags( 4398 sandboxir::Instruction::Opcode::FNeg, Arg0, CopyFrom, BB, Ctx, 4399 "NewCopyFrom3")); 4400 EXPECT_EQ(NewI->hasAllowReassoc(), CopyFrom->hasAllowReassoc()); 4401 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::FNeg); 4402 EXPECT_EQ(NewI->getOperand(0), Arg0); 4403 #ifndef NDEBUG 4404 EXPECT_EQ(NewI->getName(), "NewCopyFrom3"); 4405 #endif // NDEBUG 4406 EXPECT_EQ(NewI->getParent(), BB); 4407 EXPECT_EQ(NewI->getNextNode(), nullptr); 4408 } 4409 { 4410 // Check createWithCopiedFlags() when it gets folded. 4411 auto *FortyTwo = CopyFrom->getOperand(1); 4412 auto *NewV = sandboxir::UnaryOperator::createWithCopiedFlags( 4413 sandboxir::Instruction::Opcode::FNeg, FortyTwo, CopyFrom, BB, Ctx, 4414 "Folded"); 4415 EXPECT_TRUE(isa<sandboxir::Constant>(NewV)); 4416 } 4417 } 4418 4419 TEST_F(SandboxIRTest, BinaryOperator) { 4420 parseIR(C, R"IR( 4421 define void @foo(i8 %arg0, i8 %arg1, float %farg0, float %farg1) { 4422 %add = add i8 %arg0, %arg1 4423 %fadd = fadd float %farg0, %farg1 4424 %sub = sub i8 %arg0, %arg1 4425 %fsub = fsub float %farg0, %farg1 4426 %mul = mul i8 %arg0, %arg1 4427 %fmul = fmul float %farg0, %farg1 4428 %udiv = udiv i8 %arg0, %arg1 4429 %sdiv = sdiv i8 %arg0, %arg1 4430 %fdiv = fdiv float %farg0, %farg1 4431 %urem = urem i8 %arg0, %arg1 4432 %srem = srem i8 %arg0, %arg1 4433 %frem = frem float %farg0, %farg1 4434 %shl = shl i8 %arg0, %arg1 4435 %lshr = lshr i8 %arg0, %arg1 4436 %ashr = ashr i8 %arg0, %arg1 4437 %and = and i8 %arg0, %arg1 4438 %or = or i8 %arg0, %arg1 4439 %xor = xor i8 %arg0, %arg1 4440 4441 %copyfrom = add nsw i8 %arg0, %arg1 4442 ret void 4443 } 4444 )IR"); 4445 Function &LLVMF = *M->getFunction("foo"); 4446 sandboxir::Context Ctx(C); 4447 4448 auto &F = *Ctx.createFunction(&LLVMF); 4449 auto *Arg0 = F.getArg(0); 4450 auto *Arg1 = F.getArg(1); 4451 auto *FArg0 = F.getArg(2); 4452 auto *FArg1 = F.getArg(3); 4453 auto *BB = &*F.begin(); 4454 auto It = BB->begin(); 4455 4456 #define CHECK_IBINOP(OPCODE) \ 4457 { \ 4458 auto *I = cast<sandboxir::BinaryOperator>(&*It++); \ 4459 EXPECT_EQ(I->getOpcode(), OPCODE); \ 4460 EXPECT_EQ(I->getOperand(0), Arg0); \ 4461 EXPECT_EQ(I->getOperand(1), Arg1); \ 4462 } 4463 #define CHECK_FBINOP(OPCODE) \ 4464 { \ 4465 auto *I = cast<sandboxir::BinaryOperator>(&*It++); \ 4466 EXPECT_EQ(I->getOpcode(), OPCODE); \ 4467 EXPECT_EQ(I->getOperand(0), FArg0); \ 4468 EXPECT_EQ(I->getOperand(1), FArg1); \ 4469 } 4470 4471 CHECK_IBINOP(sandboxir::Instruction::Opcode::Add); 4472 CHECK_FBINOP(sandboxir::Instruction::Opcode::FAdd); 4473 CHECK_IBINOP(sandboxir::Instruction::Opcode::Sub); 4474 CHECK_FBINOP(sandboxir::Instruction::Opcode::FSub); 4475 CHECK_IBINOP(sandboxir::Instruction::Opcode::Mul); 4476 CHECK_FBINOP(sandboxir::Instruction::Opcode::FMul); 4477 CHECK_IBINOP(sandboxir::Instruction::Opcode::UDiv); 4478 CHECK_IBINOP(sandboxir::Instruction::Opcode::SDiv); 4479 CHECK_FBINOP(sandboxir::Instruction::Opcode::FDiv); 4480 CHECK_IBINOP(sandboxir::Instruction::Opcode::URem); 4481 CHECK_IBINOP(sandboxir::Instruction::Opcode::SRem); 4482 CHECK_FBINOP(sandboxir::Instruction::Opcode::FRem); 4483 CHECK_IBINOP(sandboxir::Instruction::Opcode::Shl); 4484 CHECK_IBINOP(sandboxir::Instruction::Opcode::LShr); 4485 CHECK_IBINOP(sandboxir::Instruction::Opcode::AShr); 4486 CHECK_IBINOP(sandboxir::Instruction::Opcode::And); 4487 CHECK_IBINOP(sandboxir::Instruction::Opcode::Or); 4488 CHECK_IBINOP(sandboxir::Instruction::Opcode::Xor); 4489 4490 auto *CopyFrom = cast<sandboxir::BinaryOperator>(&*It++); 4491 auto *Ret = cast<sandboxir::ReturnInst>(&*It++); 4492 4493 { 4494 // Check create() WhereIt, WhereBB. 4495 auto *NewI = 4496 cast<sandboxir::BinaryOperator>(sandboxir::BinaryOperator::create( 4497 sandboxir::Instruction::Opcode::Add, Arg0, Arg1, Ret->getIterator(), 4498 Ctx, "New1")); 4499 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Add); 4500 EXPECT_EQ(NewI->getOperand(0), Arg0); 4501 EXPECT_EQ(NewI->getOperand(1), Arg1); 4502 #ifndef NDEBUG 4503 EXPECT_EQ(NewI->getName(), "New1"); 4504 #endif // NDEBUG 4505 EXPECT_EQ(NewI->getNextNode(), Ret); 4506 } 4507 { 4508 // Check create() InsertBefore. 4509 auto *NewI = 4510 cast<sandboxir::BinaryOperator>(sandboxir::BinaryOperator::create( 4511 sandboxir::Instruction::Opcode::Add, Arg0, Arg1, Ret->getIterator(), 4512 Ctx, "New2")); 4513 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Add); 4514 EXPECT_EQ(NewI->getOperand(0), Arg0); 4515 EXPECT_EQ(NewI->getOperand(1), Arg1); 4516 #ifndef NDEBUG 4517 EXPECT_EQ(NewI->getName(), "New2"); 4518 #endif // NDEBUG 4519 EXPECT_EQ(NewI->getNextNode(), Ret); 4520 } 4521 { 4522 // Check create() InsertAtEnd. 4523 auto *NewI = 4524 cast<sandboxir::BinaryOperator>(sandboxir::BinaryOperator::create( 4525 sandboxir::Instruction::Opcode::Add, Arg0, Arg1, 4526 /*InsertAtEnd=*/BB, Ctx, "New3")); 4527 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Add); 4528 EXPECT_EQ(NewI->getOperand(0), Arg0); 4529 EXPECT_EQ(NewI->getOperand(1), Arg1); 4530 #ifndef NDEBUG 4531 EXPECT_EQ(NewI->getName(), "New3"); 4532 #endif // NDEBUG 4533 EXPECT_EQ(NewI->getNextNode(), nullptr); 4534 EXPECT_EQ(NewI->getParent(), BB); 4535 } 4536 { 4537 // Check create() when it gets folded. 4538 auto *FortyTwo = 4539 sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 42); 4540 auto *NewV = sandboxir::BinaryOperator::create( 4541 sandboxir::Instruction::Opcode::Add, FortyTwo, FortyTwo, 4542 Ret->getIterator(), Ctx, "Folded"); 4543 EXPECT_TRUE(isa<sandboxir::Constant>(NewV)); 4544 } 4545 4546 { 4547 // Check createWithCopiedFlags() WhereIt, WhereBB. 4548 auto *NewI = cast<sandboxir::BinaryOperator>( 4549 sandboxir::BinaryOperator::createWithCopiedFlags( 4550 sandboxir::Instruction::Opcode::Add, Arg0, Arg1, CopyFrom, 4551 Ret->getIterator(), Ctx, "NewNSW1")); 4552 EXPECT_EQ(NewI->hasNoSignedWrap(), CopyFrom->hasNoSignedWrap()); 4553 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Add); 4554 EXPECT_EQ(NewI->getOperand(0), Arg0); 4555 EXPECT_EQ(NewI->getOperand(1), Arg1); 4556 #ifndef NDEBUG 4557 EXPECT_EQ(NewI->getName(), "NewNSW1"); 4558 #endif // NDEBUG 4559 EXPECT_EQ(NewI->getNextNode(), Ret); 4560 } 4561 { 4562 // Check createWithCopiedFlags() InsertBefore. 4563 auto *NewI = cast<sandboxir::BinaryOperator>( 4564 sandboxir::BinaryOperator::createWithCopiedFlags( 4565 sandboxir::Instruction::Opcode::Add, Arg0, Arg1, CopyFrom, 4566 Ret->getIterator(), Ctx, "NewNSW2")); 4567 EXPECT_EQ(NewI->hasNoSignedWrap(), CopyFrom->hasNoSignedWrap()); 4568 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Add); 4569 EXPECT_EQ(NewI->getOperand(0), Arg0); 4570 EXPECT_EQ(NewI->getOperand(1), Arg1); 4571 #ifndef NDEBUG 4572 EXPECT_EQ(NewI->getName(), "NewNSW2"); 4573 #endif // NDEBUG 4574 EXPECT_EQ(NewI->getNextNode(), Ret); 4575 } 4576 { 4577 // Check createWithCopiedFlags() InsertAtEnd. 4578 auto *NewI = cast<sandboxir::BinaryOperator>( 4579 sandboxir::BinaryOperator::createWithCopiedFlags( 4580 sandboxir::Instruction::Opcode::Add, Arg0, Arg1, CopyFrom, BB, Ctx, 4581 "NewNSW3")); 4582 EXPECT_EQ(NewI->hasNoSignedWrap(), CopyFrom->hasNoSignedWrap()); 4583 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Add); 4584 EXPECT_EQ(NewI->getOperand(0), Arg0); 4585 EXPECT_EQ(NewI->getOperand(1), Arg1); 4586 #ifndef NDEBUG 4587 EXPECT_EQ(NewI->getName(), "NewNSW3"); 4588 #endif // NDEBUG 4589 EXPECT_EQ(NewI->getParent(), BB); 4590 EXPECT_EQ(NewI->getNextNode(), nullptr); 4591 } 4592 { 4593 // Check createWithCopiedFlags() when it gets folded. 4594 auto *FortyTwo = 4595 sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 42); 4596 auto *NewV = sandboxir::BinaryOperator::createWithCopiedFlags( 4597 sandboxir::Instruction::Opcode::Add, FortyTwo, FortyTwo, CopyFrom, 4598 Ret->getIterator(), Ctx, "Folded"); 4599 EXPECT_TRUE(isa<sandboxir::Constant>(NewV)); 4600 } 4601 } 4602 4603 TEST_F(SandboxIRTest, PossiblyDisjointInst) { 4604 parseIR(C, R"IR( 4605 define void @foo(i8 %arg0, i8 %arg1) { 4606 %or = or i8 %arg0, %arg1 4607 ret void 4608 } 4609 )IR"); 4610 Function &LLVMF = *M->getFunction("foo"); 4611 sandboxir::Context Ctx(C); 4612 4613 auto &F = *Ctx.createFunction(&LLVMF); 4614 auto *BB = &*F.begin(); 4615 auto It = BB->begin(); 4616 auto *PDI = cast<sandboxir::PossiblyDisjointInst>(&*It++); 4617 4618 // Check setIsDisjoint(), isDisjoint(). 4619 auto OrigIsDisjoint = PDI->isDisjoint(); 4620 auto NewIsDisjoint = true; 4621 EXPECT_NE(NewIsDisjoint, OrigIsDisjoint); 4622 PDI->setIsDisjoint(NewIsDisjoint); 4623 EXPECT_EQ(PDI->isDisjoint(), NewIsDisjoint); 4624 PDI->setIsDisjoint(OrigIsDisjoint); 4625 EXPECT_EQ(PDI->isDisjoint(), OrigIsDisjoint); 4626 } 4627 4628 TEST_F(SandboxIRTest, AtomicRMWInst) { 4629 parseIR(C, R"IR( 4630 define void @foo(ptr %ptr, i8 %arg) { 4631 %atomicrmw = atomicrmw add ptr %ptr, i8 %arg acquire, align 128 4632 ret void 4633 } 4634 )IR"); 4635 llvm::Function &LLVMF = *M->getFunction("foo"); 4636 llvm::BasicBlock *LLVMBB = &*LLVMF.begin(); 4637 auto LLVMIt = LLVMBB->begin(); 4638 auto *LLVMRMW = cast<llvm::AtomicRMWInst>(&*LLVMIt++); 4639 4640 sandboxir::Context Ctx(C); 4641 sandboxir::Function *F = Ctx.createFunction(&LLVMF); 4642 auto *Ptr = F->getArg(0); 4643 auto *Arg = F->getArg(1); 4644 auto *BB = &*F->begin(); 4645 auto It = BB->begin(); 4646 auto *RMW = cast<sandboxir::AtomicRMWInst>(&*It++); 4647 auto *Ret = cast<sandboxir::ReturnInst>(&*It++); 4648 4649 // Check getOperationName(). 4650 EXPECT_EQ( 4651 sandboxir::AtomicRMWInst::getOperationName( 4652 sandboxir::AtomicRMWInst::BinOp::Add), 4653 llvm::AtomicRMWInst::getOperationName(llvm::AtomicRMWInst::BinOp::Add)); 4654 // Check isFPOperation(). 4655 EXPECT_EQ( 4656 sandboxir::AtomicRMWInst::isFPOperation( 4657 sandboxir::AtomicRMWInst::BinOp::Add), 4658 llvm::AtomicRMWInst::isFPOperation(llvm::AtomicRMWInst::BinOp::Add)); 4659 EXPECT_FALSE(sandboxir::AtomicRMWInst::isFPOperation( 4660 sandboxir::AtomicRMWInst::BinOp::Add)); 4661 EXPECT_TRUE(sandboxir::AtomicRMWInst::isFPOperation( 4662 sandboxir::AtomicRMWInst::BinOp::FAdd)); 4663 // Check setOperation(), getOperation(). 4664 EXPECT_EQ(RMW->getOperation(), LLVMRMW->getOperation()); 4665 RMW->setOperation(sandboxir::AtomicRMWInst::BinOp::Sub); 4666 EXPECT_EQ(RMW->getOperation(), sandboxir::AtomicRMWInst::BinOp::Sub); 4667 RMW->setOperation(sandboxir::AtomicRMWInst::BinOp::Add); 4668 // Check getAlign(). 4669 EXPECT_EQ(RMW->getAlign(), LLVMRMW->getAlign()); 4670 auto OrigAlign = RMW->getAlign(); 4671 Align NewAlign(256); 4672 EXPECT_NE(NewAlign, OrigAlign); 4673 RMW->setAlignment(NewAlign); 4674 EXPECT_EQ(RMW->getAlign(), NewAlign); 4675 RMW->setAlignment(OrigAlign); 4676 EXPECT_EQ(RMW->getAlign(), OrigAlign); 4677 // Check isVolatile(), setVolatile(). 4678 EXPECT_EQ(RMW->isVolatile(), LLVMRMW->isVolatile()); 4679 bool OrigV = RMW->isVolatile(); 4680 bool NewV = true; 4681 EXPECT_NE(NewV, OrigV); 4682 RMW->setVolatile(NewV); 4683 EXPECT_EQ(RMW->isVolatile(), NewV); 4684 RMW->setVolatile(OrigV); 4685 EXPECT_EQ(RMW->isVolatile(), OrigV); 4686 // Check getOrdering(), setOrdering(). 4687 EXPECT_EQ(RMW->getOrdering(), LLVMRMW->getOrdering()); 4688 auto OldOrdering = RMW->getOrdering(); 4689 auto NewOrdering = AtomicOrdering::Monotonic; 4690 EXPECT_NE(NewOrdering, OldOrdering); 4691 RMW->setOrdering(NewOrdering); 4692 EXPECT_EQ(RMW->getOrdering(), NewOrdering); 4693 RMW->setOrdering(OldOrdering); 4694 EXPECT_EQ(RMW->getOrdering(), OldOrdering); 4695 // Check getSyncScopeID(), setSyncScopeID(). 4696 EXPECT_EQ(RMW->getSyncScopeID(), LLVMRMW->getSyncScopeID()); 4697 auto OrigSSID = RMW->getSyncScopeID(); 4698 SyncScope::ID NewSSID = SyncScope::SingleThread; 4699 EXPECT_NE(NewSSID, OrigSSID); 4700 RMW->setSyncScopeID(NewSSID); 4701 EXPECT_EQ(RMW->getSyncScopeID(), NewSSID); 4702 RMW->setSyncScopeID(OrigSSID); 4703 EXPECT_EQ(RMW->getSyncScopeID(), OrigSSID); 4704 // Check getPointerOperand(). 4705 EXPECT_EQ(RMW->getPointerOperand(), 4706 Ctx.getValue(LLVMRMW->getPointerOperand())); 4707 // Check getValOperand(). 4708 EXPECT_EQ(RMW->getValOperand(), Ctx.getValue(LLVMRMW->getValOperand())); 4709 // Check getPointerAddressSpace(). 4710 EXPECT_EQ(RMW->getPointerAddressSpace(), LLVMRMW->getPointerAddressSpace()); 4711 // Check isFloatingPointOperation(). 4712 EXPECT_EQ(RMW->isFloatingPointOperation(), 4713 LLVMRMW->isFloatingPointOperation()); 4714 4715 Align Align(1024); 4716 auto Ordering = AtomicOrdering::Acquire; 4717 auto SSID = SyncScope::System; 4718 { 4719 // Check create() WhereIt, WhereBB. 4720 auto *NewI = 4721 cast<sandboxir::AtomicRMWInst>(sandboxir::AtomicRMWInst::create( 4722 sandboxir::AtomicRMWInst::BinOp::Sub, Ptr, Arg, Align, Ordering, 4723 Ret->getIterator(), Ctx, SSID, "NewAtomicRMW1")); 4724 // Check getOpcode(). 4725 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::AtomicRMW); 4726 // Check getAlign(). 4727 EXPECT_EQ(NewI->getAlign(), Align); 4728 // Check getSuccessOrdering(). 4729 EXPECT_EQ(NewI->getOrdering(), Ordering); 4730 // Check instr position. 4731 EXPECT_EQ(NewI->getNextNode(), Ret); 4732 // Check getPointerOperand(). 4733 EXPECT_EQ(NewI->getPointerOperand(), Ptr); 4734 // Check getValOperand(). 4735 EXPECT_EQ(NewI->getValOperand(), Arg); 4736 #ifndef NDEBUG 4737 // Check getName(). 4738 EXPECT_EQ(NewI->getName(), "NewAtomicRMW1"); 4739 #endif // NDEBUG 4740 } 4741 { 4742 // Check create() InsertBefore. 4743 auto *NewI = 4744 cast<sandboxir::AtomicRMWInst>(sandboxir::AtomicRMWInst::create( 4745 sandboxir::AtomicRMWInst::BinOp::Sub, Ptr, Arg, Align, Ordering, 4746 Ret->getIterator(), Ctx, SSID, "NewAtomicRMW2")); 4747 // Check getOpcode(). 4748 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::AtomicRMW); 4749 // Check getAlign(). 4750 EXPECT_EQ(NewI->getAlign(), Align); 4751 // Check getSuccessOrdering(). 4752 EXPECT_EQ(NewI->getOrdering(), Ordering); 4753 // Check instr position. 4754 EXPECT_EQ(NewI->getNextNode(), Ret); 4755 // Check getPointerOperand(). 4756 EXPECT_EQ(NewI->getPointerOperand(), Ptr); 4757 // Check getValOperand(). 4758 EXPECT_EQ(NewI->getValOperand(), Arg); 4759 #ifndef NDEBUG 4760 // Check getName(). 4761 EXPECT_EQ(NewI->getName(), "NewAtomicRMW2"); 4762 #endif // NDEBUG 4763 } 4764 { 4765 // Check create() InsertAtEnd. 4766 auto *NewI = 4767 cast<sandboxir::AtomicRMWInst>(sandboxir::AtomicRMWInst::create( 4768 sandboxir::AtomicRMWInst::BinOp::Sub, Ptr, Arg, Align, Ordering, BB, 4769 Ctx, SSID, "NewAtomicRMW3")); 4770 // Check getOpcode(). 4771 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::AtomicRMW); 4772 // Check getAlign(). 4773 EXPECT_EQ(NewI->getAlign(), Align); 4774 // Check getSuccessOrdering(). 4775 EXPECT_EQ(NewI->getOrdering(), Ordering); 4776 // Check instr position. 4777 EXPECT_EQ(NewI->getParent(), BB); 4778 EXPECT_EQ(NewI->getNextNode(), nullptr); 4779 // Check getPointerOperand(). 4780 EXPECT_EQ(NewI->getPointerOperand(), Ptr); 4781 // Check getValOperand(). 4782 EXPECT_EQ(NewI->getValOperand(), Arg); 4783 #ifndef NDEBUG 4784 // Check getName(). 4785 EXPECT_EQ(NewI->getName(), "NewAtomicRMW3"); 4786 #endif // NDEBUG 4787 } 4788 } 4789 4790 TEST_F(SandboxIRTest, AtomicCmpXchgInst) { 4791 parseIR(C, R"IR( 4792 define void @foo(ptr %ptr, i8 %cmp, i8 %new) { 4793 %cmpxchg = cmpxchg ptr %ptr, i8 %cmp, i8 %new monotonic monotonic, align 128 4794 ret void 4795 } 4796 )IR"); 4797 llvm::Function &LLVMF = *M->getFunction("foo"); 4798 llvm::BasicBlock *LLVMBB = &*LLVMF.begin(); 4799 auto LLVMIt = LLVMBB->begin(); 4800 auto *LLVMCmpXchg = cast<llvm::AtomicCmpXchgInst>(&*LLVMIt++); 4801 4802 sandboxir::Context Ctx(C); 4803 sandboxir::Function *F = Ctx.createFunction(&LLVMF); 4804 auto *Ptr = F->getArg(0); 4805 auto *Cmp = F->getArg(1); 4806 auto *New = F->getArg(2); 4807 auto *BB = &*F->begin(); 4808 auto It = BB->begin(); 4809 auto *CmpXchg = cast<sandboxir::AtomicCmpXchgInst>(&*It++); 4810 auto *Ret = cast<sandboxir::ReturnInst>(&*It++); 4811 4812 // Check getAlign(), setAlignment(). 4813 EXPECT_EQ(CmpXchg->getAlign(), LLVMCmpXchg->getAlign()); 4814 auto OrigAlign = CmpXchg->getAlign(); 4815 Align NewAlign(256); 4816 EXPECT_NE(NewAlign, OrigAlign); 4817 CmpXchg->setAlignment(NewAlign); 4818 EXPECT_EQ(CmpXchg->getAlign(), NewAlign); 4819 CmpXchg->setAlignment(OrigAlign); 4820 EXPECT_EQ(CmpXchg->getAlign(), OrigAlign); 4821 // Check isVolatile(), setVolatile(). 4822 EXPECT_EQ(CmpXchg->isVolatile(), LLVMCmpXchg->isVolatile()); 4823 bool OrigV = CmpXchg->isVolatile(); 4824 bool NewV = true; 4825 EXPECT_NE(NewV, OrigV); 4826 CmpXchg->setVolatile(NewV); 4827 EXPECT_EQ(CmpXchg->isVolatile(), NewV); 4828 CmpXchg->setVolatile(OrigV); 4829 EXPECT_EQ(CmpXchg->isVolatile(), OrigV); 4830 // Check isWeak(), setWeak(). 4831 EXPECT_EQ(CmpXchg->isWeak(), LLVMCmpXchg->isWeak()); 4832 bool OrigWeak = CmpXchg->isWeak(); 4833 bool NewWeak = true; 4834 EXPECT_NE(NewWeak, OrigWeak); 4835 CmpXchg->setWeak(NewWeak); 4836 EXPECT_EQ(CmpXchg->isWeak(), NewWeak); 4837 CmpXchg->setWeak(OrigWeak); 4838 EXPECT_EQ(CmpXchg->isWeak(), OrigWeak); 4839 // Check isValidSuccessOrdering(), isValidFailureOrdering(). 4840 SmallVector<AtomicOrdering> AllOrderings( 4841 {AtomicOrdering::NotAtomic, AtomicOrdering::Unordered, 4842 AtomicOrdering::Monotonic, AtomicOrdering::Acquire, 4843 AtomicOrdering::Release, AtomicOrdering::AcquireRelease, 4844 AtomicOrdering::SequentiallyConsistent}); 4845 for (auto Ordering : AllOrderings) { 4846 EXPECT_EQ(sandboxir::AtomicCmpXchgInst::isValidSuccessOrdering(Ordering), 4847 llvm::AtomicCmpXchgInst::isValidSuccessOrdering(Ordering)); 4848 EXPECT_EQ(sandboxir::AtomicCmpXchgInst::isValidFailureOrdering(Ordering), 4849 llvm::AtomicCmpXchgInst::isValidFailureOrdering(Ordering)); 4850 } 4851 // Check getSuccessOrdering(), setSuccessOrdering(). 4852 EXPECT_EQ(CmpXchg->getSuccessOrdering(), LLVMCmpXchg->getSuccessOrdering()); 4853 auto OldSuccOrdering = CmpXchg->getSuccessOrdering(); 4854 auto NewSuccOrdering = AtomicOrdering::Acquire; 4855 EXPECT_NE(NewSuccOrdering, OldSuccOrdering); 4856 CmpXchg->setSuccessOrdering(NewSuccOrdering); 4857 EXPECT_EQ(CmpXchg->getSuccessOrdering(), NewSuccOrdering); 4858 CmpXchg->setSuccessOrdering(OldSuccOrdering); 4859 EXPECT_EQ(CmpXchg->getSuccessOrdering(), OldSuccOrdering); 4860 // Check getFailureOrdering(), setFailureOrdering(). 4861 EXPECT_EQ(CmpXchg->getFailureOrdering(), LLVMCmpXchg->getFailureOrdering()); 4862 auto OldFailOrdering = CmpXchg->getFailureOrdering(); 4863 auto NewFailOrdering = AtomicOrdering::Acquire; 4864 EXPECT_NE(NewFailOrdering, OldFailOrdering); 4865 CmpXchg->setFailureOrdering(NewFailOrdering); 4866 EXPECT_EQ(CmpXchg->getFailureOrdering(), NewFailOrdering); 4867 CmpXchg->setFailureOrdering(OldFailOrdering); 4868 EXPECT_EQ(CmpXchg->getFailureOrdering(), OldFailOrdering); 4869 // Check getMergedOrdering(). 4870 EXPECT_EQ(CmpXchg->getMergedOrdering(), LLVMCmpXchg->getMergedOrdering()); 4871 // Check getSyncScopeID(), setSyncScopeID(). 4872 EXPECT_EQ(CmpXchg->getSyncScopeID(), LLVMCmpXchg->getSyncScopeID()); 4873 auto OrigSSID = CmpXchg->getSyncScopeID(); 4874 SyncScope::ID NewSSID = SyncScope::SingleThread; 4875 EXPECT_NE(NewSSID, OrigSSID); 4876 CmpXchg->setSyncScopeID(NewSSID); 4877 EXPECT_EQ(CmpXchg->getSyncScopeID(), NewSSID); 4878 CmpXchg->setSyncScopeID(OrigSSID); 4879 EXPECT_EQ(CmpXchg->getSyncScopeID(), OrigSSID); 4880 // Check getPointerOperand(). 4881 EXPECT_EQ(CmpXchg->getPointerOperand(), 4882 Ctx.getValue(LLVMCmpXchg->getPointerOperand())); 4883 // Check getCompareOperand(). 4884 EXPECT_EQ(CmpXchg->getCompareOperand(), 4885 Ctx.getValue(LLVMCmpXchg->getCompareOperand())); 4886 // Check getNewValOperand(). 4887 EXPECT_EQ(CmpXchg->getNewValOperand(), 4888 Ctx.getValue(LLVMCmpXchg->getNewValOperand())); 4889 // Check getPointerAddressSpace(). 4890 EXPECT_EQ(CmpXchg->getPointerAddressSpace(), 4891 LLVMCmpXchg->getPointerAddressSpace()); 4892 4893 Align Align(1024); 4894 auto SuccOrdering = AtomicOrdering::Acquire; 4895 auto FailOrdering = AtomicOrdering::Monotonic; 4896 auto SSID = SyncScope::System; 4897 { 4898 // Check create() WhereIt, WhereBB. 4899 auto *NewI = 4900 cast<sandboxir::AtomicCmpXchgInst>(sandboxir::AtomicCmpXchgInst::create( 4901 Ptr, Cmp, New, Align, SuccOrdering, FailOrdering, 4902 Ret->getIterator(), Ctx, SSID, "NewAtomicCmpXchg1")); 4903 // Check getOpcode(). 4904 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::AtomicCmpXchg); 4905 // Check getAlign(). 4906 EXPECT_EQ(NewI->getAlign(), Align); 4907 // Check getSuccessOrdering(). 4908 EXPECT_EQ(NewI->getSuccessOrdering(), SuccOrdering); 4909 // Check getFailureOrdering(). 4910 EXPECT_EQ(NewI->getFailureOrdering(), FailOrdering); 4911 // Check instr position. 4912 EXPECT_EQ(NewI->getNextNode(), Ret); 4913 // Check getPointerOperand(). 4914 EXPECT_EQ(NewI->getPointerOperand(), Ptr); 4915 // Check getCompareOperand(). 4916 EXPECT_EQ(NewI->getCompareOperand(), Cmp); 4917 // Check getNewValOperand(). 4918 EXPECT_EQ(NewI->getNewValOperand(), New); 4919 #ifndef NDEBUG 4920 // Check getName(). 4921 EXPECT_EQ(NewI->getName(), "NewAtomicCmpXchg1"); 4922 #endif // NDEBUG 4923 } 4924 { 4925 // Check create() InsertBefore. 4926 auto *NewI = 4927 cast<sandboxir::AtomicCmpXchgInst>(sandboxir::AtomicCmpXchgInst::create( 4928 Ptr, Cmp, New, Align, SuccOrdering, FailOrdering, 4929 Ret->getIterator(), Ctx, SSID, "NewAtomicCmpXchg2")); 4930 // Check getOpcode(). 4931 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::AtomicCmpXchg); 4932 // Check getAlign(). 4933 EXPECT_EQ(NewI->getAlign(), Align); 4934 // Check getSuccessOrdering(). 4935 EXPECT_EQ(NewI->getSuccessOrdering(), SuccOrdering); 4936 // Check getFailureOrdering(). 4937 EXPECT_EQ(NewI->getFailureOrdering(), FailOrdering); 4938 // Check instr position. 4939 EXPECT_EQ(NewI->getNextNode(), Ret); 4940 // Check getPointerOperand(). 4941 EXPECT_EQ(NewI->getPointerOperand(), Ptr); 4942 // Check getCompareOperand(). 4943 EXPECT_EQ(NewI->getCompareOperand(), Cmp); 4944 // Check getNewValOperand(). 4945 EXPECT_EQ(NewI->getNewValOperand(), New); 4946 #ifndef NDEBUG 4947 // Check getName(). 4948 EXPECT_EQ(NewI->getName(), "NewAtomicCmpXchg2"); 4949 #endif // NDEBUG 4950 } 4951 { 4952 // Check create() InsertAtEnd. 4953 auto *NewI = 4954 cast<sandboxir::AtomicCmpXchgInst>(sandboxir::AtomicCmpXchgInst::create( 4955 Ptr, Cmp, New, Align, SuccOrdering, FailOrdering, BB, Ctx, SSID, 4956 "NewAtomicCmpXchg3")); 4957 // Check getOpcode(). 4958 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::AtomicCmpXchg); 4959 // Check getAlign(). 4960 EXPECT_EQ(NewI->getAlign(), Align); 4961 // Check getSuccessOrdering(). 4962 EXPECT_EQ(NewI->getSuccessOrdering(), SuccOrdering); 4963 // Check getFailureOrdering(). 4964 EXPECT_EQ(NewI->getFailureOrdering(), FailOrdering); 4965 // Check instr position. 4966 EXPECT_EQ(NewI->getParent(), BB); 4967 EXPECT_EQ(NewI->getNextNode(), nullptr); 4968 // Check getPointerOperand(). 4969 EXPECT_EQ(NewI->getPointerOperand(), Ptr); 4970 // Check getCompareOperand(). 4971 EXPECT_EQ(NewI->getCompareOperand(), Cmp); 4972 // Check getNewValOperand(). 4973 EXPECT_EQ(NewI->getNewValOperand(), New); 4974 #ifndef NDEBUG 4975 // Check getName(). 4976 EXPECT_EQ(NewI->getName(), "NewAtomicCmpXchg3"); 4977 #endif // NDEBUG 4978 } 4979 } 4980 4981 TEST_F(SandboxIRTest, AllocaInst) { 4982 parseIR(C, R"IR( 4983 define void @foo() { 4984 %allocaScalar = alloca i32, align 1024 4985 %allocaArray = alloca i32, i32 42 4986 ret void 4987 } 4988 )IR"); 4989 const DataLayout &DL = M->getDataLayout(); 4990 llvm::Function &LLVMF = *M->getFunction("foo"); 4991 llvm::BasicBlock *LLVMBB = &*LLVMF.begin(); 4992 auto LLVMIt = LLVMBB->begin(); 4993 auto *LLVMAllocaScalar = cast<llvm::AllocaInst>(&*LLVMIt++); 4994 auto *LLVMAllocaArray = cast<llvm::AllocaInst>(&*LLVMIt++); 4995 4996 sandboxir::Context Ctx(C); 4997 sandboxir::Function *F = Ctx.createFunction(&LLVMF); 4998 auto *BB = &*F->begin(); 4999 auto It = BB->begin(); 5000 auto *AllocaScalar = cast<sandboxir::AllocaInst>(&*It++); 5001 auto *AllocaArray = cast<sandboxir::AllocaInst>(&*It++); 5002 auto *Ret = cast<sandboxir::ReturnInst>(&*It++); 5003 5004 // Check isArrayAllocation(). 5005 EXPECT_EQ(AllocaScalar->isArrayAllocation(), 5006 LLVMAllocaScalar->isArrayAllocation()); 5007 EXPECT_EQ(AllocaArray->isArrayAllocation(), 5008 LLVMAllocaArray->isArrayAllocation()); 5009 // Check getArraySize(). 5010 EXPECT_EQ(AllocaScalar->getArraySize(), 5011 Ctx.getValue(LLVMAllocaScalar->getArraySize())); 5012 EXPECT_EQ(AllocaArray->getArraySize(), 5013 Ctx.getValue(LLVMAllocaArray->getArraySize())); 5014 // Check getType(). 5015 EXPECT_EQ(AllocaScalar->getType(), Ctx.getType(LLVMAllocaScalar->getType())); 5016 EXPECT_EQ(AllocaArray->getType(), Ctx.getType(LLVMAllocaArray->getType())); 5017 // Check getAddressSpace(). 5018 EXPECT_EQ(AllocaScalar->getAddressSpace(), 5019 LLVMAllocaScalar->getAddressSpace()); 5020 EXPECT_EQ(AllocaArray->getAddressSpace(), LLVMAllocaArray->getAddressSpace()); 5021 // Check getAllocationSize(). 5022 EXPECT_EQ(AllocaScalar->getAllocationSize(DL), 5023 LLVMAllocaScalar->getAllocationSize(DL)); 5024 EXPECT_EQ(AllocaArray->getAllocationSize(DL), 5025 LLVMAllocaArray->getAllocationSize(DL)); 5026 // Check getAllocationSizeInBits(). 5027 EXPECT_EQ(AllocaScalar->getAllocationSizeInBits(DL), 5028 LLVMAllocaScalar->getAllocationSizeInBits(DL)); 5029 EXPECT_EQ(AllocaArray->getAllocationSizeInBits(DL), 5030 LLVMAllocaArray->getAllocationSizeInBits(DL)); 5031 // Check getAllocatedType(). 5032 EXPECT_EQ(AllocaScalar->getAllocatedType(), 5033 Ctx.getType(LLVMAllocaScalar->getAllocatedType())); 5034 EXPECT_EQ(AllocaArray->getAllocatedType(), 5035 Ctx.getType(LLVMAllocaArray->getAllocatedType())); 5036 // Check setAllocatedType(). 5037 auto *OrigType = AllocaScalar->getAllocatedType(); 5038 auto *NewType = sandboxir::PointerType::get(Ctx, 0); 5039 EXPECT_NE(NewType, OrigType); 5040 AllocaScalar->setAllocatedType(NewType); 5041 EXPECT_EQ(AllocaScalar->getAllocatedType(), NewType); 5042 AllocaScalar->setAllocatedType(OrigType); 5043 EXPECT_EQ(AllocaScalar->getAllocatedType(), OrigType); 5044 // Check getAlign(). 5045 EXPECT_EQ(AllocaScalar->getAlign(), LLVMAllocaScalar->getAlign()); 5046 EXPECT_EQ(AllocaArray->getAlign(), LLVMAllocaArray->getAlign()); 5047 // Check setAlignment(). 5048 Align OrigAlign = AllocaScalar->getAlign(); 5049 Align NewAlign(16); 5050 EXPECT_NE(NewAlign, OrigAlign); 5051 AllocaScalar->setAlignment(NewAlign); 5052 EXPECT_EQ(AllocaScalar->getAlign(), NewAlign); 5053 AllocaScalar->setAlignment(OrigAlign); 5054 EXPECT_EQ(AllocaScalar->getAlign(), OrigAlign); 5055 // Check isStaticAlloca(). 5056 EXPECT_EQ(AllocaScalar->isStaticAlloca(), LLVMAllocaScalar->isStaticAlloca()); 5057 EXPECT_EQ(AllocaArray->isStaticAlloca(), LLVMAllocaArray->isStaticAlloca()); 5058 // Check isUsedWithInAlloca(), setUsedWithInAlloca(). 5059 EXPECT_EQ(AllocaScalar->isUsedWithInAlloca(), 5060 LLVMAllocaScalar->isUsedWithInAlloca()); 5061 bool OrigUsedWithInAlloca = AllocaScalar->isUsedWithInAlloca(); 5062 bool NewUsedWithInAlloca = true; 5063 EXPECT_NE(NewUsedWithInAlloca, OrigUsedWithInAlloca); 5064 AllocaScalar->setUsedWithInAlloca(NewUsedWithInAlloca); 5065 EXPECT_EQ(AllocaScalar->isUsedWithInAlloca(), NewUsedWithInAlloca); 5066 AllocaScalar->setUsedWithInAlloca(OrigUsedWithInAlloca); 5067 EXPECT_EQ(AllocaScalar->isUsedWithInAlloca(), OrigUsedWithInAlloca); 5068 5069 auto *Ty = sandboxir::Type::getInt32Ty(Ctx); 5070 unsigned AddrSpace = 42; 5071 auto *PtrTy = sandboxir::PointerType::get(Ctx, AddrSpace); 5072 auto *ArraySize = sandboxir::ConstantInt::get(Ty, 43); 5073 { 5074 // Check create() WhereIt, WhereBB. 5075 auto *NewI = cast<sandboxir::AllocaInst>(sandboxir::AllocaInst::create( 5076 Ty, AddrSpace, Ret->getIterator(), Ctx, ArraySize, "NewAlloca1")); 5077 // Check getOpcode(). 5078 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Alloca); 5079 // Check getType(). 5080 EXPECT_EQ(NewI->getType(), PtrTy); 5081 // Check getArraySize(). 5082 EXPECT_EQ(NewI->getArraySize(), ArraySize); 5083 // Check getAddrSpace(). 5084 EXPECT_EQ(NewI->getAddressSpace(), AddrSpace); 5085 // Check instr position. 5086 EXPECT_EQ(NewI->getNextNode(), Ret); 5087 } 5088 { 5089 // Check create() InsertBefore. 5090 auto *NewI = cast<sandboxir::AllocaInst>(sandboxir::AllocaInst::create( 5091 Ty, AddrSpace, Ret->getIterator(), Ctx, ArraySize, "NewAlloca2")); 5092 // Check getOpcode(). 5093 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Alloca); 5094 // Check getType(). 5095 EXPECT_EQ(NewI->getType(), PtrTy); 5096 // Check getArraySize(). 5097 EXPECT_EQ(NewI->getArraySize(), ArraySize); 5098 // Check getAddrSpace(). 5099 EXPECT_EQ(NewI->getAddressSpace(), AddrSpace); 5100 // Check instr position. 5101 EXPECT_EQ(NewI->getNextNode(), Ret); 5102 } 5103 { 5104 // Check create() InsertAtEnd. 5105 auto *NewI = cast<sandboxir::AllocaInst>(sandboxir::AllocaInst::create( 5106 Ty, AddrSpace, BB, Ctx, ArraySize, "NewAlloca3")); 5107 // Check getOpcode(). 5108 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Alloca); 5109 // Check getType(). 5110 EXPECT_EQ(NewI->getType(), PtrTy); 5111 // Check getArraySize(). 5112 EXPECT_EQ(NewI->getArraySize(), ArraySize); 5113 // Check getAddrSpace(). 5114 EXPECT_EQ(NewI->getAddressSpace(), AddrSpace); 5115 // Check instr position. 5116 EXPECT_EQ(NewI->getParent(), BB); 5117 EXPECT_EQ(NewI->getNextNode(), nullptr); 5118 } 5119 } 5120 5121 TEST_F(SandboxIRTest, CastInst) { 5122 parseIR(C, R"IR( 5123 define void @foo(i32 %arg, float %farg, double %darg, ptr %ptr) { 5124 %zext = zext i32 %arg to i64 5125 %sext = sext i32 %arg to i64 5126 %fptoui = fptoui float %farg to i32 5127 %fptosi = fptosi float %farg to i32 5128 %fpext = fpext float %farg to double 5129 %ptrtoint = ptrtoint ptr %ptr to i32 5130 %inttoptr = inttoptr i32 %arg to ptr 5131 %sitofp = sitofp i32 %arg to float 5132 %uitofp = uitofp i32 %arg to float 5133 %trunc = trunc i32 %arg to i16 5134 %fptrunc = fptrunc double %darg to float 5135 %bitcast = bitcast i32 %arg to float 5136 %addrspacecast = addrspacecast ptr %ptr to ptr addrspace(1) 5137 ret void 5138 } 5139 )IR"); 5140 Function &LLVMF = *M->getFunction("foo"); 5141 sandboxir::Context Ctx(C); 5142 sandboxir::Function *F = Ctx.createFunction(&LLVMF); 5143 unsigned ArgIdx = 0; 5144 auto *Arg = F->getArg(ArgIdx++); 5145 auto *BB = &*F->begin(); 5146 auto It = BB->begin(); 5147 5148 auto *Ti64 = sandboxir::Type::getInt64Ty(Ctx); 5149 auto *Ti32 = sandboxir::Type::getInt32Ty(Ctx); 5150 auto *Ti16 = sandboxir::Type::getInt16Ty(Ctx); 5151 auto *Tdouble = sandboxir::Type::getDoubleTy(Ctx); 5152 auto *Tfloat = sandboxir::Type::getFloatTy(Ctx); 5153 auto *Tptr = sandboxir::PointerType::get(Ctx, 0); 5154 auto *Tptr1 = sandboxir::PointerType::get(Ctx, 1); 5155 5156 // Check classof(), getOpcode(), getSrcTy(), getDstTy() 5157 auto *ZExt = cast<sandboxir::CastInst>(&*It++); 5158 auto *ZExtI = cast<sandboxir::ZExtInst>(ZExt); 5159 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(ZExtI)); 5160 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(ZExtI)); 5161 EXPECT_EQ(ZExt->getOpcode(), sandboxir::Instruction::Opcode::ZExt); 5162 EXPECT_EQ(ZExt->getSrcTy(), Ti32); 5163 EXPECT_EQ(ZExt->getDestTy(), Ti64); 5164 5165 auto *SExt = cast<sandboxir::CastInst>(&*It++); 5166 auto *SExtI = cast<sandboxir::SExtInst>(SExt); 5167 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(SExt)); 5168 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(SExtI)); 5169 EXPECT_EQ(SExt->getOpcode(), sandboxir::Instruction::Opcode::SExt); 5170 EXPECT_EQ(SExt->getSrcTy(), Ti32); 5171 EXPECT_EQ(SExt->getDestTy(), Ti64); 5172 5173 auto *FPToUI = cast<sandboxir::CastInst>(&*It++); 5174 auto *FPToUII = cast<sandboxir::FPToUIInst>(FPToUI); 5175 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(FPToUI)); 5176 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(FPToUII)); 5177 EXPECT_EQ(FPToUI->getOpcode(), sandboxir::Instruction::Opcode::FPToUI); 5178 EXPECT_EQ(FPToUI->getSrcTy(), Tfloat); 5179 EXPECT_EQ(FPToUI->getDestTy(), Ti32); 5180 5181 auto *FPToSI = cast<sandboxir::CastInst>(&*It++); 5182 auto *FPToSII = cast<sandboxir::FPToSIInst>(FPToSI); 5183 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(FPToSI)); 5184 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(FPToSII)); 5185 EXPECT_EQ(FPToSI->getOpcode(), sandboxir::Instruction::Opcode::FPToSI); 5186 EXPECT_EQ(FPToSI->getSrcTy(), Tfloat); 5187 EXPECT_EQ(FPToSI->getDestTy(), Ti32); 5188 5189 auto *FPExt = cast<sandboxir::CastInst>(&*It++); 5190 auto *FPExtI = cast<sandboxir::FPExtInst>(FPExt); 5191 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(FPExt)); 5192 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(FPExtI)); 5193 EXPECT_EQ(FPExt->getOpcode(), sandboxir::Instruction::Opcode::FPExt); 5194 EXPECT_EQ(FPExt->getSrcTy(), Tfloat); 5195 EXPECT_EQ(FPExt->getDestTy(), Tdouble); 5196 5197 auto *PtrToInt = cast<sandboxir::CastInst>(&*It++); 5198 auto *PtrToIntI = cast<sandboxir::PtrToIntInst>(PtrToInt); 5199 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(PtrToInt)); 5200 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(PtrToIntI)); 5201 EXPECT_EQ(PtrToInt->getOpcode(), sandboxir::Instruction::Opcode::PtrToInt); 5202 EXPECT_EQ(PtrToInt->getSrcTy(), Tptr); 5203 EXPECT_EQ(PtrToInt->getDestTy(), Ti32); 5204 5205 auto *IntToPtr = cast<sandboxir::CastInst>(&*It++); 5206 auto *IntToPtrI = cast<sandboxir::IntToPtrInst>(IntToPtr); 5207 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(IntToPtr)); 5208 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(IntToPtrI)); 5209 EXPECT_EQ(IntToPtr->getOpcode(), sandboxir::Instruction::Opcode::IntToPtr); 5210 EXPECT_EQ(IntToPtr->getSrcTy(), Ti32); 5211 EXPECT_EQ(IntToPtr->getDestTy(), Tptr); 5212 5213 auto *SIToFP = cast<sandboxir::CastInst>(&*It++); 5214 auto *SIToFPI = cast<sandboxir::SIToFPInst>(SIToFP); 5215 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(SIToFP)); 5216 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(SIToFPI)); 5217 EXPECT_EQ(SIToFP->getOpcode(), sandboxir::Instruction::Opcode::SIToFP); 5218 EXPECT_EQ(SIToFP->getSrcTy(), Ti32); 5219 EXPECT_EQ(SIToFP->getDestTy(), Tfloat); 5220 5221 auto *UIToFP = cast<sandboxir::CastInst>(&*It++); 5222 auto *UIToFPI = cast<sandboxir::UIToFPInst>(UIToFP); 5223 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(UIToFP)); 5224 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(UIToFPI)); 5225 EXPECT_EQ(UIToFP->getOpcode(), sandboxir::Instruction::Opcode::UIToFP); 5226 EXPECT_EQ(UIToFP->getSrcTy(), Ti32); 5227 EXPECT_EQ(UIToFP->getDestTy(), Tfloat); 5228 5229 auto *Trunc = cast<sandboxir::CastInst>(&*It++); 5230 auto *TruncI = cast<sandboxir::TruncInst>(Trunc); 5231 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(Trunc)); 5232 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(TruncI)); 5233 EXPECT_EQ(Trunc->getOpcode(), sandboxir::Instruction::Opcode::Trunc); 5234 EXPECT_EQ(Trunc->getSrcTy(), Ti32); 5235 EXPECT_EQ(Trunc->getDestTy(), Ti16); 5236 5237 auto *FPTrunc = cast<sandboxir::CastInst>(&*It++); 5238 auto *FPTruncI = cast<sandboxir::FPTruncInst>(FPTrunc); 5239 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(FPTrunc)); 5240 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(FPTruncI)); 5241 EXPECT_EQ(FPTrunc->getOpcode(), sandboxir::Instruction::Opcode::FPTrunc); 5242 EXPECT_EQ(FPTrunc->getSrcTy(), Tdouble); 5243 EXPECT_EQ(FPTrunc->getDestTy(), Tfloat); 5244 5245 auto *BitCast = cast<sandboxir::CastInst>(&*It++); 5246 auto *BitCastI = cast<sandboxir::BitCastInst>(BitCast); 5247 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(BitCast)); 5248 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(BitCastI)); 5249 EXPECT_EQ(BitCast->getOpcode(), sandboxir::Instruction::Opcode::BitCast); 5250 EXPECT_EQ(BitCast->getSrcTy(), Ti32); 5251 EXPECT_EQ(BitCast->getDestTy(), Tfloat); 5252 5253 auto *AddrSpaceCast = cast<sandboxir::CastInst>(&*It++); 5254 auto *AddrSpaceCastI = cast<sandboxir::AddrSpaceCastInst>(AddrSpaceCast); 5255 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(AddrSpaceCast)); 5256 EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(AddrSpaceCastI)); 5257 EXPECT_EQ(AddrSpaceCast->getOpcode(), 5258 sandboxir::Instruction::Opcode::AddrSpaceCast); 5259 EXPECT_EQ(AddrSpaceCast->getSrcTy(), Tptr); 5260 EXPECT_EQ(AddrSpaceCast->getDestTy(), Tptr1); 5261 5262 auto *Ret = cast<sandboxir::ReturnInst>(&*It++); 5263 5264 { 5265 // Check create() WhereIt, WhereBB 5266 auto *NewI = cast<sandboxir::CastInst>( 5267 sandboxir::CastInst::create(Ti64, sandboxir::Instruction::Opcode::SExt, 5268 Arg, BB->end(), Ctx, "SExt")); 5269 // Check getOpcode(). 5270 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::SExt); 5271 // Check getSrcTy(). 5272 EXPECT_EQ(NewI->getSrcTy(), Arg->getType()); 5273 // Check getDestTy(). 5274 EXPECT_EQ(NewI->getDestTy(), Ti64); 5275 // Check instr position. 5276 EXPECT_EQ(NewI->getNextNode(), nullptr); 5277 EXPECT_EQ(NewI->getPrevNode(), Ret); 5278 } 5279 5280 { 5281 // Check create() InsertBefore. 5282 auto *NewI = cast<sandboxir::CastInst>( 5283 sandboxir::CastInst::create(Ti64, sandboxir::Instruction::Opcode::ZExt, 5284 Arg, Ret->getIterator(), Ctx, "ZExt")); 5285 // Check getOpcode(). 5286 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::ZExt); 5287 // Check getSrcTy(). 5288 EXPECT_EQ(NewI->getSrcTy(), Arg->getType()); 5289 // Check getDestTy(). 5290 EXPECT_EQ(NewI->getDestTy(), Ti64); 5291 // Check instr position. 5292 EXPECT_EQ(NewI->getNextNode(), Ret); 5293 } 5294 { 5295 // Check create() InsertAtEnd. 5296 auto *NewI = cast<sandboxir::CastInst>(sandboxir::CastInst::create( 5297 Ti64, sandboxir::Instruction::Opcode::ZExt, Arg, BB, Ctx, "ZExt")); 5298 // Check getOpcode(). 5299 EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::ZExt); 5300 // Check getSrcTy(). 5301 EXPECT_EQ(NewI->getSrcTy(), Arg->getType()); 5302 // Check getDestTy(). 5303 EXPECT_EQ(NewI->getDestTy(), Ti64); 5304 // Check instr position. 5305 EXPECT_EQ(NewI->getNextNode(), nullptr); 5306 EXPECT_EQ(NewI->getParent(), BB); 5307 } 5308 5309 { 5310 #ifndef NDEBUG 5311 // Check that passing a non-cast opcode crashes. 5312 EXPECT_DEATH( 5313 sandboxir::CastInst::create(Ti64, sandboxir::Instruction::Opcode::Store, 5314 Arg, Ret->getIterator(), Ctx, "Bad"), 5315 ".*Opcode.*"); 5316 #endif // NDEBUG 5317 } 5318 } 5319 5320 TEST_F(SandboxIRTest, PossiblyNonNegInst) { 5321 parseIR(C, R"IR( 5322 define void @foo(i32 %arg, float %farg, double %darg, ptr %ptr) { 5323 %zext = zext i32 %arg to i64 5324 %uitofp = uitofp i32 %arg to float 5325 5326 %sext = sext i32 %arg to i64 5327 %fptoui = fptoui float %farg to i32 5328 %fptosi = fptosi float %farg to i32 5329 %fpext = fpext float %farg to double 5330 %ptrtoint = ptrtoint ptr %ptr to i32 5331 %inttoptr = inttoptr i32 %arg to ptr 5332 %sitofp = sitofp i32 %arg to float 5333 %trunc = trunc i32 %arg to i16 5334 %fptrunc = fptrunc double %darg to float 5335 %bitcast = bitcast i32 %arg to float 5336 %addrspacecast = addrspacecast ptr %ptr to ptr addrspace(1) 5337 ret void 5338 } 5339 )IR"); 5340 Function &LLVMF = *M->getFunction("foo"); 5341 sandboxir::Context Ctx(C); 5342 sandboxir::Function *F = Ctx.createFunction(&LLVMF); 5343 auto *BB = &*F->begin(); 5344 auto It = BB->begin(); 5345 auto *PNNI0 = cast<sandboxir::PossiblyNonNegInst>(&*It++); 5346 auto *PNNI1 = cast<sandboxir::PossiblyNonNegInst>(&*It++); 5347 for (auto ItE = BB->end(); It != ItE; ++It) 5348 EXPECT_FALSE(isa<sandboxir::PossiblyNonNegInst>(&*It++)); 5349 5350 for (auto *PNNI : {PNNI0, PNNI1}) { 5351 // Check setNonNeg(), hasNonNeg(). 5352 auto OrigNonNeg = PNNI->hasNonNeg(); 5353 auto NewNonNeg = true; 5354 EXPECT_NE(NewNonNeg, OrigNonNeg); 5355 PNNI->setNonNeg(NewNonNeg); 5356 EXPECT_EQ(PNNI->hasNonNeg(), NewNonNeg); 5357 PNNI->setNonNeg(OrigNonNeg); 5358 EXPECT_EQ(PNNI->hasNonNeg(), OrigNonNeg); 5359 } 5360 } 5361 5362 /// CastInst's subclasses are very similar so we can use a common test function 5363 /// for them. 5364 template <typename SubclassT, sandboxir::Instruction::Opcode OpcodeT> 5365 void testCastInst(llvm::Module &M, llvm::Type *LLVMSrcTy, 5366 llvm::Type *LLVMDstTy) { 5367 Function &LLVMF = *M.getFunction("foo"); 5368 sandboxir::Context Ctx(M.getContext()); 5369 sandboxir::Function *F = Ctx.createFunction(&LLVMF); 5370 sandboxir::Type *SrcTy = Ctx.getType(LLVMSrcTy); 5371 sandboxir::Type *DstTy = Ctx.getType(LLVMDstTy); 5372 unsigned ArgIdx = 0; 5373 auto *Arg = F->getArg(ArgIdx++); 5374 auto *BB = &*F->begin(); 5375 auto It = BB->begin(); 5376 5377 auto *CI = cast<SubclassT>(&*It++); 5378 EXPECT_EQ(CI->getOpcode(), OpcodeT); 5379 EXPECT_EQ(CI->getSrcTy(), SrcTy); 5380 EXPECT_EQ(CI->getDestTy(), DstTy); 5381 auto *Ret = cast<sandboxir::ReturnInst>(&*It++); 5382 5383 { 5384 // Check create() WhereIt, WhereBB 5385 auto *NewI = 5386 cast<SubclassT>(SubclassT::create(Arg, DstTy, BB->end(), Ctx, "NewCI")); 5387 // Check getOpcode(). 5388 EXPECT_EQ(NewI->getOpcode(), OpcodeT); 5389 // Check getSrcTy(). 5390 EXPECT_EQ(NewI->getSrcTy(), Arg->getType()); 5391 // Check getDestTy(). 5392 EXPECT_EQ(NewI->getDestTy(), DstTy); 5393 // Check instr position. 5394 EXPECT_EQ(NewI->getNextNode(), nullptr); 5395 EXPECT_EQ(NewI->getPrevNode(), Ret); 5396 // Check instr name. 5397 EXPECT_EQ(NewI->getName(), "NewCI"); 5398 } 5399 { 5400 // Check create() InsertBefore. 5401 auto *NewI = cast<SubclassT>( 5402 SubclassT::create(Arg, DstTy, Ret->getIterator(), Ctx, "NewCI")); 5403 // Check getOpcode(). 5404 EXPECT_EQ(NewI->getOpcode(), OpcodeT); 5405 // Check getSrcTy(). 5406 EXPECT_EQ(NewI->getSrcTy(), Arg->getType()); 5407 // Check getDestTy(). 5408 EXPECT_EQ(NewI->getDestTy(), DstTy); 5409 // Check instr position. 5410 EXPECT_EQ(NewI->getNextNode(), Ret); 5411 } 5412 { 5413 // Check create() InsertAtEnd. 5414 auto *NewI = 5415 cast<SubclassT>(SubclassT::create(Arg, DstTy, 5416 /*InsertAtEnd=*/BB, Ctx, "NewCI")); 5417 // Check getOpcode(). 5418 EXPECT_EQ(NewI->getOpcode(), OpcodeT); 5419 // Check getSrcTy(). 5420 EXPECT_EQ(NewI->getSrcTy(), Arg->getType()); 5421 // Check getDestTy(). 5422 EXPECT_EQ(NewI->getDestTy(), DstTy); 5423 // Check instr position. 5424 EXPECT_EQ(NewI->getNextNode(), nullptr); 5425 EXPECT_EQ(NewI->getParent(), BB); 5426 } 5427 } 5428 5429 TEST_F(SandboxIRTest, TruncInst) { 5430 parseIR(C, R"IR( 5431 define void @foo(i64 %arg) { 5432 %trunc = trunc i64 %arg to i32 5433 ret void 5434 } 5435 )IR"); 5436 testCastInst<sandboxir::TruncInst, sandboxir::Instruction::Opcode::Trunc>( 5437 *M, 5438 /*SrcTy=*/Type::getInt64Ty(C), /*DstTy=*/Type::getInt32Ty(C)); 5439 } 5440 5441 TEST_F(SandboxIRTest, ZExtInst) { 5442 parseIR(C, R"IR( 5443 define void @foo(i32 %arg) { 5444 %zext = zext i32 %arg to i64 5445 ret void 5446 } 5447 )IR"); 5448 testCastInst<sandboxir::ZExtInst, sandboxir::Instruction::Opcode::ZExt>( 5449 *M, 5450 /*SrcTy=*/Type::getInt32Ty(C), /*DstTy=*/Type::getInt64Ty(C)); 5451 } 5452 5453 TEST_F(SandboxIRTest, SExtInst) { 5454 parseIR(C, R"IR( 5455 define void @foo(i32 %arg) { 5456 %sext = sext i32 %arg to i64 5457 ret void 5458 } 5459 )IR"); 5460 testCastInst<sandboxir::SExtInst, sandboxir::Instruction::Opcode::SExt>( 5461 *M, 5462 /*SrcTy=*/Type::getInt32Ty(C), /*DstTy=*/Type::getInt64Ty(C)); 5463 } 5464 5465 TEST_F(SandboxIRTest, FPTruncInst) { 5466 parseIR(C, R"IR( 5467 define void @foo(double %arg) { 5468 %fptrunc = fptrunc double %arg to float 5469 ret void 5470 } 5471 )IR"); 5472 testCastInst<sandboxir::FPTruncInst, sandboxir::Instruction::Opcode::FPTrunc>( 5473 *M, 5474 /*SrcTy=*/Type::getDoubleTy(C), /*DstTy=*/Type::getFloatTy(C)); 5475 } 5476 5477 TEST_F(SandboxIRTest, FPExtInst) { 5478 parseIR(C, R"IR( 5479 define void @foo(float %arg) { 5480 %fpext = fpext float %arg to double 5481 ret void 5482 } 5483 )IR"); 5484 testCastInst<sandboxir::FPExtInst, sandboxir::Instruction::Opcode::FPExt>( 5485 *M, 5486 /*SrcTy=*/Type::getFloatTy(C), /*DstTy=*/Type::getDoubleTy(C)); 5487 } 5488 5489 TEST_F(SandboxIRTest, UIToFPInst) { 5490 parseIR(C, R"IR( 5491 define void @foo(i32 %arg) { 5492 %uitofp = uitofp i32 %arg to float 5493 ret void 5494 } 5495 )IR"); 5496 testCastInst<sandboxir::UIToFPInst, sandboxir::Instruction::Opcode::UIToFP>( 5497 *M, 5498 /*SrcTy=*/Type::getInt32Ty(C), /*DstTy=*/Type::getFloatTy(C)); 5499 } 5500 5501 TEST_F(SandboxIRTest, SIToFPInst) { 5502 parseIR(C, R"IR( 5503 define void @foo(i32 %arg) { 5504 %sitofp = sitofp i32 %arg to float 5505 ret void 5506 } 5507 )IR"); 5508 testCastInst<sandboxir::SIToFPInst, sandboxir::Instruction::Opcode::SIToFP>( 5509 *M, 5510 /*SrcTy=*/Type::getInt32Ty(C), 5511 /*DstTy=*/Type::getFloatTy(C)); 5512 } 5513 5514 TEST_F(SandboxIRTest, FPToUIInst) { 5515 parseIR(C, R"IR( 5516 define void @foo(float %arg) { 5517 %fptoui = fptoui float %arg to i32 5518 ret void 5519 } 5520 )IR"); 5521 testCastInst<sandboxir::FPToUIInst, sandboxir::Instruction::Opcode::FPToUI>( 5522 5523 *M, /*SrcTy=*/Type::getFloatTy(C), /*DstTy=*/Type::getInt32Ty(C)); 5524 } 5525 5526 TEST_F(SandboxIRTest, FPToSIInst) { 5527 parseIR(C, R"IR( 5528 define void @foo(float %arg) { 5529 %fptosi = fptosi float %arg to i32 5530 ret void 5531 } 5532 )IR"); 5533 testCastInst<sandboxir::FPToSIInst, sandboxir::Instruction::Opcode::FPToSI>( 5534 *M, /*SrcTy=*/Type::getFloatTy(C), /*DstTy=*/Type::getInt32Ty(C)); 5535 } 5536 5537 TEST_F(SandboxIRTest, IntToPtrInst) { 5538 parseIR(C, R"IR( 5539 define void @foo(i32 %arg) { 5540 %inttoptr = inttoptr i32 %arg to ptr 5541 ret void 5542 } 5543 )IR"); 5544 testCastInst<sandboxir::IntToPtrInst, 5545 sandboxir::Instruction::Opcode::IntToPtr>( 5546 *M, 5547 /*SrcTy=*/Type::getInt32Ty(C), /*DstTy=*/PointerType::get(C, 0)); 5548 } 5549 5550 TEST_F(SandboxIRTest, PtrToIntInst) { 5551 parseIR(C, R"IR( 5552 define void @foo(ptr %ptr) { 5553 %ptrtoint = ptrtoint ptr %ptr to i32 5554 ret void 5555 } 5556 )IR"); 5557 testCastInst<sandboxir::PtrToIntInst, 5558 sandboxir::Instruction::Opcode::PtrToInt>( 5559 *M, /*SrcTy=*/PointerType::get(C, 0), /*DstTy=*/Type::getInt32Ty(C)); 5560 } 5561 5562 TEST_F(SandboxIRTest, BitCastInst) { 5563 parseIR(C, R"IR( 5564 define void @foo(i32 %arg) { 5565 %bitcast = bitcast i32 %arg to float 5566 ret void 5567 } 5568 )IR"); 5569 testCastInst<sandboxir::BitCastInst, sandboxir::Instruction::Opcode::BitCast>( 5570 *M, 5571 /*SrcTy=*/Type::getInt32Ty(C), /*DstTy=*/Type::getFloatTy(C)); 5572 } 5573 5574 TEST_F(SandboxIRTest, AddrSpaceCastInst) { 5575 parseIR(C, R"IR( 5576 define void @foo(ptr %ptr) { 5577 %addrspacecast = addrspacecast ptr %ptr to ptr addrspace(1) 5578 ret void 5579 } 5580 )IR"); 5581 Type *Tptr0 = PointerType::get(C, 0); 5582 Type *Tptr1 = PointerType::get(C, 1); 5583 testCastInst<sandboxir::AddrSpaceCastInst, 5584 sandboxir::Instruction::Opcode::AddrSpaceCast>(*M, 5585 /*SrcTy=*/Tptr0, 5586 /*DstTy=*/Tptr1); 5587 Function &LLVMF = *M->getFunction("foo"); 5588 sandboxir::Context Ctx(C); 5589 sandboxir::Function *F = Ctx.createFunction(&LLVMF); 5590 unsigned ArgIdx = 0; 5591 auto *Arg = F->getArg(ArgIdx++); 5592 auto *BB = &*F->begin(); 5593 auto It = BB->begin(); 5594 5595 auto *AddrSpaceCast = cast<sandboxir::AddrSpaceCastInst>(&*It++); 5596 EXPECT_EQ(AddrSpaceCast->getOpcode(), 5597 sandboxir::Instruction::Opcode::AddrSpaceCast); 5598 EXPECT_EQ(AddrSpaceCast->getPointerOperand(), Arg); 5599 EXPECT_EQ(sandboxir::AddrSpaceCastInst::getPointerOperandIndex(), 0u); 5600 EXPECT_EQ(AddrSpaceCast->getSrcAddressSpace(), 5601 cast<PointerType>(Tptr0)->getPointerAddressSpace()); 5602 EXPECT_EQ(AddrSpaceCast->getDestAddressSpace(), 5603 cast<PointerType>(Tptr1)->getPointerAddressSpace()); 5604 } 5605 5606 TEST_F(SandboxIRTest, PHINode) { 5607 parseIR(C, R"IR( 5608 define void @foo(i32 %arg) { 5609 bb1: 5610 br label %bb2 5611 5612 bb2: 5613 %phi = phi i32 [ %arg, %bb1 ], [ 0, %bb2 ], [ 1, %bb3 ], [ 2, %bb4 ], [ 3, %bb5 ] 5614 br label %bb2 5615 5616 bb3: 5617 br label %bb2 5618 5619 bb4: 5620 br label %bb2 5621 5622 bb5: 5623 br label %bb2 5624 ret void 5625 } 5626 )IR"); 5627 Function &LLVMF = *M->getFunction("foo"); 5628 auto *LLVMBB1 = getBasicBlockByName(LLVMF, "bb1"); 5629 auto *LLVMBB2 = getBasicBlockByName(LLVMF, "bb2"); 5630 auto *LLVMBB3 = getBasicBlockByName(LLVMF, "bb3"); 5631 auto LLVMIt = LLVMBB2->begin(); 5632 auto *LLVMPHI = cast<llvm::PHINode>(&*LLVMIt++); 5633 sandboxir::Context Ctx(C); 5634 sandboxir::Function *F = Ctx.createFunction(&LLVMF); 5635 auto *Arg = F->getArg(0); 5636 auto *BB1 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB1)); 5637 auto *BB2 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB2)); 5638 auto *BB3 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB3)); 5639 auto It = BB2->begin(); 5640 // Check classof(). 5641 auto *PHI = cast<sandboxir::PHINode>(&*It++); 5642 auto *Br = cast<sandboxir::BranchInst>(&*It++); 5643 // Check blocks(). 5644 EXPECT_EQ(range_size(PHI->blocks()), range_size(LLVMPHI->blocks())); 5645 auto BlockIt = PHI->block_begin(); 5646 for (llvm::BasicBlock *LLVMBB : LLVMPHI->blocks()) { 5647 sandboxir::BasicBlock *BB = *BlockIt++; 5648 EXPECT_EQ(BB, Ctx.getValue(LLVMBB)); 5649 } 5650 // Check incoming_values(). 5651 EXPECT_EQ(range_size(PHI->incoming_values()), 5652 range_size(LLVMPHI->incoming_values())); 5653 auto IncIt = PHI->incoming_values().begin(); 5654 for (llvm::Value *LLVMV : LLVMPHI->incoming_values()) { 5655 sandboxir::Value *IncV = *IncIt++; 5656 EXPECT_EQ(IncV, Ctx.getValue(LLVMV)); 5657 } 5658 // Check getNumIncomingValues(). 5659 EXPECT_EQ(PHI->getNumIncomingValues(), LLVMPHI->getNumIncomingValues()); 5660 // Check getIncomingValue(). 5661 EXPECT_EQ(PHI->getIncomingValue(0), 5662 Ctx.getValue(LLVMPHI->getIncomingValue(0))); 5663 EXPECT_EQ(PHI->getIncomingValue(1), 5664 Ctx.getValue(LLVMPHI->getIncomingValue(1))); 5665 // Check setIncomingValue(). 5666 auto *OrigV = PHI->getIncomingValue(0); 5667 PHI->setIncomingValue(0, PHI); 5668 EXPECT_EQ(PHI->getIncomingValue(0), PHI); 5669 PHI->setIncomingValue(0, OrigV); 5670 // Check getOperandNumForIncomingValue(). 5671 EXPECT_EQ(sandboxir::PHINode::getOperandNumForIncomingValue(0), 5672 llvm::PHINode::getOperandNumForIncomingValue(0)); 5673 // Check getIncomingValueNumForOperand(). 5674 EXPECT_EQ(sandboxir::PHINode::getIncomingValueNumForOperand(0), 5675 llvm::PHINode::getIncomingValueNumForOperand(0)); 5676 // Check getIncomingBlock(unsigned). 5677 EXPECT_EQ(PHI->getIncomingBlock(0), 5678 Ctx.getValue(LLVMPHI->getIncomingBlock(0))); 5679 // Check getIncomingBlock(Use). 5680 llvm::Use &LLVMUse = LLVMPHI->getOperandUse(0); 5681 sandboxir::Use Use = PHI->getOperandUse(0); 5682 EXPECT_EQ(PHI->getIncomingBlock(Use), 5683 Ctx.getValue(LLVMPHI->getIncomingBlock(LLVMUse))); 5684 // Check setIncomingBlock(). 5685 sandboxir::BasicBlock *OrigBB = PHI->getIncomingBlock(0); 5686 EXPECT_NE(OrigBB, BB2); 5687 PHI->setIncomingBlock(0, BB2); 5688 EXPECT_EQ(PHI->getIncomingBlock(0), BB2); 5689 PHI->setIncomingBlock(0, OrigBB); 5690 EXPECT_EQ(PHI->getIncomingBlock(0), OrigBB); 5691 // Check addIncoming(). 5692 unsigned OrigNumIncoming = PHI->getNumIncomingValues(); 5693 PHI->addIncoming(Arg, BB3); 5694 EXPECT_EQ(PHI->getNumIncomingValues(), LLVMPHI->getNumIncomingValues()); 5695 EXPECT_EQ(PHI->getNumIncomingValues(), OrigNumIncoming + 1); 5696 EXPECT_EQ(PHI->getIncomingValue(OrigNumIncoming), Arg); 5697 EXPECT_EQ(PHI->getIncomingBlock(OrigNumIncoming), BB3); 5698 // Check removeIncomingValue(unsigned). 5699 PHI->removeIncomingValue(OrigNumIncoming); 5700 EXPECT_EQ(PHI->getNumIncomingValues(), OrigNumIncoming); 5701 // Check removeIncomingValue(BasicBlock *). 5702 PHI->addIncoming(Arg, BB3); 5703 PHI->removeIncomingValue(BB3); 5704 EXPECT_EQ(PHI->getNumIncomingValues(), OrigNumIncoming); 5705 // Check getBasicBlockIndex(). 5706 EXPECT_EQ(PHI->getBasicBlockIndex(BB1), LLVMPHI->getBasicBlockIndex(LLVMBB1)); 5707 // Check getIncomingValueForBlock(). 5708 EXPECT_EQ(PHI->getIncomingValueForBlock(BB1), 5709 Ctx.getValue(LLVMPHI->getIncomingValueForBlock(LLVMBB1))); 5710 // Check hasConstantValue(). 5711 llvm::Value *ConstV = LLVMPHI->hasConstantValue(); 5712 EXPECT_EQ(PHI->hasConstantValue(), 5713 ConstV != nullptr ? Ctx.getValue(ConstV) : nullptr); 5714 // Check hasConstantOrUndefValue(). 5715 EXPECT_EQ(PHI->hasConstantOrUndefValue(), LLVMPHI->hasConstantOrUndefValue()); 5716 // Check isComplete(). 5717 EXPECT_EQ(PHI->isComplete(), LLVMPHI->isComplete()); 5718 // Check replaceIncomingValueIf 5719 EXPECT_EQ(PHI->getNumIncomingValues(), 5u); 5720 auto *RemainBB0 = PHI->getIncomingBlock(0); 5721 auto *RemoveBB0 = PHI->getIncomingBlock(1); 5722 auto *RemainBB1 = PHI->getIncomingBlock(2); 5723 auto *RemoveBB1 = PHI->getIncomingBlock(3); 5724 auto *RemainBB2 = PHI->getIncomingBlock(4); 5725 PHI->removeIncomingValueIf([&](unsigned Idx) { 5726 return PHI->getIncomingBlock(Idx) == RemoveBB0 || 5727 PHI->getIncomingBlock(Idx) == RemoveBB1; 5728 }); 5729 EXPECT_EQ(PHI->getNumIncomingValues(), 3u); 5730 EXPECT_EQ(PHI->getIncomingBlock(0), RemainBB0); 5731 EXPECT_EQ(PHI->getIncomingBlock(1), RemainBB1); 5732 EXPECT_EQ(PHI->getIncomingBlock(2), RemainBB2); 5733 // Check replaceIncomingBlockWith 5734 OrigBB = RemainBB0; 5735 auto *NewBB = RemainBB1; 5736 EXPECT_NE(NewBB, OrigBB); 5737 PHI->replaceIncomingBlockWith(OrigBB, NewBB); 5738 EXPECT_EQ(PHI->getIncomingBlock(0), NewBB); 5739 EXPECT_EQ(PHI->getIncomingBlock(1), RemainBB1); 5740 EXPECT_EQ(PHI->getIncomingBlock(2), RemainBB2); 5741 // Check create(). 5742 auto *NewPHI = cast<sandboxir::PHINode>(sandboxir::PHINode::create( 5743 PHI->getType(), 0, Br->getIterator(), Ctx, "NewPHI")); 5744 EXPECT_EQ(NewPHI->getType(), PHI->getType()); 5745 EXPECT_EQ(NewPHI->getNextNode(), Br); 5746 EXPECT_EQ(NewPHI->getName(), "NewPHI"); 5747 EXPECT_EQ(NewPHI->getNumIncomingValues(), 0u); 5748 for (auto [Idx, V] : enumerate(PHI->incoming_values())) { 5749 sandboxir::BasicBlock *IncBB = PHI->getIncomingBlock(Idx); 5750 NewPHI->addIncoming(V, IncBB); 5751 } 5752 EXPECT_EQ(NewPHI->getNumIncomingValues(), PHI->getNumIncomingValues()); 5753 } 5754 5755 static void checkSwapOperands(sandboxir::Context &Ctx, 5756 llvm::sandboxir::CmpInst *Cmp, 5757 llvm::CmpInst *LLVMCmp) { 5758 auto OrigOp0 = Cmp->getOperand(0); 5759 auto OrigOp1 = Cmp->getOperand(1); 5760 EXPECT_EQ(Ctx.getValue(LLVMCmp->getOperand(0)), OrigOp0); 5761 EXPECT_EQ(Ctx.getValue(LLVMCmp->getOperand(1)), OrigOp1); 5762 // This checks the dispatch mechanism in CmpInst, as well as 5763 // the specific implementations. 5764 Cmp->swapOperands(); 5765 EXPECT_EQ(Ctx.getValue(LLVMCmp->getOperand(1)), OrigOp0); 5766 EXPECT_EQ(Ctx.getValue(LLVMCmp->getOperand(0)), OrigOp1); 5767 EXPECT_EQ(Cmp->getOperand(0), OrigOp1); 5768 EXPECT_EQ(Cmp->getOperand(1), OrigOp0); 5769 // Undo it to keep the rest of the test consistent 5770 Cmp->swapOperands(); 5771 } 5772 5773 static void checkCommonPredicates(sandboxir::CmpInst *Cmp, 5774 llvm::CmpInst *LLVMCmp) { 5775 // Check proper creation 5776 auto Pred = Cmp->getPredicate(); 5777 auto LLVMPred = LLVMCmp->getPredicate(); 5778 EXPECT_EQ(Pred, LLVMPred); 5779 // Check setPredicate 5780 Cmp->setPredicate(llvm::CmpInst::FCMP_FALSE); 5781 EXPECT_EQ(Cmp->getPredicate(), llvm::CmpInst::FCMP_FALSE); 5782 EXPECT_EQ(LLVMCmp->getPredicate(), llvm::CmpInst::FCMP_FALSE); 5783 Cmp->setPredicate(Pred); 5784 EXPECT_EQ(LLVMCmp->getPredicate(), Pred); 5785 // Ensure the accessors properly forward to the underlying implementation 5786 EXPECT_STREQ(sandboxir::CmpInst::getPredicateName(Pred).data(), 5787 llvm::CmpInst::getPredicateName(LLVMPred).data()); 5788 EXPECT_EQ(Cmp->isFPPredicate(), LLVMCmp->isFPPredicate()); 5789 EXPECT_EQ(Cmp->isIntPredicate(), LLVMCmp->isIntPredicate()); 5790 EXPECT_EQ(Cmp->getInversePredicate(), LLVMCmp->getInversePredicate()); 5791 EXPECT_EQ(Cmp->getOrderedPredicate(), LLVMCmp->getOrderedPredicate()); 5792 EXPECT_EQ(Cmp->getUnorderedPredicate(), LLVMCmp->getUnorderedPredicate()); 5793 EXPECT_EQ(Cmp->getSwappedPredicate(), LLVMCmp->getSwappedPredicate()); 5794 EXPECT_EQ(Cmp->isStrictPredicate(), LLVMCmp->isStrictPredicate()); 5795 EXPECT_EQ(Cmp->isNonStrictPredicate(), LLVMCmp->isNonStrictPredicate()); 5796 EXPECT_EQ(Cmp->isRelational(), LLVMCmp->isRelational()); 5797 if (Cmp->isRelational()) { 5798 EXPECT_EQ(Cmp->getFlippedStrictnessPredicate(), 5799 LLVMCmp->getFlippedStrictnessPredicate()); 5800 } 5801 EXPECT_EQ(Cmp->isCommutative(), LLVMCmp->isCommutative()); 5802 EXPECT_EQ(Cmp->isTrueWhenEqual(), LLVMCmp->isTrueWhenEqual()); 5803 EXPECT_EQ(Cmp->isFalseWhenEqual(), LLVMCmp->isFalseWhenEqual()); 5804 EXPECT_EQ(sandboxir::CmpInst::isOrdered(Pred), 5805 llvm::CmpInst::isOrdered(LLVMPred)); 5806 EXPECT_EQ(sandboxir::CmpInst::isUnordered(Pred), 5807 llvm::CmpInst::isUnordered(LLVMPred)); 5808 } 5809 5810 TEST_F(SandboxIRTest, ICmpInst) { 5811 SCOPED_TRACE("SandboxIRTest sandboxir::ICmpInst tests"); 5812 parseIR(C, R"IR( 5813 define void @foo(i32 %i0, i32 %i1) { 5814 bb: 5815 %ine = icmp ne i32 %i0, %i1 5816 %iugt = icmp ugt i32 %i0, %i1 5817 %iuge = icmp uge i32 %i0, %i1 5818 %iult = icmp ult i32 %i0, %i1 5819 %iule = icmp ule i32 %i0, %i1 5820 %isgt = icmp sgt i32 %i0, %i1 5821 %isle = icmp sle i32 %i0, %i1 5822 %ieg = icmp eq i32 %i0, %i1 5823 ret void 5824 } 5825 )IR"); 5826 Function &LLVMF = *M->getFunction("foo"); 5827 sandboxir::Context Ctx(C); 5828 [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF); 5829 5830 auto *LLVMBB = getBasicBlockByName(LLVMF, "bb"); 5831 auto LLVMIt = LLVMBB->begin(); 5832 auto *BB = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB)); 5833 auto It = BB->begin(); 5834 // Check classof() 5835 while (auto *ICmp = dyn_cast<sandboxir::ICmpInst>(&*It++)) { 5836 auto *LLVMICmp = cast<llvm::ICmpInst>(&*LLVMIt++); 5837 checkSwapOperands(Ctx, ICmp, LLVMICmp); 5838 checkCommonPredicates(ICmp, LLVMICmp); 5839 EXPECT_EQ(ICmp->isSigned(), LLVMICmp->isSigned()); 5840 EXPECT_EQ(ICmp->isUnsigned(), LLVMICmp->isUnsigned()); 5841 EXPECT_EQ(ICmp->getSignedPredicate(), LLVMICmp->getSignedPredicate()); 5842 EXPECT_EQ(ICmp->getUnsignedPredicate(), LLVMICmp->getUnsignedPredicate()); 5843 } 5844 auto *NewCmp = cast<sandboxir::CmpInst>( 5845 sandboxir::CmpInst::create(llvm::CmpInst::ICMP_ULE, F.getArg(0), 5846 F.getArg(1), BB->begin(), Ctx, "NewCmp")); 5847 EXPECT_EQ(NewCmp, &*BB->begin()); 5848 EXPECT_EQ(NewCmp->getPredicate(), llvm::CmpInst::ICMP_ULE); 5849 EXPECT_EQ(NewCmp->getOperand(0), F.getArg(0)); 5850 EXPECT_EQ(NewCmp->getOperand(1), F.getArg(1)); 5851 #ifndef NDEBUG 5852 EXPECT_EQ(NewCmp->getName(), "NewCmp"); 5853 #endif // NDEBUG 5854 // TODO: Improve this test when sandboxir::VectorType is more completely 5855 // implemented. 5856 sandboxir::Type *RT = 5857 sandboxir::CmpInst::makeCmpResultType(F.getArg(0)->getType()); 5858 EXPECT_TRUE(RT->isIntegerTy(1)); // Only one bit in a single comparison 5859 5860 { 5861 // Check create() when operands are constant. 5862 auto *Const42 = 5863 sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 42); 5864 auto *NewConstCmp = 5865 sandboxir::CmpInst::create(llvm::CmpInst::ICMP_ULE, Const42, Const42, 5866 BB->begin(), Ctx, "NewConstCmp"); 5867 EXPECT_TRUE(isa<sandboxir::Constant>(NewConstCmp)); 5868 } 5869 } 5870 5871 TEST_F(SandboxIRTest, FCmpInst) { 5872 SCOPED_TRACE("SandboxIRTest sandboxir::FCmpInst tests"); 5873 parseIR(C, R"IR( 5874 define void @foo(float %f0, float %f1) { 5875 bb: 5876 %ffalse = fcmp false float %f0, %f1 5877 %foeq = fcmp oeq float %f0, %f1 5878 %fogt = fcmp ogt float %f0, %f1 5879 %folt = fcmp olt float %f0, %f1 5880 %fole = fcmp ole float %f0, %f1 5881 %fone = fcmp one float %f0, %f1 5882 %ford = fcmp ord float %f0, %f1 5883 %funo = fcmp uno float %f0, %f1 5884 %fueq = fcmp ueq float %f0, %f1 5885 %fugt = fcmp ugt float %f0, %f1 5886 %fuge = fcmp uge float %f0, %f1 5887 %fult = fcmp ult float %f0, %f1 5888 %fule = fcmp ule float %f0, %f1 5889 %fune = fcmp une float %f0, %f1 5890 %ftrue = fcmp true float %f0, %f1 5891 ret void 5892 bb1: 5893 %copyfrom = fadd reassoc float %f0, 42.0 5894 ret void 5895 } 5896 )IR"); 5897 Function &LLVMF = *M->getFunction("foo"); 5898 sandboxir::Context Ctx(C); 5899 [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF); 5900 5901 auto *LLVMBB = getBasicBlockByName(LLVMF, "bb"); 5902 auto LLVMIt = LLVMBB->begin(); 5903 auto *BB = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB)); 5904 auto It = BB->begin(); 5905 // Check classof() 5906 while (auto *FCmp = dyn_cast<sandboxir::ICmpInst>(&*It++)) { 5907 auto *LLVMFCmp = cast<llvm::ICmpInst>(&*LLVMIt++); 5908 checkSwapOperands(Ctx, FCmp, LLVMFCmp); 5909 checkCommonPredicates(FCmp, LLVMFCmp); 5910 } 5911 5912 auto *LLVMBB1 = getBasicBlockByName(LLVMF, "bb1"); 5913 auto *BB1 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB1)); 5914 auto It1 = BB1->begin(); 5915 auto *CopyFrom = &*It1++; 5916 CopyFrom->setFastMathFlags(FastMathFlags::getFast()); 5917 5918 // create with default flags 5919 auto *NewFCmp = cast<sandboxir::CmpInst>(sandboxir::CmpInst::create( 5920 llvm::CmpInst::FCMP_ONE, F.getArg(0), F.getArg(1), It1, Ctx, "NewFCmp")); 5921 EXPECT_EQ(NewFCmp->getPredicate(), llvm::CmpInst::FCMP_ONE); 5922 EXPECT_EQ(NewFCmp->getOperand(0), F.getArg(0)); 5923 EXPECT_EQ(NewFCmp->getOperand(1), F.getArg(1)); 5924 #ifndef NDEBUG 5925 EXPECT_EQ(NewFCmp->getName(), "NewFCmp"); 5926 #endif // NDEBUG 5927 FastMathFlags DefaultFMF = NewFCmp->getFastMathFlags(); 5928 EXPECT_TRUE(CopyFrom->getFastMathFlags() != DefaultFMF); 5929 // create with copied flags 5930 auto *NewFCmpFlags = 5931 cast<sandboxir::CmpInst>(sandboxir::CmpInst::createWithCopiedFlags( 5932 llvm::CmpInst::FCMP_ONE, F.getArg(0), F.getArg(1), CopyFrom, It1, Ctx, 5933 "NewFCmpFlags")); 5934 EXPECT_FALSE(NewFCmpFlags->getFastMathFlags() != 5935 CopyFrom->getFastMathFlags()); 5936 EXPECT_EQ(NewFCmpFlags->getPredicate(), llvm::CmpInst::FCMP_ONE); 5937 EXPECT_EQ(NewFCmpFlags->getOperand(0), F.getArg(0)); 5938 EXPECT_EQ(NewFCmpFlags->getOperand(1), F.getArg(1)); 5939 #ifndef NDEBUG 5940 EXPECT_EQ(NewFCmpFlags->getName(), "NewFCmpFlags"); 5941 #endif // NDEBUG 5942 5943 { 5944 // Check create() when operands are constant. 5945 auto *Const42 = 5946 sandboxir::ConstantFP::get(sandboxir::Type::getFloatTy(Ctx), 42.0); 5947 auto *NewConstCmp = 5948 sandboxir::CmpInst::create(llvm::CmpInst::FCMP_ULE, Const42, Const42, 5949 BB->begin(), Ctx, "NewConstCmp"); 5950 EXPECT_TRUE(isa<sandboxir::Constant>(NewConstCmp)); 5951 } 5952 } 5953 5954 TEST_F(SandboxIRTest, UnreachableInst) { 5955 parseIR(C, R"IR( 5956 define void @foo() { 5957 unreachable 5958 } 5959 )IR"); 5960 llvm::Function *LLVMF = &*M->getFunction("foo"); 5961 sandboxir::Context Ctx(C); 5962 sandboxir::Function *F = Ctx.createFunction(LLVMF); 5963 auto *BB = &*F->begin(); 5964 auto It = BB->begin(); 5965 auto *UI = cast<sandboxir::UnreachableInst>(&*It++); 5966 5967 EXPECT_EQ(UI->getNumSuccessors(), 0u); 5968 EXPECT_EQ(UI->getNumOfIRInstrs(), 1u); 5969 // Check create(InsertBefore) 5970 sandboxir::UnreachableInst *NewUI = 5971 sandboxir::UnreachableInst::create(UI->getIterator(), Ctx); 5972 EXPECT_EQ(NewUI->getNextNode(), UI); 5973 // Check create(InsertAtEnd) 5974 sandboxir::UnreachableInst *NewUIEnd = 5975 sandboxir::UnreachableInst::create(/*InsertAtEnd=*/BB, Ctx); 5976 EXPECT_EQ(NewUIEnd->getParent(), BB); 5977 EXPECT_EQ(NewUIEnd->getNextNode(), nullptr); 5978 } 5979 5980 /// Makes sure that all Instruction sub-classes have a classof(). 5981 TEST_F(SandboxIRTest, CheckClassof) { 5982 #define DEF_INSTR(ID, OPC, CLASS) \ 5983 EXPECT_NE(&sandboxir::CLASS::classof, &sandboxir::Instruction::classof); 5984 #include "llvm/SandboxIR/Values.def" 5985 } 5986 5987 TEST_F(SandboxIRTest, InstructionCallbacks) { 5988 parseIR(C, R"IR( 5989 define void @foo(ptr %ptr, i8 %val) { 5990 ret void 5991 } 5992 )IR"); 5993 Function &LLVMF = *M->getFunction("foo"); 5994 sandboxir::Context Ctx(C); 5995 5996 auto &F = *Ctx.createFunction(&LLVMF); 5997 auto &BB = *F.begin(); 5998 sandboxir::Argument *Ptr = F.getArg(0); 5999 sandboxir::Argument *Val = F.getArg(1); 6000 sandboxir::Instruction *Ret = &BB.front(); 6001 6002 SmallVector<sandboxir::Instruction *> Inserted; 6003 auto InsertCbId = Ctx.registerCreateInstrCallback( 6004 [&Inserted](sandboxir::Instruction *I) { Inserted.push_back(I); }); 6005 6006 SmallVector<sandboxir::Instruction *> Removed; 6007 auto RemoveCbId = Ctx.registerEraseInstrCallback( 6008 [&Removed](sandboxir::Instruction *I) { Removed.push_back(I); }); 6009 6010 // Keep the moved instruction and the instruction pointed by the Where 6011 // iterator so we can check both callback arguments work as expected. 6012 SmallVector<std::pair<sandboxir::Instruction *, sandboxir::Instruction *>> 6013 Moved; 6014 auto MoveCbId = Ctx.registerMoveInstrCallback( 6015 [&Moved](sandboxir::Instruction *I, const sandboxir::BBIterator &Where) { 6016 // Use a nullptr to signal "move to end" to keep it single. We only 6017 // have a basic block in this test case anyway. 6018 if (Where == Where.getNodeParent()->end()) 6019 Moved.push_back(std::make_pair(I, nullptr)); 6020 else 6021 Moved.push_back(std::make_pair(I, &*Where)); 6022 }); 6023 6024 // Two more insertion callbacks, to check that they're called in registration 6025 // order. 6026 SmallVector<int> Order; 6027 auto CheckOrderInsertCbId1 = Ctx.registerCreateInstrCallback( 6028 [&Order](sandboxir::Instruction *I) { Order.push_back(1); }); 6029 6030 auto CheckOrderInsertCbId2 = Ctx.registerCreateInstrCallback( 6031 [&Order](sandboxir::Instruction *I) { Order.push_back(2); }); 6032 6033 Ctx.save(); 6034 auto *NewI = sandboxir::StoreInst::create(Val, Ptr, /*Align=*/std::nullopt, 6035 Ret->getIterator(), Ctx); 6036 EXPECT_THAT(Inserted, testing::ElementsAre(NewI)); 6037 EXPECT_THAT(Removed, testing::IsEmpty()); 6038 EXPECT_THAT(Moved, testing::IsEmpty()); 6039 EXPECT_THAT(Order, testing::ElementsAre(1, 2)); 6040 6041 Ret->moveBefore(NewI); 6042 EXPECT_THAT(Inserted, testing::ElementsAre(NewI)); 6043 EXPECT_THAT(Removed, testing::IsEmpty()); 6044 EXPECT_THAT(Moved, testing::ElementsAre(std::make_pair(Ret, NewI))); 6045 6046 Ret->eraseFromParent(); 6047 EXPECT_THAT(Inserted, testing::ElementsAre(NewI)); 6048 EXPECT_THAT(Removed, testing::ElementsAre(Ret)); 6049 EXPECT_THAT(Moved, testing::ElementsAre(std::make_pair(Ret, NewI))); 6050 6051 NewI->eraseFromParent(); 6052 EXPECT_THAT(Inserted, testing::ElementsAre(NewI)); 6053 EXPECT_THAT(Removed, testing::ElementsAre(Ret, NewI)); 6054 EXPECT_THAT(Moved, testing::ElementsAre(std::make_pair(Ret, NewI))); 6055 6056 // Check that after revert the callbacks have been called for the inverse 6057 // operations of the changes made so far. 6058 Ctx.revert(); 6059 EXPECT_THAT(Inserted, testing::ElementsAre(NewI, NewI, Ret)); 6060 EXPECT_THAT(Removed, testing::ElementsAre(Ret, NewI, NewI)); 6061 EXPECT_THAT(Moved, testing::ElementsAre(std::make_pair(Ret, NewI), 6062 std::make_pair(Ret, nullptr))); 6063 EXPECT_THAT(Order, testing::ElementsAre(1, 2, 1, 2, 1, 2)); 6064 6065 // Check that deregistration works. Do an operation of each type after 6066 // deregistering callbacks and check. 6067 Inserted.clear(); 6068 Removed.clear(); 6069 Moved.clear(); 6070 Ctx.unregisterCreateInstrCallback(InsertCbId); 6071 Ctx.unregisterEraseInstrCallback(RemoveCbId); 6072 Ctx.unregisterMoveInstrCallback(MoveCbId); 6073 Ctx.unregisterCreateInstrCallback(CheckOrderInsertCbId1); 6074 Ctx.unregisterCreateInstrCallback(CheckOrderInsertCbId2); 6075 auto *NewI2 = sandboxir::StoreInst::create(Val, Ptr, /*Align=*/std::nullopt, 6076 Ret->getIterator(), Ctx); 6077 Ret->moveBefore(NewI2); 6078 Ret->eraseFromParent(); 6079 EXPECT_THAT(Inserted, testing::IsEmpty()); 6080 EXPECT_THAT(Removed, testing::IsEmpty()); 6081 EXPECT_THAT(Moved, testing::IsEmpty()); 6082 } 6083 6084 TEST_F(SandboxIRTest, FunctionObjectAlreadyExists) { 6085 parseIR(C, R"IR( 6086 define void @foo() { 6087 call void @bar() 6088 ret void 6089 } 6090 define void @bar() { 6091 ret void 6092 } 6093 )IR"); 6094 Function &LLVMFoo = *M->getFunction("foo"); 6095 Function &LLVMBar = *M->getFunction("bar"); 6096 sandboxir::Context Ctx(C); 6097 // This will create a Function object for @bar(). 6098 Ctx.createFunction(&LLVMFoo); 6099 EXPECT_NE(Ctx.getValue(&LLVMBar), nullptr); 6100 // This should not crash, even though there is already a value for LLVMBar. 6101 Ctx.createFunction(&LLVMBar); 6102 } 6103