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