brintos

brintos / llvm-project-archived public Read only

0
0
Text · 48.5 KiB · 4d5bbe9 Raw
1314 lines · cpp
1//===- llvm/unittest/IR/IRBuilderTest.cpp - IRBuilder tests ---------------===//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/IR/IRBuilder.h"10#include "llvm/Analysis/InstSimplifyFolder.h"11#include "llvm/IR/BasicBlock.h"12#include "llvm/IR/DIBuilder.h"13#include "llvm/IR/DataLayout.h"14#include "llvm/IR/DebugInfoMetadata.h"15#include "llvm/IR/Function.h"16#include "llvm/IR/IntrinsicInst.h"17#include "llvm/IR/IntrinsicsAArch64.h"18#include "llvm/IR/LLVMContext.h"19#include "llvm/IR/MDBuilder.h"20#include "llvm/IR/Module.h"21#include "llvm/IR/NoFolder.h"22#include "llvm/IR/Verifier.h"23#include "gmock/gmock.h"24#include "gtest/gtest.h"25 26#include <type_traits>27 28using namespace llvm;29using ::testing::UnorderedElementsAre;30 31namespace {32 33class IRBuilderTest : public testing::Test {34protected:35  void SetUp() override {36    M.reset(new Module("MyModule", Ctx));37    FunctionType *FTy = FunctionType::get(Type::getVoidTy(Ctx),38                                          /*isVarArg=*/false);39    F = Function::Create(FTy, Function::ExternalLinkage, "", M.get());40    BB = BasicBlock::Create(Ctx, "", F);41    GV = new GlobalVariable(*M, Type::getFloatTy(Ctx), true,42                            GlobalValue::ExternalLinkage, nullptr);43  }44 45  void TearDown() override {46    BB = nullptr;47    M.reset();48  }49 50  LLVMContext Ctx;51  std::unique_ptr<Module> M;52  Function *F;53  BasicBlock *BB;54  GlobalVariable *GV;55};56 57TEST_F(IRBuilderTest, Intrinsics) {58  IRBuilder<> Builder(BB);59  Value *V;60  Instruction *I;61  Value *Result;62  IntrinsicInst *II;63 64  V = Builder.CreateLoad(GV->getValueType(), GV);65  I = cast<Instruction>(Builder.CreateFAdd(V, V));66  I->setHasNoInfs(true);67  I->setHasNoNaNs(false);68 69  Result = Builder.CreateMinNum(V, V);70  II = cast<IntrinsicInst>(Result);71  EXPECT_EQ(II->getIntrinsicID(), Intrinsic::minnum);72 73  Result = Builder.CreateMaxNum(V, V);74  II = cast<IntrinsicInst>(Result);75  EXPECT_EQ(II->getIntrinsicID(), Intrinsic::maxnum);76 77  Result = Builder.CreateMinimum(V, V);78  II = cast<IntrinsicInst>(Result);79  EXPECT_EQ(II->getIntrinsicID(), Intrinsic::minimum);80 81  Result = Builder.CreateMaximum(V, V);82  II = cast<IntrinsicInst>(Result);83  EXPECT_EQ(II->getIntrinsicID(), Intrinsic::maximum);84 85  Result = Builder.CreateIntrinsic(Intrinsic::readcyclecounter,86                                   ArrayRef<Type *>{}, {});87  II = cast<IntrinsicInst>(Result);88  EXPECT_EQ(II->getIntrinsicID(), Intrinsic::readcyclecounter);89 90  Result = Builder.CreateIntrinsic(Intrinsic::readcyclecounter, {});91  II = cast<IntrinsicInst>(Result);92  EXPECT_EQ(II->getIntrinsicID(), Intrinsic::readcyclecounter);93 94  Result = Builder.CreateUnaryIntrinsic(Intrinsic::fabs, V);95  II = cast<IntrinsicInst>(Result);96  EXPECT_EQ(II->getIntrinsicID(), Intrinsic::fabs);97  EXPECT_FALSE(II->hasNoInfs());98  EXPECT_FALSE(II->hasNoNaNs());99 100  Result = Builder.CreateUnaryIntrinsic(Intrinsic::fabs, V, I);101  II = cast<IntrinsicInst>(Result);102  EXPECT_EQ(II->getIntrinsicID(), Intrinsic::fabs);103  EXPECT_TRUE(II->hasNoInfs());104  EXPECT_FALSE(II->hasNoNaNs());105 106  Result = Builder.CreateBinaryIntrinsic(Intrinsic::pow, V, V);107  II = cast<IntrinsicInst>(Result);108  EXPECT_EQ(II->getIntrinsicID(), Intrinsic::pow);109  EXPECT_FALSE(II->hasNoInfs());110  EXPECT_FALSE(II->hasNoNaNs());111 112  Result = Builder.CreateBinaryIntrinsic(Intrinsic::pow, V, V, I);113  II = cast<IntrinsicInst>(Result);114  EXPECT_EQ(II->getIntrinsicID(), Intrinsic::pow);115  EXPECT_TRUE(II->hasNoInfs());116  EXPECT_FALSE(II->hasNoNaNs());117 118  Result = Builder.CreateFMA(V, V, V);119  II = cast<IntrinsicInst>(Result);120  EXPECT_EQ(II->getIntrinsicID(), Intrinsic::fma);121  EXPECT_FALSE(II->hasNoInfs());122  EXPECT_FALSE(II->hasNoNaNs());123 124  Result = Builder.CreateFMA(V, V, V, I);125  II = cast<IntrinsicInst>(Result);126  EXPECT_EQ(II->getIntrinsicID(), Intrinsic::fma);127  EXPECT_TRUE(II->hasNoInfs());128  EXPECT_FALSE(II->hasNoNaNs());129 130  Result = Builder.CreateFMA(V, V, V, FastMathFlags::getFast());131  II = cast<IntrinsicInst>(Result);132  EXPECT_EQ(II->getIntrinsicID(), Intrinsic::fma);133  EXPECT_TRUE(II->hasNoInfs());134  EXPECT_TRUE(II->hasNoNaNs());135 136  Result = Builder.CreateUnaryIntrinsic(Intrinsic::roundeven, V);137  II = cast<IntrinsicInst>(Result);138  EXPECT_EQ(II->getIntrinsicID(), Intrinsic::roundeven);139  EXPECT_FALSE(II->hasNoInfs());140  EXPECT_FALSE(II->hasNoNaNs());141 142  Result = Builder.CreateIntrinsic(143      Intrinsic::set_rounding,144      {Builder.getInt32(static_cast<uint32_t>(RoundingMode::TowardZero))});145  II = cast<IntrinsicInst>(Result);146  EXPECT_EQ(II->getIntrinsicID(), Intrinsic::set_rounding);147}148 149TEST_F(IRBuilderTest, IntrinsicMangling) {150  IRBuilder<> Builder(BB);151  Type *VoidTy = Builder.getVoidTy();152  Type *Int64Ty = Builder.getInt64Ty();153  Value *Int64Val = Builder.getInt64(0);154  Value *DoubleVal = PoisonValue::get(Builder.getDoubleTy());155  CallInst *Call;156 157  // Mangled return type, no arguments.158  Call = Builder.CreateIntrinsic(Int64Ty, Intrinsic::coro_size, {});159  EXPECT_EQ(Call->getCalledFunction()->getName(), "llvm.coro.size.i64");160 161  // Void return type, mangled argument type.162  Call =163      Builder.CreateIntrinsic(VoidTy, Intrinsic::set_loop_iterations, Int64Val);164  EXPECT_EQ(Call->getCalledFunction()->getName(),165            "llvm.set.loop.iterations.i64");166 167  // Mangled return type and argument type.168  Call = Builder.CreateIntrinsic(Int64Ty, Intrinsic::lround, DoubleVal);169  EXPECT_EQ(Call->getCalledFunction()->getName(), "llvm.lround.i64.f64");170}171 172TEST_F(IRBuilderTest, IntrinsicsWithScalableVectors) {173  IRBuilder<> Builder(BB);174  CallInst *Call;175  FunctionType *FTy;176 177  // Test scalable flag isn't dropped for intrinsic that is explicitly defined178  // with scalable vectors, e.g. LLVMType<nxv4i32>.179  Type *SrcVecTy = VectorType::get(Builder.getHalfTy(), 8, true);180  Type *DstVecTy = VectorType::get(Builder.getInt32Ty(), 4, true);181  Type *PredTy = VectorType::get(Builder.getInt1Ty(), 4, true);182 183  SmallVector<Value *, 3> Args;184  Args.push_back(UndefValue::get(DstVecTy));185  Args.push_back(UndefValue::get(PredTy));186  Args.push_back(UndefValue::get(SrcVecTy));187 188  Call = Builder.CreateIntrinsic(Intrinsic::aarch64_sve_fcvtzs_i32f16, Args,189                                 nullptr, "aarch64.sve.fcvtzs.i32f16");190  FTy = Call->getFunctionType();191  EXPECT_EQ(FTy->getReturnType(), DstVecTy);192  for (unsigned i = 0; i != Args.size(); ++i)193    EXPECT_EQ(FTy->getParamType(i), Args[i]->getType());194 195  // Test scalable flag isn't dropped for intrinsic defined with196  // LLVMScalarOrSameVectorWidth.197 198  Type *VecTy = VectorType::get(Builder.getInt32Ty(), 4, true);199  Type *PtrToVecTy = Builder.getPtrTy();200  PredTy = VectorType::get(Builder.getInt1Ty(), 4, true);201 202  Args.clear();203  Args.push_back(UndefValue::get(PtrToVecTy));204  Args.push_back(UndefValue::get(PredTy));205  Args.push_back(UndefValue::get(VecTy));206 207  Call = Builder.CreateIntrinsic(Intrinsic::masked_load, {VecTy, PtrToVecTy},208                                 Args, nullptr, "masked.load");209  FTy = Call->getFunctionType();210  EXPECT_EQ(FTy->getReturnType(), VecTy);211  for (unsigned i = 0; i != Args.size(); ++i)212    EXPECT_EQ(FTy->getParamType(i), Args[i]->getType());213}214 215TEST_F(IRBuilderTest, CreateStepVector) {216  IRBuilder<> Builder(BB);217 218  // Fixed width vectors219  Type *DstVecTy = VectorType::get(Builder.getInt32Ty(), 4, false);220  Value *StepVec = Builder.CreateStepVector(DstVecTy);221  EXPECT_TRUE(isa<Constant>(StepVec));222  EXPECT_EQ(StepVec->getType(), DstVecTy);223 224  const auto *VectorValue = cast<Constant>(StepVec);225  for (unsigned i = 0; i < 4; i++) {226    EXPECT_TRUE(isa<ConstantInt>(VectorValue->getAggregateElement(i)));227    ConstantInt *El = cast<ConstantInt>(VectorValue->getAggregateElement(i));228    EXPECT_EQ(El->getValue(), i);229  }230 231  // Scalable vectors232  DstVecTy = VectorType::get(Builder.getInt32Ty(), 4, true);233  StepVec = Builder.CreateStepVector(DstVecTy);234  EXPECT_TRUE(isa<CallInst>(StepVec));235  CallInst *Call = cast<CallInst>(StepVec);236  FunctionType *FTy = Call->getFunctionType();237  EXPECT_EQ(FTy->getReturnType(), DstVecTy);238  EXPECT_EQ(Call->getIntrinsicID(), Intrinsic::stepvector);239}240 241TEST_F(IRBuilderTest, CreateStepVectorI3) {242  IRBuilder<> Builder(BB);243 244  // Scalable vectors245  Type *DstVecTy = VectorType::get(IntegerType::get(Ctx, 3), 2, true);246  Type *VecI8Ty = VectorType::get(Builder.getInt8Ty(), 2, true);247  Value *StepVec = Builder.CreateStepVector(DstVecTy);248  EXPECT_TRUE(isa<TruncInst>(StepVec));249  TruncInst *Trunc = cast<TruncInst>(StepVec);250  EXPECT_EQ(Trunc->getDestTy(), DstVecTy);251  EXPECT_EQ(Trunc->getSrcTy(), VecI8Ty);252  EXPECT_TRUE(isa<CallInst>(Trunc->getOperand(0)));253 254  CallInst *Call = cast<CallInst>(Trunc->getOperand(0));255  FunctionType *FTy = Call->getFunctionType();256  EXPECT_EQ(FTy->getReturnType(), VecI8Ty);257  EXPECT_EQ(Call->getIntrinsicID(), Intrinsic::stepvector);258}259 260TEST_F(IRBuilderTest, ConstrainedFP) {261  IRBuilder<> Builder(BB);262  Value *V;263  Value *VDouble;264  Value *VInt;265  CallInst *Call;266  IntrinsicInst *II;267  GlobalVariable *GVDouble = new GlobalVariable(*M, Type::getDoubleTy(Ctx),268                            true, GlobalValue::ExternalLinkage, nullptr);269 270  V = Builder.CreateLoad(GV->getValueType(), GV);271  VDouble = Builder.CreateLoad(GVDouble->getValueType(), GVDouble);272 273  // See if we get constrained intrinsics instead of non-constrained274  // instructions.275  Builder.setIsFPConstrained(true);276  auto Parent = BB->getParent();277  Parent->addFnAttr(Attribute::StrictFP);278 279  V = Builder.CreateFAdd(V, V);280  ASSERT_TRUE(isa<IntrinsicInst>(V));281  II = cast<IntrinsicInst>(V);282  EXPECT_EQ(II->getIntrinsicID(), Intrinsic::experimental_constrained_fadd);283 284  V = Builder.CreateFSub(V, V);285  ASSERT_TRUE(isa<IntrinsicInst>(V));286  II = cast<IntrinsicInst>(V);287  EXPECT_EQ(II->getIntrinsicID(), Intrinsic::experimental_constrained_fsub);288 289  V = Builder.CreateFMul(V, V);290  ASSERT_TRUE(isa<IntrinsicInst>(V));291  II = cast<IntrinsicInst>(V);292  EXPECT_EQ(II->getIntrinsicID(), Intrinsic::experimental_constrained_fmul);293  294  V = Builder.CreateFDiv(V, V);295  ASSERT_TRUE(isa<IntrinsicInst>(V));296  II = cast<IntrinsicInst>(V);297  EXPECT_EQ(II->getIntrinsicID(), Intrinsic::experimental_constrained_fdiv);298  299  V = Builder.CreateFRem(V, V);300  ASSERT_TRUE(isa<IntrinsicInst>(V));301  II = cast<IntrinsicInst>(V);302  EXPECT_EQ(II->getIntrinsicID(), Intrinsic::experimental_constrained_frem);303 304  V = Builder.CreateFMA(V, V, V);305  ASSERT_TRUE(isa<IntrinsicInst>(V));306  II = cast<IntrinsicInst>(V);307  EXPECT_EQ(II->getIntrinsicID(), Intrinsic::experimental_constrained_fma);308 309  VInt = Builder.CreateFPToUI(VDouble, Builder.getInt32Ty());310  ASSERT_TRUE(isa<IntrinsicInst>(VInt));311  II = cast<IntrinsicInst>(VInt);312  EXPECT_EQ(II->getIntrinsicID(), Intrinsic::experimental_constrained_fptoui);313 314  VInt = Builder.CreateFPToSI(VDouble, Builder.getInt32Ty());315  ASSERT_TRUE(isa<IntrinsicInst>(VInt));316  II = cast<IntrinsicInst>(VInt);317  EXPECT_EQ(II->getIntrinsicID(), Intrinsic::experimental_constrained_fptosi);318 319  VDouble = Builder.CreateUIToFP(VInt, Builder.getDoubleTy());320  ASSERT_TRUE(isa<IntrinsicInst>(VDouble));321  II = cast<IntrinsicInst>(VDouble);322  EXPECT_EQ(II->getIntrinsicID(), Intrinsic::experimental_constrained_uitofp);323 324  VDouble = Builder.CreateSIToFP(VInt, Builder.getDoubleTy());325  ASSERT_TRUE(isa<IntrinsicInst>(VDouble));326  II = cast<IntrinsicInst>(VDouble);327  EXPECT_EQ(II->getIntrinsicID(), Intrinsic::experimental_constrained_sitofp);328 329  V = Builder.CreateFPTrunc(VDouble, Type::getFloatTy(Ctx));330  ASSERT_TRUE(isa<IntrinsicInst>(V));331  II = cast<IntrinsicInst>(V);332  EXPECT_EQ(II->getIntrinsicID(), Intrinsic::experimental_constrained_fptrunc);333 334  VDouble = Builder.CreateFPExt(V, Type::getDoubleTy(Ctx));335  ASSERT_TRUE(isa<IntrinsicInst>(VDouble));336  II = cast<IntrinsicInst>(VDouble);337  EXPECT_EQ(II->getIntrinsicID(), Intrinsic::experimental_constrained_fpext);338 339  // Verify attributes on the call are created automatically.340  AttributeSet CallAttrs = II->getAttributes().getFnAttrs();341  EXPECT_EQ(CallAttrs.hasAttribute(Attribute::StrictFP), true);342 343  // Verify attributes on the containing function are created when requested.344  Builder.setConstrainedFPFunctionAttr();345  AttributeList Attrs = BB->getParent()->getAttributes();346  AttributeSet FnAttrs = Attrs.getFnAttrs();347  EXPECT_EQ(FnAttrs.hasAttribute(Attribute::StrictFP), true);348 349  // Verify the codepaths for setting and overriding the default metadata.350  V = Builder.CreateFAdd(V, V);351  ASSERT_TRUE(isa<ConstrainedFPIntrinsic>(V));352  auto *CII = cast<ConstrainedFPIntrinsic>(V);353  EXPECT_EQ(fp::ebStrict, CII->getExceptionBehavior());354  EXPECT_EQ(RoundingMode::Dynamic, CII->getRoundingMode());355 356  Builder.setDefaultConstrainedExcept(fp::ebIgnore);357  Builder.setDefaultConstrainedRounding(RoundingMode::TowardPositive);358  V = Builder.CreateFAdd(V, V);359  CII = cast<ConstrainedFPIntrinsic>(V);360  EXPECT_EQ(fp::ebIgnore, CII->getExceptionBehavior());361  EXPECT_EQ(CII->getRoundingMode(), RoundingMode::TowardPositive);362 363  Builder.setDefaultConstrainedExcept(fp::ebIgnore);364  Builder.setDefaultConstrainedRounding(RoundingMode::NearestTiesToEven);365  V = Builder.CreateFAdd(V, V);366  CII = cast<ConstrainedFPIntrinsic>(V);367  EXPECT_EQ(fp::ebIgnore, CII->getExceptionBehavior());368  EXPECT_EQ(RoundingMode::NearestTiesToEven, CII->getRoundingMode());369 370  Builder.setDefaultConstrainedExcept(fp::ebMayTrap);371  Builder.setDefaultConstrainedRounding(RoundingMode::TowardNegative);372  V = Builder.CreateFAdd(V, V);373  CII = cast<ConstrainedFPIntrinsic>(V);374  EXPECT_EQ(fp::ebMayTrap, CII->getExceptionBehavior());375  EXPECT_EQ(RoundingMode::TowardNegative, CII->getRoundingMode());376 377  Builder.setDefaultConstrainedExcept(fp::ebStrict);378  Builder.setDefaultConstrainedRounding(RoundingMode::TowardZero);379  V = Builder.CreateFAdd(V, V);380  CII = cast<ConstrainedFPIntrinsic>(V);381  EXPECT_EQ(fp::ebStrict, CII->getExceptionBehavior());382  EXPECT_EQ(RoundingMode::TowardZero, CII->getRoundingMode());383 384  Builder.setDefaultConstrainedExcept(fp::ebIgnore);385  Builder.setDefaultConstrainedRounding(RoundingMode::Dynamic);386  V = Builder.CreateFAdd(V, V);387  CII = cast<ConstrainedFPIntrinsic>(V);388  EXPECT_EQ(fp::ebIgnore, CII->getExceptionBehavior());389  EXPECT_EQ(RoundingMode::Dynamic, CII->getRoundingMode());390 391  // Now override the defaults.392  Call = Builder.CreateConstrainedFPBinOp(393        Intrinsic::experimental_constrained_fadd, V, V, nullptr, "", nullptr,394        RoundingMode::TowardNegative, fp::ebMayTrap);395  CII = cast<ConstrainedFPIntrinsic>(Call);396  EXPECT_EQ(CII->getIntrinsicID(), Intrinsic::experimental_constrained_fadd);397  EXPECT_EQ(fp::ebMayTrap, CII->getExceptionBehavior());398  EXPECT_EQ(RoundingMode::TowardNegative, CII->getRoundingMode());399 400  // Same as previous test for CreateConstrainedFPIntrinsic401  Call = Builder.CreateConstrainedFPIntrinsic(402      Intrinsic::experimental_constrained_fadd, {V->getType()}, {V, V}, nullptr,403      "", nullptr, RoundingMode::TowardNegative, fp::ebMayTrap);404  CII = cast<ConstrainedFPIntrinsic>(Call);405  EXPECT_EQ(CII->getIntrinsicID(), Intrinsic::experimental_constrained_fadd);406  EXPECT_EQ(fp::ebMayTrap, CII->getExceptionBehavior());407  EXPECT_EQ(RoundingMode::TowardNegative, CII->getRoundingMode());408 409  Builder.CreateRetVoid();410  EXPECT_FALSE(verifyModule(*M));411}412 413TEST_F(IRBuilderTest, ConstrainedFPIntrinsics) {414  IRBuilder<> Builder(BB);415  Value *V;416  Value *VDouble;417  ConstrainedFPIntrinsic *CII;418  GlobalVariable *GVDouble = new GlobalVariable(419      *M, Type::getDoubleTy(Ctx), true, GlobalValue::ExternalLinkage, nullptr);420  VDouble = Builder.CreateLoad(GVDouble->getValueType(), GVDouble);421 422  Builder.setDefaultConstrainedExcept(fp::ebStrict);423  Builder.setDefaultConstrainedRounding(RoundingMode::TowardZero);424  Function *Fn = Intrinsic::getOrInsertDeclaration(425      M.get(), Intrinsic::experimental_constrained_roundeven,426      {Type::getDoubleTy(Ctx)});427  V = Builder.CreateConstrainedFPCall(Fn, { VDouble });428  CII = cast<ConstrainedFPIntrinsic>(V);429  EXPECT_EQ(Intrinsic::experimental_constrained_roundeven, CII->getIntrinsicID());430  EXPECT_EQ(fp::ebStrict, CII->getExceptionBehavior());431}432 433TEST_F(IRBuilderTest, ConstrainedFPFunctionCall) {434  IRBuilder<> Builder(BB);435 436  // Create an empty constrained FP function.437  FunctionType *FTy = FunctionType::get(Type::getVoidTy(Ctx),438                                        /*isVarArg=*/false);439  Function *Callee =440      Function::Create(FTy, Function::ExternalLinkage, "", M.get());441  BasicBlock *CalleeBB = BasicBlock::Create(Ctx, "", Callee);442  IRBuilder<> CalleeBuilder(CalleeBB);443  CalleeBuilder.setIsFPConstrained(true);444  CalleeBuilder.setConstrainedFPFunctionAttr();445  CalleeBuilder.CreateRetVoid();446 447  // Now call the empty constrained FP function.448  Builder.setIsFPConstrained(true);449  Builder.setConstrainedFPFunctionAttr();450  CallInst *FCall = Builder.CreateCall(Callee, {});451 452  // Check the attributes to verify the strictfp attribute is on the call.453  EXPECT_TRUE(454      FCall->getAttributes().getFnAttrs().hasAttribute(Attribute::StrictFP));455 456  Builder.CreateRetVoid();457  EXPECT_FALSE(verifyModule(*M));458}459 460TEST_F(IRBuilderTest, Lifetime) {461  IRBuilder<> Builder(BB);462  AllocaInst *Var1 = Builder.CreateAlloca(Builder.getInt8Ty());463  AllocaInst *Var2 = Builder.CreateAlloca(Builder.getInt32Ty());464  AllocaInst *Var3 = Builder.CreateAlloca(Builder.getInt8Ty(),465                                          Builder.getInt32(123));466 467  CallInst *Start1 = Builder.CreateLifetimeStart(Var1);468  CallInst *Start2 = Builder.CreateLifetimeStart(Var2);469  CallInst *Start3 = Builder.CreateLifetimeStart(Var3);470 471  EXPECT_EQ(Start1->getArgOperand(0), Var1);472  EXPECT_EQ(Start2->getArgOperand(0), Var2);473  EXPECT_EQ(Start3->getArgOperand(0), Var3);474 475  Value *End1 = Builder.CreateLifetimeEnd(Var1);476  Builder.CreateLifetimeEnd(Var2);477  Builder.CreateLifetimeEnd(Var3);478 479  IntrinsicInst *II_Start1 = dyn_cast<IntrinsicInst>(Start1);480  IntrinsicInst *II_End1 = dyn_cast<IntrinsicInst>(End1);481  ASSERT_TRUE(II_Start1 != nullptr);482  EXPECT_EQ(II_Start1->getIntrinsicID(), Intrinsic::lifetime_start);483  ASSERT_TRUE(II_End1 != nullptr);484  EXPECT_EQ(II_End1->getIntrinsicID(), Intrinsic::lifetime_end);485}486 487TEST_F(IRBuilderTest, CreateCondBr) {488  IRBuilder<> Builder(BB);489  BasicBlock *TBB = BasicBlock::Create(Ctx, "", F);490  BasicBlock *FBB = BasicBlock::Create(Ctx, "", F);491 492  BranchInst *BI = Builder.CreateCondBr(Builder.getTrue(), TBB, FBB);493  Instruction *TI = BB->getTerminator();494  EXPECT_EQ(BI, TI);495  EXPECT_EQ(2u, TI->getNumSuccessors());496  EXPECT_EQ(TBB, TI->getSuccessor(0));497  EXPECT_EQ(FBB, TI->getSuccessor(1));498 499  BI->eraseFromParent();500  MDNode *Weights = MDBuilder(Ctx).createBranchWeights(42, 13);501  BI = Builder.CreateCondBr(Builder.getTrue(), TBB, FBB, Weights);502  TI = BB->getTerminator();503  EXPECT_EQ(BI, TI);504  EXPECT_EQ(2u, TI->getNumSuccessors());505  EXPECT_EQ(TBB, TI->getSuccessor(0));506  EXPECT_EQ(FBB, TI->getSuccessor(1));507  EXPECT_EQ(Weights, TI->getMetadata(LLVMContext::MD_prof));508}509 510TEST_F(IRBuilderTest, LandingPadName) {511  IRBuilder<> Builder(BB);512  LandingPadInst *LP = Builder.CreateLandingPad(Builder.getInt32Ty(), 0, "LP");513  EXPECT_EQ(LP->getName(), "LP");514}515 516TEST_F(IRBuilderTest, DataLayout) {517  std::unique_ptr<Module> M(new Module("test", Ctx));518  M->setDataLayout("e-n32");519  EXPECT_TRUE(M->getDataLayout().isLegalInteger(32));520  M->setDataLayout("e");521  EXPECT_FALSE(M->getDataLayout().isLegalInteger(32));522}523 524TEST_F(IRBuilderTest, GetIntTy) {525  IRBuilder<> Builder(BB);526  IntegerType *Ty1 = Builder.getInt1Ty();527  EXPECT_EQ(Ty1, IntegerType::get(Ctx, 1));528 529  const DataLayout &DL = M->getDataLayout();530  IntegerType *IntPtrTy = Builder.getIntPtrTy(DL);531  unsigned IntPtrBitSize = DL.getPointerSizeInBits(0);532  EXPECT_EQ(IntPtrTy, IntegerType::get(Ctx, IntPtrBitSize));533}534 535TEST_F(IRBuilderTest, UnaryOperators) {536  IRBuilder<NoFolder> Builder(BB);537  Value *V = Builder.CreateLoad(GV->getValueType(), GV);538 539  // Test CreateUnOp(X)540  Value *U = Builder.CreateUnOp(Instruction::FNeg, V);541  ASSERT_TRUE(isa<Instruction>(U));542  ASSERT_TRUE(isa<FPMathOperator>(U));543  ASSERT_TRUE(isa<UnaryOperator>(U));544  ASSERT_FALSE(isa<BinaryOperator>(U));545 546  // Test CreateFNegFMF(X)547  Instruction *I = cast<Instruction>(U);548  I->setHasNoSignedZeros(true);549  I->setHasNoNaNs(true);550  Value *VFMF = Builder.CreateFNegFMF(V, I);551  Instruction *IFMF = cast<Instruction>(VFMF);552  EXPECT_TRUE(IFMF->hasNoSignedZeros());553  EXPECT_TRUE(IFMF->hasNoNaNs());554  EXPECT_FALSE(IFMF->hasAllowReassoc());555}556 557TEST_F(IRBuilderTest, FastMathFlags) {558  IRBuilder<> Builder(BB);559  Value *F, *FC;560  Instruction *FDiv, *FAdd, *FCmp, *FCall, *FNeg, *FSub, *FMul, *FRem;561 562  F = Builder.CreateLoad(GV->getValueType(), GV);563  F = Builder.CreateFAdd(F, F);564 565  EXPECT_FALSE(Builder.getFastMathFlags().any());566  ASSERT_TRUE(isa<Instruction>(F));567  FAdd = cast<Instruction>(F);568  EXPECT_FALSE(FAdd->hasNoNaNs());569 570  FastMathFlags FMF;571  Builder.setFastMathFlags(FMF);572 573  // By default, no flags are set.574  F = Builder.CreateFAdd(F, F);575  EXPECT_FALSE(Builder.getFastMathFlags().any());576  ASSERT_TRUE(isa<Instruction>(F));577  FAdd = cast<Instruction>(F);578  EXPECT_FALSE(FAdd->hasNoNaNs());579  EXPECT_FALSE(FAdd->hasNoInfs());580  EXPECT_FALSE(FAdd->hasNoSignedZeros());581  EXPECT_FALSE(FAdd->hasAllowReciprocal());582  EXPECT_FALSE(FAdd->hasAllowContract());583  EXPECT_FALSE(FAdd->hasAllowReassoc());584  EXPECT_FALSE(FAdd->hasApproxFunc());585 586  // Set all flags in the instruction.587  FAdd->setFast(true);588  EXPECT_TRUE(FAdd->hasNoNaNs());589  EXPECT_TRUE(FAdd->hasNoInfs());590  EXPECT_TRUE(FAdd->hasNoSignedZeros());591  EXPECT_TRUE(FAdd->hasAllowReciprocal());592  EXPECT_TRUE(FAdd->hasAllowContract());593  EXPECT_TRUE(FAdd->hasAllowReassoc());594  EXPECT_TRUE(FAdd->hasApproxFunc());595 596  // All flags are set in the builder.597  FMF.setFast();598  Builder.setFastMathFlags(FMF);599 600  F = Builder.CreateFAdd(F, F);601  EXPECT_TRUE(Builder.getFastMathFlags().any());602  EXPECT_TRUE(Builder.getFastMathFlags().all());603  ASSERT_TRUE(isa<Instruction>(F));604  FAdd = cast<Instruction>(F);605  EXPECT_TRUE(FAdd->hasNoNaNs());606  EXPECT_TRUE(FAdd->isFast());607 608  // Now, try it with CreateBinOp609  F = Builder.CreateBinOp(Instruction::FAdd, F, F);610  EXPECT_TRUE(Builder.getFastMathFlags().any());611  ASSERT_TRUE(isa<Instruction>(F));612  FAdd = cast<Instruction>(F);613  EXPECT_TRUE(FAdd->hasNoNaNs());614  EXPECT_TRUE(FAdd->isFast());615 616  F = Builder.CreateFDiv(F, F);617  EXPECT_TRUE(Builder.getFastMathFlags().all());618  ASSERT_TRUE(isa<Instruction>(F));619  FDiv = cast<Instruction>(F);620  EXPECT_TRUE(FDiv->hasAllowReciprocal());621 622  // Clear all FMF in the builder.623  Builder.clearFastMathFlags();624 625  F = Builder.CreateFDiv(F, F);626  ASSERT_TRUE(isa<Instruction>(F));627  FDiv = cast<Instruction>(F);628  EXPECT_FALSE(FDiv->hasAllowReciprocal());629 630  // Try individual flags.631  FMF.clear();632  FMF.setAllowReciprocal();633  Builder.setFastMathFlags(FMF);634 635  F = Builder.CreateFDiv(F, F);636  EXPECT_TRUE(Builder.getFastMathFlags().any());637  EXPECT_TRUE(Builder.getFastMathFlags().AllowReciprocal);638  ASSERT_TRUE(isa<Instruction>(F));639  FDiv = cast<Instruction>(F);640  EXPECT_TRUE(FDiv->hasAllowReciprocal());641 642  Builder.clearFastMathFlags();643 644  FC = Builder.CreateFCmpOEQ(F, F);645  ASSERT_TRUE(isa<Instruction>(FC));646  FCmp = cast<Instruction>(FC);647  EXPECT_FALSE(FCmp->hasAllowReciprocal());648 649  FMF.clear();650  FMF.setAllowReciprocal();651  Builder.setFastMathFlags(FMF);652 653  FC = Builder.CreateFCmpOEQ(F, F);654  EXPECT_TRUE(Builder.getFastMathFlags().any());655  EXPECT_TRUE(Builder.getFastMathFlags().AllowReciprocal);656  ASSERT_TRUE(isa<Instruction>(FC));657  FCmp = cast<Instruction>(FC);658  EXPECT_TRUE(FCmp->hasAllowReciprocal());659 660  Builder.clearFastMathFlags();661 662  // Test FP-contract663  FC = Builder.CreateFAdd(F, F);664  ASSERT_TRUE(isa<Instruction>(FC));665  FAdd = cast<Instruction>(FC);666  EXPECT_FALSE(FAdd->hasAllowContract());667 668  FMF.clear();669  FMF.setAllowContract(true);670  Builder.setFastMathFlags(FMF);671 672  FC = Builder.CreateFAdd(F, F);673  EXPECT_TRUE(Builder.getFastMathFlags().any());674  EXPECT_TRUE(Builder.getFastMathFlags().AllowContract);675  ASSERT_TRUE(isa<Instruction>(FC));676  FAdd = cast<Instruction>(FC);677  EXPECT_TRUE(FAdd->hasAllowContract());678 679  FMF.setApproxFunc();680  Builder.clearFastMathFlags();681  Builder.setFastMathFlags(FMF);682  // Now 'aml' and 'contract' are set.683  F = Builder.CreateFMul(F, F);684  FAdd = cast<Instruction>(F);685  EXPECT_TRUE(FAdd->hasApproxFunc());686  EXPECT_TRUE(FAdd->hasAllowContract());687  EXPECT_FALSE(FAdd->hasAllowReassoc());688  689  FMF.setAllowReassoc();690  Builder.clearFastMathFlags();691  Builder.setFastMathFlags(FMF);692  // Now 'aml' and 'contract' and 'reassoc' are set.693  F = Builder.CreateFMul(F, F);694  FAdd = cast<Instruction>(F);695  EXPECT_TRUE(FAdd->hasApproxFunc());696  EXPECT_TRUE(FAdd->hasAllowContract());697  EXPECT_TRUE(FAdd->hasAllowReassoc());698 699  // Test a call with FMF.700  auto CalleeTy = FunctionType::get(Type::getFloatTy(Ctx),701                                    /*isVarArg=*/false);702  auto Callee =703      Function::Create(CalleeTy, Function::ExternalLinkage, "", M.get());704 705  FCall = Builder.CreateCall(Callee, {});706  EXPECT_FALSE(FCall->hasNoNaNs());707 708  Function *V =709      Function::Create(CalleeTy, Function::ExternalLinkage, "", M.get());710  FCall = Builder.CreateCall(V, {});711  EXPECT_FALSE(FCall->hasNoNaNs());712 713  FMF.clear();714  FMF.setNoNaNs();715  Builder.setFastMathFlags(FMF);716 717  FCall = Builder.CreateCall(Callee, {});718  EXPECT_TRUE(Builder.getFastMathFlags().any());719  EXPECT_TRUE(Builder.getFastMathFlags().NoNaNs);720  EXPECT_TRUE(FCall->hasNoNaNs());721 722  FCall = Builder.CreateCall(V, {});723  EXPECT_TRUE(Builder.getFastMathFlags().any());724  EXPECT_TRUE(Builder.getFastMathFlags().NoNaNs);725  EXPECT_TRUE(FCall->hasNoNaNs());726 727  Builder.clearFastMathFlags();728 729  // To test a copy, make sure that a '0' and a '1' change state.730  F = Builder.CreateFDiv(F, F);731  ASSERT_TRUE(isa<Instruction>(F));732  FDiv = cast<Instruction>(F);733  EXPECT_FALSE(FDiv->getFastMathFlags().any());734  FDiv->setHasAllowReciprocal(true);735  FAdd->setHasAllowReciprocal(false);736  FAdd->setHasNoNaNs(true);737  FDiv->copyFastMathFlags(FAdd);738  EXPECT_TRUE(FDiv->hasNoNaNs());739  EXPECT_FALSE(FDiv->hasAllowReciprocal());740 741  // Test that CreateF*FMF functions copy flags from the source instruction742  // instead of using the builder default.743  Instruction *const FMFSource = FAdd;744  EXPECT_FALSE(Builder.getFastMathFlags().noNaNs());745  EXPECT_TRUE(FMFSource->hasNoNaNs());746 747  F = Builder.CreateFNegFMF(F, FMFSource);748  ASSERT_TRUE(isa<Instruction>(F));749  FNeg = cast<Instruction>(F);750  EXPECT_TRUE(FNeg->hasNoNaNs());751  F = Builder.CreateFAddFMF(F, F, FMFSource);752  ASSERT_TRUE(isa<Instruction>(F));753  FAdd = cast<Instruction>(F);754  EXPECT_TRUE(FAdd->hasNoNaNs());755  F = Builder.CreateFSubFMF(F, F, FMFSource);756  ASSERT_TRUE(isa<Instruction>(F));757  FSub = cast<Instruction>(F);758  EXPECT_TRUE(FSub->hasNoNaNs());759  F = Builder.CreateFMulFMF(F, F, FMFSource);760  ASSERT_TRUE(isa<Instruction>(F));761  FMul = cast<Instruction>(F);762  EXPECT_TRUE(FMul->hasNoNaNs());763  F = Builder.CreateFDivFMF(F, F, FMFSource);764  ASSERT_TRUE(isa<Instruction>(F));765  FDiv = cast<Instruction>(F);766  EXPECT_TRUE(FDiv->hasNoNaNs());767  F = Builder.CreateFRemFMF(F, F, FMFSource);768  ASSERT_TRUE(isa<Instruction>(F));769  FRem = cast<Instruction>(F);770  EXPECT_TRUE(FRem->hasNoNaNs());771}772 773TEST_F(IRBuilderTest, WrapFlags) {774  IRBuilder<NoFolder> Builder(BB);775 776  // Test instructions.777  GlobalVariable *G = new GlobalVariable(*M, Builder.getInt32Ty(), true,778                                         GlobalValue::ExternalLinkage, nullptr);779  Value *V = Builder.CreateLoad(G->getValueType(), G);780  EXPECT_TRUE(781      cast<BinaryOperator>(Builder.CreateNSWAdd(V, V))->hasNoSignedWrap());782  EXPECT_TRUE(783      cast<BinaryOperator>(Builder.CreateNSWMul(V, V))->hasNoSignedWrap());784  EXPECT_TRUE(785      cast<BinaryOperator>(Builder.CreateNSWSub(V, V))->hasNoSignedWrap());786  EXPECT_TRUE(cast<BinaryOperator>(787                  Builder.CreateShl(V, V, "", /* NUW */ false, /* NSW */ true))788                  ->hasNoSignedWrap());789 790  EXPECT_TRUE(791      cast<BinaryOperator>(Builder.CreateNUWAdd(V, V))->hasNoUnsignedWrap());792  EXPECT_TRUE(793      cast<BinaryOperator>(Builder.CreateNUWMul(V, V))->hasNoUnsignedWrap());794  EXPECT_TRUE(795      cast<BinaryOperator>(Builder.CreateNUWSub(V, V))->hasNoUnsignedWrap());796  EXPECT_TRUE(cast<BinaryOperator>(797                  Builder.CreateShl(V, V, "", /* NUW */ true, /* NSW */ false))798                  ->hasNoUnsignedWrap());799 800  // Test operators created with constants.801  Constant *C = Builder.getInt32(42);802  EXPECT_TRUE(cast<OverflowingBinaryOperator>(Builder.CreateNSWAdd(C, C))803                  ->hasNoSignedWrap());804  EXPECT_TRUE(cast<OverflowingBinaryOperator>(Builder.CreateNSWSub(C, C))805                  ->hasNoSignedWrap());806  EXPECT_TRUE(cast<OverflowingBinaryOperator>(Builder.CreateNSWMul(C, C))807                  ->hasNoSignedWrap());808  EXPECT_TRUE(cast<OverflowingBinaryOperator>(809                  Builder.CreateShl(C, C, "", /* NUW */ false, /* NSW */ true))810                  ->hasNoSignedWrap());811 812  EXPECT_TRUE(cast<OverflowingBinaryOperator>(Builder.CreateNUWAdd(C, C))813                  ->hasNoUnsignedWrap());814  EXPECT_TRUE(cast<OverflowingBinaryOperator>(Builder.CreateNUWSub(C, C))815                  ->hasNoUnsignedWrap());816  EXPECT_TRUE(cast<OverflowingBinaryOperator>(Builder.CreateNUWMul(C, C))817                  ->hasNoUnsignedWrap());818  EXPECT_TRUE(cast<OverflowingBinaryOperator>(819                  Builder.CreateShl(C, C, "", /* NUW */ true, /* NSW */ false))820                  ->hasNoUnsignedWrap());821}822 823TEST_F(IRBuilderTest, RAIIHelpersTest) {824  IRBuilder<> Builder(BB);825  EXPECT_FALSE(Builder.getFastMathFlags().allowReciprocal());826  MDBuilder MDB(M->getContext());827 828  MDNode *FPMathA = MDB.createFPMath(0.01f);829  MDNode *FPMathB = MDB.createFPMath(0.1f);830 831  Builder.setDefaultFPMathTag(FPMathA);832 833  {834    IRBuilder<>::FastMathFlagGuard Guard(Builder);835    FastMathFlags FMF;836    FMF.setAllowReciprocal();837    Builder.setFastMathFlags(FMF);838    Builder.setDefaultFPMathTag(FPMathB);839    EXPECT_TRUE(Builder.getFastMathFlags().allowReciprocal());840    EXPECT_EQ(FPMathB, Builder.getDefaultFPMathTag());841  }842 843  EXPECT_FALSE(Builder.getFastMathFlags().allowReciprocal());844  EXPECT_EQ(FPMathA, Builder.getDefaultFPMathTag());845 846  Value *F = Builder.CreateLoad(GV->getValueType(), GV);847 848  {849    IRBuilder<>::InsertPointGuard Guard(Builder);850    Builder.SetInsertPoint(cast<Instruction>(F));851    EXPECT_EQ(F, &*Builder.GetInsertPoint());852  }853 854  EXPECT_EQ(BB->end(), Builder.GetInsertPoint());855  EXPECT_EQ(BB, Builder.GetInsertBlock());856}857 858TEST_F(IRBuilderTest, createFunction) {859  IRBuilder<> Builder(BB);860  DIBuilder DIB(*M);861  auto File = DIB.createFile("error.swift", "/");862  auto CU = DIB.createCompileUnit(DISourceLanguageName(dwarf::DW_LANG_Swift),863                                  File, "swiftc", true, "", 0);864  auto Type = DIB.createSubroutineType(DIB.getOrCreateTypeArray({}));865  auto NoErr = DIB.createFunction(866      CU, "noerr", "", File, 1, Type, 1, DINode::FlagZero,867      DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized);868  EXPECT_TRUE(!NoErr->getThrownTypes());869  auto Int = DIB.createBasicType("Int", 64, dwarf::DW_ATE_signed);870  auto Error = DIB.getOrCreateArray({Int});871  auto Err = DIB.createFunction(872      CU, "err", "", File, 1, Type, 1, DINode::FlagZero,873      DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized, nullptr,874      nullptr, Error.get());875  EXPECT_TRUE(Err->getThrownTypes().get() == Error.get());876  DIB.finalize();877}878 879TEST_F(IRBuilderTest, DIBuilder) {880  auto GetLastDbgRecord = [](const Instruction *I) -> DbgRecord * {881    if (I->getDbgRecordRange().empty())882      return nullptr;883    return &*std::prev(I->getDbgRecordRange().end());884  };885 886  auto ExpectOrder = [&](DbgInstPtr First, BasicBlock::iterator Second) {887    EXPECT_TRUE(isa<DbgRecord *>(First));888    EXPECT_FALSE(Second->getDbgRecordRange().empty());889    EXPECT_EQ(GetLastDbgRecord(&*Second), cast<DbgRecord *>(First));890  };891 892  auto RunTest = [&]() {893    IRBuilder<> Builder(BB);894    DIBuilder DIB(*M);895    auto File = DIB.createFile("F.CBL", "/");896    auto CU = DIB.createCompileUnit(897        DISourceLanguageName(dwarf::DW_LANG_Cobol74),898        DIB.createFile("F.CBL", "/"), "llvm-cobol74", true, "", 0);899    auto Type = DIB.createSubroutineType(DIB.getOrCreateTypeArray({}));900    auto SP = DIB.createFunction(901        CU, "foo", "", File, 1, Type, 1, DINode::FlagZero,902        DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized);903    F->setSubprogram(SP);904    AllocaInst *I = Builder.CreateAlloca(Builder.getInt8Ty());905    auto BarSP = DIB.createFunction(906        CU, "bar", "", File, 1, Type, 1, DINode::FlagZero,907        DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized);908    auto BarScope = DIB.createLexicalBlockFile(BarSP, File, 0);909    I->setDebugLoc(DILocation::get(Ctx, 2, 0, BarScope));910 911    // Create another instruction so that there's one before the alloca we're912    // inserting debug intrinsics before, to make end-checking easier.913    I = Builder.CreateAlloca(Builder.getInt1Ty());914 915    // Label metadata and records916    // --------------------------917    DILocation *LabelLoc = DILocation::get(Ctx, 1, 0, BarScope);918    DILabel *AlwaysPreserveLabel = DIB.createLabel(919        BarScope, "meles_meles", File, 1, /*Column*/ 0, /*IsArtificial*/ false,920        /*CoroSuspendIdx*/ std::nullopt, /*AlwaysPreserve*/ true);921    DILabel *Label = DIB.createLabel(922        BarScope, "badger", File, 1, /*Column*/ 0, /*IsArtificial*/ false,923        /*CoroSuspendIdx*/ std::nullopt, /*AlwaysPreserve*/ false);924 925    { /* dbg.label | DbgLabelRecord */926      // Insert before I and check order.927      ExpectOrder(DIB.insertLabel(Label, LabelLoc, I->getIterator()),928                  I->getIterator());929 930      // We should be able to insert at the end of the block, even if there's931      // no terminator yet. Note that in RemoveDIs mode this record won't get932      // inserted into the block untill another instruction is added.933      DbgInstPtr LabelRecord = DIB.insertLabel(Label, LabelLoc, BB->end());934      // Specifically do not insert a terminator, to check this works. `I`935      // should have absorbed the DbgLabelRecord in the new debug info mode.936      I = Builder.CreateAlloca(Builder.getInt32Ty());937      ExpectOrder(LabelRecord, I->getIterator());938    }939 940    // Variable metadata and records941    // -----------------------------942    DILocation *VarLoc = DILocation::get(Ctx, 2, 0, BarScope);943    auto *IntType = DIB.createBasicType("int", 32, dwarf::DW_ATE_signed);944    DILocalVariable *VarX =945        DIB.createAutoVariable(BarSP, "X", File, 2, IntType, true);946    DILocalVariable *VarY =947        DIB.createAutoVariable(BarSP, "Y", File, 2, IntType, true);948    { /* dbg.value | DbgVariableRecord::Value */949      ExpectOrder(DIB.insertDbgValueIntrinsic(I, VarX, DIB.createExpression(),950                                              VarLoc, I->getIterator()),951                  I->getIterator());952      // Check inserting at end of the block works as with labels.953      DbgInstPtr VarXValue = DIB.insertDbgValueIntrinsic(954          I, VarX, DIB.createExpression(), VarLoc, BB);955      I = Builder.CreateAlloca(Builder.getInt32Ty());956      ExpectOrder(VarXValue, I->getIterator());957      EXPECT_EQ(BB->getTrailingDbgRecords(), nullptr);958    }959    { /* dbg.declare | DbgVariableRecord::Declare */960      ExpectOrder(DIB.insertDeclare(I, VarY, DIB.createExpression(), VarLoc,961                                    I->getIterator()),962                  I->getIterator());963      // Check inserting at end of the block works as with labels.964      DbgInstPtr VarYDeclare =965          DIB.insertDeclare(I, VarY, DIB.createExpression(), VarLoc, BB);966      I = Builder.CreateAlloca(Builder.getInt32Ty());967      ExpectOrder(VarYDeclare, I->getIterator());968      EXPECT_EQ(BB->getTrailingDbgRecords(), nullptr);969    }970    { /* dbg.assign | DbgVariableRecord::Assign */971      I = Builder.CreateAlloca(Builder.getInt32Ty());972      I->setMetadata(LLVMContext::MD_DIAssignID, DIAssignID::getDistinct(Ctx));973      // DbgAssign interface is slightly different - it always inserts after the974      // linked instr. Check we can do this with no instruction to insert975      // before.976      DbgInstPtr VarXAssign =977          DIB.insertDbgAssign(I, I, VarX, DIB.createExpression(), I,978                              DIB.createExpression(), VarLoc);979      I = Builder.CreateAlloca(Builder.getInt32Ty());980      ExpectOrder(VarXAssign, I->getIterator());981      EXPECT_EQ(BB->getTrailingDbgRecords(), nullptr);982    }983 984    Builder.CreateRet(nullptr);985    DIB.finalize();986    // Check the labels are not/are added to Bar's retainedNodes array987    // (AlwaysPreserve).988    EXPECT_EQ(find(BarSP->getRetainedNodes(), Label),989              BarSP->getRetainedNodes().end());990    EXPECT_NE(find(BarSP->getRetainedNodes(), AlwaysPreserveLabel),991              BarSP->getRetainedNodes().end());992    EXPECT_NE(find(BarSP->getRetainedNodes(), VarX),993              BarSP->getRetainedNodes().end());994    EXPECT_NE(find(BarSP->getRetainedNodes(), VarY),995              BarSP->getRetainedNodes().end());996    EXPECT_TRUE(verifyModule(*M));997  };998 999  RunTest();1000  TearDown();1001}1002 1003TEST_F(IRBuilderTest, createArtificialSubprogram) {1004  IRBuilder<> Builder(BB);1005  DIBuilder DIB(*M);1006  auto File = DIB.createFile("main.c", "/");1007  auto CU = DIB.createCompileUnit(DISourceLanguageName(dwarf::DW_LANG_C), File,1008                                  "clang",1009                                  /*isOptimized=*/true, /*Flags=*/"",1010                                  /*Runtime Version=*/0);1011  auto Type = DIB.createSubroutineType(DIB.getOrCreateTypeArray({}));1012  auto SP = DIB.createFunction(1013      CU, "foo", /*LinkageName=*/"", File,1014      /*LineNo=*/1, Type, /*ScopeLine=*/2, DINode::FlagZero,1015      DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized);1016  EXPECT_TRUE(SP->isDistinct());1017 1018  F->setSubprogram(SP);1019  AllocaInst *I = Builder.CreateAlloca(Builder.getInt8Ty());1020  ReturnInst *R = Builder.CreateRetVoid();1021  I->setDebugLoc(DILocation::get(Ctx, 3, 2, SP));1022  R->setDebugLoc(DILocation::get(Ctx, 4, 2, SP));1023  DIB.finalize();1024  EXPECT_FALSE(verifyModule(*M));1025 1026  Function *G = Function::Create(F->getFunctionType(),1027                                 Function::ExternalLinkage, "", M.get());1028  BasicBlock *GBB = BasicBlock::Create(Ctx, "", G);1029  Builder.SetInsertPoint(GBB);1030  I->removeFromParent();1031  Builder.Insert(I);1032  Builder.CreateRetVoid();1033  EXPECT_FALSE(verifyModule(*M));1034 1035  DISubprogram *GSP = DIBuilder::createArtificialSubprogram(F->getSubprogram());1036  EXPECT_EQ(SP->getFile(), GSP->getFile());1037  EXPECT_EQ(SP->getType(), GSP->getType());1038  EXPECT_EQ(SP->getLine(), GSP->getLine());1039  EXPECT_EQ(SP->getScopeLine(), GSP->getScopeLine());1040  EXPECT_TRUE(GSP->isDistinct());1041 1042  G->setSubprogram(GSP);1043  EXPECT_TRUE(verifyModule(*M));1044 1045  auto *InlinedAtNode =1046      DILocation::getDistinct(Ctx, GSP->getScopeLine(), 0, GSP);1047  DebugLoc DL = I->getDebugLoc();1048  DenseMap<const MDNode *, MDNode *> IANodes;1049  auto IA = DebugLoc::appendInlinedAt(DL, InlinedAtNode, Ctx, IANodes);1050  auto NewDL =1051      DILocation::get(Ctx, DL.getLine(), DL.getCol(), DL.getScope(), IA);1052  I->setDebugLoc(NewDL);1053  EXPECT_FALSE(verifyModule(*M));1054 1055  EXPECT_EQ("foo", SP->getName());1056  EXPECT_EQ("foo", GSP->getName());1057  EXPECT_FALSE(SP->isArtificial());1058  EXPECT_TRUE(GSP->isArtificial());1059}1060 1061// Check that we can add debug info to an existing DICompileUnit.1062TEST_F(IRBuilderTest, appendDebugInfo) {1063  IRBuilder<> Builder(BB);1064  Builder.CreateRetVoid();1065  EXPECT_FALSE(verifyModule(*M));1066 1067  auto GetNames = [](DICompileUnit *CU) {1068    SmallVector<StringRef> Names;1069    for (auto *ET : CU->getEnumTypes())1070      Names.push_back(ET->getName());1071    for (auto *RT : CU->getRetainedTypes())1072      Names.push_back(RT->getName());1073    for (auto *GV : CU->getGlobalVariables())1074      Names.push_back(GV->getVariable()->getName());1075    for (auto *IE : CU->getImportedEntities())1076      Names.push_back(IE->getName());1077    for (auto *Node : CU->getMacros())1078      if (auto *MN = dyn_cast_or_null<DIMacro>(Node))1079        Names.push_back(MN->getName());1080    return Names;1081  };1082 1083  DICompileUnit *CU;1084  {1085    DIBuilder DIB(*M);1086    auto *File = DIB.createFile("main.c", "/");1087    CU = DIB.createCompileUnit(DISourceLanguageName(dwarf::DW_LANG_C), File,1088                               "clang",1089                               /*isOptimized=*/true, /*Flags=*/"",1090                               /*Runtime Version=*/0);1091    auto *ByteTy = DIB.createBasicType("byte0", 8, dwarf::DW_ATE_signed);1092    DIB.createEnumerationType(CU, "ET0", File, /*LineNo=*/0, /*SizeInBits=*/8,1093                              /*AlignInBits=*/8, /*Elements=*/{}, ByteTy);1094    DIB.retainType(ByteTy);1095    DIB.createGlobalVariableExpression(CU, "GV0", /*LinkageName=*/"", File,1096                                       /*LineNo=*/1, ByteTy,1097                                       /*IsLocalToUnit=*/true);1098    DIB.createImportedDeclaration(CU, nullptr, File, /*LineNo=*/2, "IM0");1099    DIB.createMacro(nullptr, /*LineNo=*/0, dwarf::DW_MACINFO_define, "M0");1100    DIB.finalize();1101  }1102  EXPECT_FALSE(verifyModule(*M));1103  EXPECT_THAT(GetNames(CU),1104              UnorderedElementsAre("ET0", "byte0", "GV0", "IM0", "M0"));1105 1106  {1107    DIBuilder DIB(*M, true, CU);1108    auto *File = CU->getFile();1109    auto *ByteTy = DIB.createBasicType("byte1", 8, dwarf::DW_ATE_signed);1110    DIB.createEnumerationType(CU, "ET1", File, /*LineNo=*/0,1111                              /*SizeInBits=*/8, /*AlignInBits=*/8,1112                              /*Elements=*/{}, ByteTy);1113    DIB.retainType(ByteTy);1114    DIB.createGlobalVariableExpression(CU, "GV1", /*LinkageName=*/"", File,1115                                       /*LineNo=*/1, ByteTy,1116                                       /*IsLocalToUnit=*/true);1117    DIB.createImportedDeclaration(CU, nullptr, File, /*LineNo=*/2, "IM1");1118    DIB.createMacro(nullptr, /*LineNo=*/0, dwarf::DW_MACINFO_define, "M1");1119    DIB.finalize();1120  }1121  EXPECT_FALSE(verifyModule(*M));1122  EXPECT_THAT(GetNames(CU),1123              UnorderedElementsAre("ET0", "byte0", "GV0", "IM0", "M0", "ET1",1124                                   "byte1", "GV1", "IM1", "M1"));1125}1126 1127TEST_F(IRBuilderTest, InsertExtractElement) {1128  IRBuilder<> Builder(BB);1129 1130  auto VecTy = FixedVectorType::get(Builder.getInt64Ty(), 4);1131  auto Elt1 = Builder.getInt64(-1);1132  auto Elt2 = Builder.getInt64(-2);1133  Value *Vec = Builder.CreateInsertElement(VecTy, Elt1, Builder.getInt8(1));1134  Vec = Builder.CreateInsertElement(Vec, Elt2, 2);1135  auto X1 = Builder.CreateExtractElement(Vec, 1);1136  auto X2 = Builder.CreateExtractElement(Vec, Builder.getInt32(2));1137  EXPECT_EQ(Elt1, X1);1138  EXPECT_EQ(Elt2, X2);1139}1140 1141TEST_F(IRBuilderTest, CreateGlobalString) {1142  IRBuilder<> Builder(BB);1143 1144  auto String1a = Builder.CreateGlobalString("TestString", "String1a");1145  auto String1b = Builder.CreateGlobalString("TestString", "String1b", 0);1146  auto String2 = Builder.CreateGlobalString("TestString", "String2", 1);1147  auto String3 = Builder.CreateGlobalString("TestString", "String3", 2);1148 1149  EXPECT_TRUE(String1a->getType()->getPointerAddressSpace() == 0);1150  EXPECT_TRUE(String1b->getType()->getPointerAddressSpace() == 0);1151  EXPECT_TRUE(String2->getType()->getPointerAddressSpace() == 1);1152  EXPECT_TRUE(String3->getType()->getPointerAddressSpace() == 2);1153}1154 1155TEST_F(IRBuilderTest, DebugLoc) {1156  auto CalleeTy = FunctionType::get(Type::getVoidTy(Ctx),1157                                    /*isVarArg=*/false);1158  auto Callee =1159      Function::Create(CalleeTy, Function::ExternalLinkage, "", M.get());1160 1161  DIBuilder DIB(*M);1162  auto File = DIB.createFile("tmp.cpp", "/");1163  auto CU =1164      DIB.createCompileUnit(DISourceLanguageName(dwarf::DW_LANG_C_plus_plus_11),1165                            DIB.createFile("tmp.cpp", "/"), "", true, "", 0);1166  auto SPType = DIB.createSubroutineType(DIB.getOrCreateTypeArray({}));1167  auto SP =1168      DIB.createFunction(CU, "foo", "foo", File, 1, SPType, 1, DINode::FlagZero,1169                         DISubprogram::SPFlagDefinition);1170  DebugLoc DL1 = DILocation::get(Ctx, 2, 0, SP);1171  DebugLoc DL2 = DILocation::get(Ctx, 3, 0, SP);1172 1173  auto BB2 = BasicBlock::Create(Ctx, "bb2", F);1174  auto Br = BranchInst::Create(BB2, BB);1175  Br->setDebugLoc(DL1);1176 1177  IRBuilder<> Builder(Ctx);1178  Builder.SetInsertPoint(Br);1179  EXPECT_EQ(DL1, Builder.getCurrentDebugLocation());1180  auto Call1 = Builder.CreateCall(Callee, {});1181  EXPECT_EQ(DL1, Call1->getDebugLoc());1182 1183  Call1->setDebugLoc(DL2);1184  Builder.SetInsertPoint(Call1->getParent(), Call1->getIterator());1185  EXPECT_EQ(DL2, Builder.getCurrentDebugLocation());1186  auto Call2 = Builder.CreateCall(Callee, {});1187  EXPECT_EQ(DL2, Call2->getDebugLoc());1188 1189  DIB.finalize();1190}1191 1192TEST_F(IRBuilderTest, DIImportedEntity) {1193  IRBuilder<> Builder(BB);1194  DIBuilder DIB(*M);1195  auto F = DIB.createFile("F.CBL", "/");1196  auto CU = DIB.createCompileUnit(DISourceLanguageName(dwarf::DW_LANG_Cobol74),1197                                  F, "llvm-cobol74", true, "", 0);1198  MDTuple *Elements = MDTuple::getDistinct(Ctx, {});1199 1200  DIB.createImportedDeclaration(CU, nullptr, F, 1);1201  DIB.createImportedDeclaration(CU, nullptr, F, 1);1202  DIB.createImportedModule(CU, (DIImportedEntity *)nullptr, F, 2);1203  DIB.createImportedModule(CU, (DIImportedEntity *)nullptr, F, 2);1204  DIB.createImportedModule(CU, (DIImportedEntity *)nullptr, F, 2, Elements);1205  DIB.createImportedModule(CU, (DIImportedEntity *)nullptr, F, 2, Elements);1206  DIB.finalize();1207  EXPECT_TRUE(verifyModule(*M));1208  EXPECT_TRUE(CU->getImportedEntities().size() == 3);1209}1210 1211//  0: #define M0 V0          <-- command line definition1212//  0: main.c                 <-- main file1213//     3:   #define M1 V1     <-- M1 definition in main.c1214//     5:   #include "file.h" <-- inclusion of file.h from main.c1215//          1: #define M2     <-- M2 definition in file.h with no value1216//     7:   #undef M1 V1      <-- M1 un-definition in main.c1217TEST_F(IRBuilderTest, DIBuilderMacro) {1218  IRBuilder<> Builder(BB);1219  DIBuilder DIB(*M);1220  auto File1 = DIB.createFile("main.c", "/");1221  auto File2 = DIB.createFile("file.h", "/");1222  auto CU = DIB.createCompileUnit(DISourceLanguageName(dwarf::DW_LANG_C),1223                                  DIB.createFile("main.c", "/"), "llvm-c", true,1224                                  "", 0);1225  auto MDef0 =1226      DIB.createMacro(nullptr, 0, dwarf::DW_MACINFO_define, "M0", "V0");1227  auto TMF1 = DIB.createTempMacroFile(nullptr, 0, File1);1228  auto MDef1 = DIB.createMacro(TMF1, 3, dwarf::DW_MACINFO_define, "M1", "V1");1229  auto TMF2 = DIB.createTempMacroFile(TMF1, 5, File2);1230  auto MDef2 = DIB.createMacro(TMF2, 1, dwarf::DW_MACINFO_define, "M2");1231  auto MUndef1 = DIB.createMacro(TMF1, 7, dwarf::DW_MACINFO_undef, "M1");1232 1233  EXPECT_EQ(dwarf::DW_MACINFO_define, MDef1->getMacinfoType());1234  EXPECT_EQ(3u, MDef1->getLine());1235  EXPECT_EQ("M1", MDef1->getName());1236  EXPECT_EQ("V1", MDef1->getValue());1237 1238  EXPECT_EQ(dwarf::DW_MACINFO_undef, MUndef1->getMacinfoType());1239  EXPECT_EQ(7u, MUndef1->getLine());1240  EXPECT_EQ("M1", MUndef1->getName());1241  EXPECT_EQ("", MUndef1->getValue());1242 1243  EXPECT_EQ(dwarf::DW_MACINFO_start_file, TMF2->getMacinfoType());1244  EXPECT_EQ(5u, TMF2->getLine());1245  EXPECT_EQ(File2, TMF2->getFile());1246 1247  DIB.finalize();1248 1249  SmallVector<Metadata *, 4> Elements;1250  Elements.push_back(MDef2);1251  auto MF2 = DIMacroFile::get(Ctx, dwarf::DW_MACINFO_start_file, 5, File2,1252                              DIB.getOrCreateMacroArray(Elements));1253 1254  Elements.clear();1255  Elements.push_back(MDef1);1256  Elements.push_back(MF2);1257  Elements.push_back(MUndef1);1258  auto MF1 = DIMacroFile::get(Ctx, dwarf::DW_MACINFO_start_file, 0, File1,1259                              DIB.getOrCreateMacroArray(Elements));1260 1261  Elements.clear();1262  Elements.push_back(MDef0);1263  Elements.push_back(MF1);1264  auto MN0 = MDTuple::get(Ctx, Elements);1265  EXPECT_EQ(MN0, CU->getRawMacros());1266 1267  Elements.clear();1268  Elements.push_back(MDef1);1269  Elements.push_back(MF2);1270  Elements.push_back(MUndef1);1271  auto MN1 = MDTuple::get(Ctx, Elements);1272  EXPECT_EQ(MN1, MF1->getRawElements());1273 1274  Elements.clear();1275  Elements.push_back(MDef2);1276  auto MN2 = MDTuple::get(Ctx, Elements);1277  EXPECT_EQ(MN2, MF2->getRawElements());1278  EXPECT_TRUE(verifyModule(*M));1279}1280 1281TEST_F(IRBuilderTest, NoFolderNames) {1282  IRBuilder<NoFolder> Builder(BB);1283  auto *Add =1284      Builder.CreateAdd(Builder.getInt32(1), Builder.getInt32(2), "add");1285  EXPECT_EQ(Add->getName(), "add");1286}1287 1288TEST_F(IRBuilderTest, CTAD) {1289  struct TestInserter : public IRBuilderDefaultInserter {1290    TestInserter() = default;1291  };1292  InstSimplifyFolder Folder(M->getDataLayout());1293 1294  IRBuilder Builder1(Ctx, Folder, TestInserter());1295  static_assert(std::is_same_v<decltype(Builder1),1296                               IRBuilder<InstSimplifyFolder, TestInserter>>);1297  IRBuilder Builder2(Ctx);1298  static_assert(std::is_same_v<decltype(Builder2), IRBuilder<>>);1299  IRBuilder Builder3(BB, Folder);1300  static_assert(1301      std::is_same_v<decltype(Builder3), IRBuilder<InstSimplifyFolder>>);1302  IRBuilder Builder4(BB);1303  static_assert(std::is_same_v<decltype(Builder4), IRBuilder<>>);1304  // The block BB is empty, so don't test this one.1305  // IRBuilder Builder5(BB->getTerminator());1306  // static_assert(std::is_same_v<decltype(Builder5), IRBuilder<>>);1307  IRBuilder Builder6(BB, BB->end(), Folder);1308  static_assert(1309      std::is_same_v<decltype(Builder6), IRBuilder<InstSimplifyFolder>>);1310  IRBuilder Builder7(BB, BB->end());1311  static_assert(std::is_same_v<decltype(Builder7), IRBuilder<>>);1312}1313}1314