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