brintos

brintos / llvm-project-archived public Read only

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