brintos

brintos / llvm-project-archived public Read only

0
0
Text · 30.7 KiB · 6376165 Raw
840 lines · cpp
1//===- llvm/unittest/IR/ConstantsTest.cpp - Constants unit 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/Constants.h"10#include "llvm-c/Core.h"11#include "llvm/AsmParser/Parser.h"12#include "llvm/IR/ConstantFold.h"13#include "llvm/IR/DerivedTypes.h"14#include "llvm/IR/InstrTypes.h"15#include "llvm/IR/Instruction.h"16#include "llvm/IR/LLVMContext.h"17#include "llvm/IR/Module.h"18#include "llvm/Support/SourceMgr.h"19#include "gtest/gtest.h"20 21namespace llvm {22namespace {23 24// Check that use count checks treat ConstantData like they have no uses.25TEST(ConstantsTest, UseCounts) {26  LLVMContext Context;27  Type *Int32Ty = Type::getInt32Ty(Context);28  Constant *Zero = ConstantInt::get(Int32Ty, 0);29 30  EXPECT_TRUE(Zero->use_empty());31  EXPECT_EQ(Zero->getNumUses(), 0u);32  EXPECT_TRUE(Zero->hasNUses(0));33  EXPECT_FALSE(Zero->hasOneUse());34  EXPECT_FALSE(Zero->hasOneUser());35  EXPECT_FALSE(Zero->hasNUses(1));36  EXPECT_FALSE(Zero->hasNUsesOrMore(1));37  EXPECT_FALSE(Zero->hasNUses(2));38  EXPECT_FALSE(Zero->hasNUsesOrMore(2));39 40  std::unique_ptr<Module> M(new Module("MyModule", Context));41 42  // Introduce some uses43  new GlobalVariable(*M, Int32Ty, /*isConstant=*/false,44                     GlobalValue::ExternalLinkage, /*Initializer=*/Zero,45                     "gv_user0");46  new GlobalVariable(*M, Int32Ty, /*isConstant=*/false,47                     GlobalValue::ExternalLinkage, /*Initializer=*/Zero,48                     "gv_user1");49 50  // Still looks like use_empty with uses.51  EXPECT_TRUE(Zero->use_empty());52  EXPECT_EQ(Zero->getNumUses(), 0u);53  EXPECT_TRUE(Zero->hasNUses(0));54  EXPECT_FALSE(Zero->hasOneUse());55  EXPECT_FALSE(Zero->hasOneUser());56  EXPECT_FALSE(Zero->hasNUses(1));57  EXPECT_FALSE(Zero->hasNUsesOrMore(1));58  EXPECT_FALSE(Zero->hasNUses(2));59  EXPECT_FALSE(Zero->hasNUsesOrMore(2));60}61 62TEST(ConstantsTest, Integer_i1) {63  LLVMContext Context;64  IntegerType *Int1 = IntegerType::get(Context, 1);65  Constant *One = ConstantInt::get(Int1, 1, true);66  Constant *Zero = ConstantInt::get(Int1, 0);67  Constant *NegOne = ConstantInt::get(Int1, static_cast<uint64_t>(-1), true);68  EXPECT_EQ(NegOne, ConstantInt::getSigned(Int1, -1));69  Constant *Poison = PoisonValue::get(Int1);70 71  // Input:  @b = constant i1 add(i1 1 , i1 1)72  // Output: @b = constant i1 false73  EXPECT_EQ(Zero, ConstantExpr::getAdd(One, One));74 75  // @c = constant i1 add(i1 -1, i1 1)76  // @c = constant i1 false77  EXPECT_EQ(Zero, ConstantExpr::getAdd(NegOne, One));78 79  // @d = constant i1 add(i1 -1, i1 -1)80  // @d = constant i1 false81  EXPECT_EQ(Zero, ConstantExpr::getAdd(NegOne, NegOne));82 83  // @e = constant i1 sub(i1 -1, i1 1)84  // @e = constant i1 false85  EXPECT_EQ(Zero, ConstantExpr::getSub(NegOne, One));86 87  // @f = constant i1 sub(i1 1 , i1 -1)88  // @f = constant i1 false89  EXPECT_EQ(Zero, ConstantExpr::getSub(One, NegOne));90 91  // @g = constant i1 sub(i1 1 , i1 1)92  // @g = constant i1 false93  EXPECT_EQ(Zero, ConstantExpr::getSub(One, One));94 95  // @h = constant i1 shl(i1 1 , i1 1)  ; poison96  // @h = constant i1 poison97  EXPECT_EQ(Poison, ConstantFoldBinaryInstruction(Instruction::Shl, One, One));98 99  // @i = constant i1 shl(i1 1 , i1 0)100  // @i = constant i1 true101  EXPECT_EQ(One, ConstantFoldBinaryInstruction(Instruction::Shl, One, Zero));102 103  // @n = constant i1 mul(i1 -1, i1 1)104  // @n = constant i1 true105  EXPECT_EQ(One, ConstantFoldBinaryInstruction(Instruction::Mul, NegOne, One));106 107  // @o = constant i1 sdiv(i1 -1, i1 1) ; overflow108  // @o = constant i1 true109  EXPECT_EQ(One, ConstantFoldBinaryInstruction(Instruction::SDiv, NegOne, One));110 111  // @p = constant i1 sdiv(i1 1 , i1 -1); overflow112  // @p = constant i1 true113  EXPECT_EQ(One, ConstantFoldBinaryInstruction(Instruction::SDiv, One, NegOne));114 115  // @q = constant i1 udiv(i1 -1, i1 1)116  // @q = constant i1 true117  EXPECT_EQ(One, ConstantFoldBinaryInstruction(Instruction::UDiv, NegOne, One));118 119  // @r = constant i1 udiv(i1 1, i1 -1)120  // @r = constant i1 true121  EXPECT_EQ(One, ConstantFoldBinaryInstruction(Instruction::UDiv, One, NegOne));122 123  // @s = constant i1 srem(i1 -1, i1 1) ; overflow124  // @s = constant i1 false125  EXPECT_EQ(Zero,126            ConstantFoldBinaryInstruction(Instruction::SRem, NegOne, One));127 128  // @u = constant i1 srem(i1  1, i1 -1) ; overflow129  // @u = constant i1 false130  EXPECT_EQ(Zero,131            ConstantFoldBinaryInstruction(Instruction::SRem, One, NegOne));132}133 134TEST(ConstantsTest, IntSigns) {135  LLVMContext Context;136  IntegerType *Int8Ty = Type::getInt8Ty(Context);137  EXPECT_EQ(100, ConstantInt::get(Int8Ty, 100, false)->getSExtValue());138  EXPECT_EQ(100, ConstantInt::get(Int8Ty, 100, true)->getSExtValue());139  EXPECT_EQ(100, ConstantInt::getSigned(Int8Ty, 100)->getSExtValue());140  EXPECT_EQ(-50, ConstantInt::get(Int8Ty, 206)->getSExtValue());141  EXPECT_EQ(-50, ConstantInt::getSigned(Int8Ty, -50)->getSExtValue());142  EXPECT_EQ(206U, ConstantInt::getSigned(Int8Ty, -50)->getZExtValue());143 144  // Overflow is handled by truncation.145  EXPECT_EQ(0x3b, ConstantInt::get(Int8Ty, 0x13b)->getSExtValue());146}147 148TEST(ConstantsTest, PointerCast) {149  LLVMContext C;150  Type *PtrTy = PointerType::get(C, 0);151  Type *Int64Ty = Type::getInt64Ty(C);152  VectorType *PtrVecTy = FixedVectorType::get(PtrTy, 4);153  VectorType *Int64VecTy = FixedVectorType::get(Int64Ty, 4);154  VectorType *PtrScalableVecTy = ScalableVectorType::get(PtrTy, 4);155  VectorType *Int64ScalableVecTy = ScalableVectorType::get(Int64Ty, 4);156 157  // ptrtoint ptr to i64158  EXPECT_EQ(159      Constant::getNullValue(Int64Ty),160      ConstantExpr::getPointerCast(Constant::getNullValue(PtrTy), Int64Ty));161 162  // bitcast ptr to ptr163  EXPECT_EQ(Constant::getNullValue(PtrTy),164            ConstantExpr::getPointerCast(Constant::getNullValue(PtrTy), PtrTy));165 166  // ptrtoint <4 x ptr> to <4 x i64>167  EXPECT_EQ(Constant::getNullValue(Int64VecTy),168            ConstantExpr::getPointerCast(Constant::getNullValue(PtrVecTy),169                                         Int64VecTy));170 171  // ptrtoint <vscale x 4 x ptr> to <vscale x 4 x i64>172  EXPECT_EQ(Constant::getNullValue(Int64ScalableVecTy),173            ConstantExpr::getPointerCast(174                Constant::getNullValue(PtrScalableVecTy), Int64ScalableVecTy));175 176  // bitcast <4 x ptr> to <4 x ptr>177  EXPECT_EQ(178      Constant::getNullValue(PtrVecTy),179      ConstantExpr::getPointerCast(Constant::getNullValue(PtrVecTy), PtrVecTy));180 181  // bitcast <vscale x 4 x ptr> to <vscale x 4 x ptr>182  EXPECT_EQ(Constant::getNullValue(PtrScalableVecTy),183            ConstantExpr::getPointerCast(184                Constant::getNullValue(PtrScalableVecTy), PtrScalableVecTy));185 186  Type *Ptr1Ty = PointerType::get(C, 1);187  ConstantInt *K = ConstantInt::get(Type::getInt64Ty(C), 1234);188 189  // Make sure that addrspacecast of inttoptr is not folded away.190  EXPECT_NE(K, ConstantExpr::getAddrSpaceCast(191                   ConstantExpr::getIntToPtr(K, PtrTy), Ptr1Ty));192  EXPECT_NE(K, ConstantExpr::getAddrSpaceCast(193                   ConstantExpr::getIntToPtr(K, Ptr1Ty), PtrTy));194 195  Constant *NullPtr0 = Constant::getNullValue(PtrTy);196  Constant *NullPtr1 = Constant::getNullValue(Ptr1Ty);197 198  // Make sure that addrspacecast of null is not folded away.199  EXPECT_NE(Constant::getNullValue(PtrTy),200            ConstantExpr::getAddrSpaceCast(NullPtr0, Ptr1Ty));201 202  EXPECT_NE(Constant::getNullValue(Ptr1Ty),203            ConstantExpr::getAddrSpaceCast(NullPtr1, PtrTy));204}205 206#define CHECK(x, y)                                                            \207  {                                                                            \208    std::string __s;                                                           \209    raw_string_ostream __o(__s);                                               \210    Instruction *__I = cast<ConstantExpr>(x)->getAsInstruction();              \211    __I->print(__o);                                                           \212    __I->deleteValue();                                                        \213    EXPECT_EQ(std::string("  <badref> = " y), __s);                            \214  }215 216TEST(ConstantsTest, AsInstructionsTest) {217  LLVMContext Context;218  std::unique_ptr<Module> M(new Module("MyModule", Context));219 220  Type *Int64Ty = Type::getInt64Ty(Context);221  Type *Int32Ty = Type::getInt32Ty(Context);222  Type *Int16Ty = Type::getInt16Ty(Context);223 224  Constant *Global =225      M->getOrInsertGlobal("dummy", PointerType::getUnqual(Context));226  Constant *Global2 =227      M->getOrInsertGlobal("dummy2", PointerType::getUnqual(Context));228 229  Constant *P0 = ConstantExpr::getPtrToInt(Global, Int32Ty);230  Constant *P4 = ConstantExpr::getPtrToInt(Global2, Int32Ty);231  Constant *P6 = ConstantExpr::getBitCast(P4, FixedVectorType::get(Int16Ty, 2));232 233  Constant *One = ConstantInt::get(Int32Ty, 1);234  Constant *Two = ConstantInt::get(Int64Ty, 2);235  Constant *Big = ConstantInt::get(Context, APInt{256, uint64_t(-1), true});236  Constant *Elt = ConstantInt::get(Int16Ty, 2015);237  Constant *Poison16 = PoisonValue::get(Int16Ty);238  Constant *Undef64 = UndefValue::get(Int64Ty);239  Constant *PoisonV16 = PoisonValue::get(P6->getType());240 241#define P0STR "ptrtoint (ptr @dummy to i32)"242#define P3STR "ptrtoint (ptr @dummy to i1)"243#define P4STR "ptrtoint (ptr @dummy2 to i32)"244#define P6STR "bitcast (i32 ptrtoint (ptr @dummy2 to i32) to <2 x i16>)"245 246  CHECK(ConstantExpr::getNeg(P0), "sub i32 0, " P0STR);247  CHECK(ConstantExpr::getNot(P0), "xor i32 " P0STR ", -1");248  CHECK(ConstantExpr::getAdd(P0, P0), "add i32 " P0STR ", " P0STR);249  CHECK(ConstantExpr::getAdd(P0, P0, false, true),250        "add nsw i32 " P0STR ", " P0STR);251  CHECK(ConstantExpr::getAdd(P0, P0, true, true),252        "add nuw nsw i32 " P0STR ", " P0STR);253  CHECK(ConstantExpr::getSub(P0, P0), "sub i32 " P0STR ", " P0STR);254  CHECK(ConstantExpr::getXor(P0, P0), "xor i32 " P0STR ", " P0STR);255 256  std::vector<Constant *> V;257  V.push_back(One);258  // FIXME: getGetElementPtr() actually creates an inbounds ConstantGEP,259  //        not a normal one!260  // CHECK(ConstantExpr::getGetElementPtr(Global, V, false),261  //      "getelementptr i32*, i32** @dummy, i32 1");262  CHECK(ConstantExpr::getInBoundsGetElementPtr(PointerType::getUnqual(Context),263                                               Global, V),264        "getelementptr inbounds ptr, ptr @dummy, i32 1");265 266  CHECK(ConstantExpr::getExtractElement(P6, One),267        "extractelement <2 x i16> " P6STR ", i32 1");268 269  EXPECT_EQ(Poison16, ConstantExpr::getExtractElement(P6, Two));270  EXPECT_EQ(Poison16, ConstantExpr::getExtractElement(P6, Big));271  EXPECT_EQ(Poison16, ConstantExpr::getExtractElement(P6, Undef64));272 273  EXPECT_EQ(Elt, ConstantExpr::getExtractElement(274                 ConstantExpr::getInsertElement(P6, Elt, One), One));275  EXPECT_EQ(PoisonV16, ConstantExpr::getInsertElement(P6, Elt, Two));276  EXPECT_EQ(PoisonV16, ConstantExpr::getInsertElement(P6, Elt, Big));277  EXPECT_EQ(PoisonV16, ConstantExpr::getInsertElement(P6, Elt, Undef64));278}279 280#ifdef GTEST_HAS_DEATH_TEST281#ifndef NDEBUG282TEST(ConstantsTest, ReplaceWithConstantTest) {283  LLVMContext Context;284  std::unique_ptr<Module> M(new Module("MyModule", Context));285 286  Type *Int32Ty = Type::getInt32Ty(Context);287  Constant *One = ConstantInt::get(Int32Ty, 1);288 289  Constant *Global =290      M->getOrInsertGlobal("dummy", PointerType::getUnqual(Context));291  Constant *GEP = ConstantExpr::getGetElementPtr(292      PointerType::getUnqual(Context), Global, One);293  EXPECT_DEATH(Global->replaceAllUsesWith(GEP),294               "this->replaceAllUsesWith\\(expr\\(this\\)\\) is NOT valid!");295}296 297#endif298#endif299 300#undef CHECK301 302TEST(ConstantsTest, ConstantArrayReplaceWithConstant) {303  LLVMContext Context;304  std::unique_ptr<Module> M(new Module("MyModule", Context));305 306  Type *IntTy = Type::getInt8Ty(Context);307  ArrayType *ArrayTy = ArrayType::get(IntTy, 2);308  Constant *A01Vals[2] = {ConstantInt::get(IntTy, 0),309                          ConstantInt::get(IntTy, 1)};310  Constant *A01 = ConstantArray::get(ArrayTy, A01Vals);311 312  Constant *Global = new GlobalVariable(*M, IntTy, false,313                                        GlobalValue::ExternalLinkage, nullptr);314  Constant *GlobalInt = ConstantExpr::getPtrToInt(Global, IntTy);315  Constant *A0GVals[2] = {ConstantInt::get(IntTy, 0), GlobalInt};316  Constant *A0G = ConstantArray::get(ArrayTy, A0GVals);317  ASSERT_NE(A01, A0G);318 319  GlobalVariable *RefArray =320      new GlobalVariable(*M, ArrayTy, false, GlobalValue::ExternalLinkage, A0G);321  ASSERT_EQ(A0G, RefArray->getInitializer());322 323  GlobalInt->replaceAllUsesWith(ConstantInt::get(IntTy, 1));324  ASSERT_EQ(A01, RefArray->getInitializer());325}326 327TEST(ConstantsTest, ConstantExprReplaceWithConstant) {328  LLVMContext Context;329  std::unique_ptr<Module> M(new Module("MyModule", Context));330 331  Type *IntTy = Type::getInt8Ty(Context);332  Constant *G1 = new GlobalVariable(*M, IntTy, false,333                                    GlobalValue::ExternalLinkage, nullptr);334  Constant *G2 = new GlobalVariable(*M, IntTy, false,335                                    GlobalValue::ExternalLinkage, nullptr);336  ASSERT_NE(G1, G2);337 338  Constant *Int1 = ConstantExpr::getPtrToInt(G1, IntTy);339  Constant *Int2 = ConstantExpr::getPtrToInt(G2, IntTy);340  ASSERT_NE(Int1, Int2);341 342  GlobalVariable *Ref =343      new GlobalVariable(*M, IntTy, false, GlobalValue::ExternalLinkage, Int1);344  ASSERT_EQ(Int1, Ref->getInitializer());345 346  G1->replaceAllUsesWith(G2);347  ASSERT_EQ(Int2, Ref->getInitializer());348}349 350TEST(ConstantsTest, GEPReplaceWithConstant) {351  LLVMContext Context;352  std::unique_ptr<Module> M(new Module("MyModule", Context));353 354  Type *IntTy = Type::getInt32Ty(Context);355  Type *PtrTy = PointerType::get(Context, 0);356  auto *C1 = ConstantInt::get(IntTy, 1);357  auto *Placeholder = new GlobalVariable(358      *M, IntTy, false, GlobalValue::ExternalWeakLinkage, nullptr);359  auto *GEP = ConstantExpr::getGetElementPtr(IntTy, Placeholder, C1);360  ASSERT_EQ(GEP->getOperand(0), Placeholder);361 362  auto *Ref =363      new GlobalVariable(*M, PtrTy, false, GlobalValue::ExternalLinkage, GEP);364  ASSERT_EQ(GEP, Ref->getInitializer());365 366  auto *Global = new GlobalVariable(*M, IntTy, false,367                                    GlobalValue::ExternalLinkage, nullptr);368  auto *Alias = GlobalAlias::create(IntTy, 0, GlobalValue::ExternalLinkage,369                                    "alias", Global, M.get());370  Placeholder->replaceAllUsesWith(Alias);371  ASSERT_EQ(GEP, Ref->getInitializer());372  ASSERT_EQ(GEP->getOperand(0), Alias);373}374 375TEST(ConstantsTest, AliasCAPI) {376  LLVMContext Context;377  SMDiagnostic Error;378  std::unique_ptr<Module> M =379      parseAssemblyString("@g = global i32 42", Error, Context);380  GlobalVariable *G = M->getGlobalVariable("g");381  Type *I16Ty = Type::getInt16Ty(Context);382  Type *I16PTy = PointerType::get(Context, 0);383  Constant *Aliasee = ConstantExpr::getBitCast(G, I16PTy);384  LLVMValueRef AliasRef =385      LLVMAddAlias2(wrap(M.get()), wrap(I16Ty), 0, wrap(Aliasee), "a");386  ASSERT_EQ(unwrap<GlobalAlias>(AliasRef)->getAliasee(), Aliasee);387}388 389static std::string getNameOfType(Type *T) {390  std::string S;391  raw_string_ostream RSOS(S);392  T->print(RSOS);393  return S;394}395 396TEST(ConstantsTest, BuildConstantDataArrays) {397  LLVMContext Context;398 399  for (Type *T : {Type::getInt8Ty(Context), Type::getInt16Ty(Context),400                  Type::getInt32Ty(Context), Type::getInt64Ty(Context)}) {401    ArrayType *ArrayTy = ArrayType::get(T, 2);402    Constant *Vals[] = {ConstantInt::get(T, 0), ConstantInt::get(T, 1)};403    Constant *CA = ConstantArray::get(ArrayTy, Vals);404    ASSERT_TRUE(isa<ConstantDataArray>(CA)) << " T = " << getNameOfType(T);405    auto *CDA = cast<ConstantDataArray>(CA);406    Constant *CA2 = ConstantDataArray::getRaw(407        CDA->getRawDataValues(), CDA->getNumElements(), CDA->getElementType());408    ASSERT_TRUE(CA == CA2) << " T = " << getNameOfType(T);409  }410 411  for (Type *T : {Type::getHalfTy(Context), Type::getBFloatTy(Context),412                  Type::getFloatTy(Context), Type::getDoubleTy(Context)}) {413    ArrayType *ArrayTy = ArrayType::get(T, 2);414    Constant *Vals[] = {ConstantFP::get(T, 0), ConstantFP::get(T, 1)};415    Constant *CA = ConstantArray::get(ArrayTy, Vals);416    ASSERT_TRUE(isa<ConstantDataArray>(CA)) << " T = " << getNameOfType(T);417    auto *CDA = cast<ConstantDataArray>(CA);418    Constant *CA2 = ConstantDataArray::getRaw(419        CDA->getRawDataValues(), CDA->getNumElements(), CDA->getElementType());420    ASSERT_TRUE(CA == CA2) << " T = " << getNameOfType(T);421  }422}423 424TEST(ConstantsTest, BuildConstantDataVectors) {425  LLVMContext Context;426 427  for (Type *T : {Type::getInt8Ty(Context), Type::getInt16Ty(Context),428                  Type::getInt32Ty(Context), Type::getInt64Ty(Context)}) {429    Constant *Vals[] = {ConstantInt::get(T, 0), ConstantInt::get(T, 1)};430    Constant *CV = ConstantVector::get(Vals);431    ASSERT_TRUE(isa<ConstantDataVector>(CV)) << " T = " << getNameOfType(T);432    auto *CDV = cast<ConstantDataVector>(CV);433    Constant *CV2 = ConstantDataVector::getRaw(434        CDV->getRawDataValues(), CDV->getNumElements(), CDV->getElementType());435    ASSERT_TRUE(CV == CV2) << " T = " << getNameOfType(T);436  }437 438  for (Type *T : {Type::getHalfTy(Context), Type::getBFloatTy(Context),439                  Type::getFloatTy(Context), Type::getDoubleTy(Context)}) {440    Constant *Vals[] = {ConstantFP::get(T, 0), ConstantFP::get(T, 1)};441    Constant *CV = ConstantVector::get(Vals);442    ASSERT_TRUE(isa<ConstantDataVector>(CV)) << " T = " << getNameOfType(T);443    auto *CDV = cast<ConstantDataVector>(CV);444    Constant *CV2 = ConstantDataVector::getRaw(445        CDV->getRawDataValues(), CDV->getNumElements(), CDV->getElementType());446    ASSERT_TRUE(CV == CV2) << " T = " << getNameOfType(T);447  }448}449 450TEST(ConstantsTest, BitcastToGEP) {451  LLVMContext Context;452  std::unique_ptr<Module> M(new Module("MyModule", Context));453 454  auto *i32 = Type::getInt32Ty(Context);455  auto *U = StructType::create(Context, "Unsized");456  Type *EltTys[] = {i32, U};457  auto *S = StructType::create(EltTys);458 459  auto *G =460      new GlobalVariable(*M, S, false, GlobalValue::ExternalLinkage, nullptr);461  auto *PtrTy = PointerType::get(Context, 0);462  auto *C = ConstantExpr::getBitCast(G, PtrTy);463  /* With opaque pointers, no cast is necessary. */464  EXPECT_EQ(C, G);465}466 467bool foldFuncPtrAndConstToNull(LLVMContext &Context, Module *TheModule,468                               uint64_t AndValue,469                               MaybeAlign FunctionAlign = std::nullopt) {470  Type *VoidType(Type::getVoidTy(Context));471  FunctionType *FuncType(FunctionType::get(VoidType, false));472  Function *Func(473      Function::Create(FuncType, GlobalValue::ExternalLinkage, "", TheModule));474 475  if (FunctionAlign)476    Func->setAlignment(*FunctionAlign);477 478  IntegerType *ConstantIntType(Type::getInt32Ty(Context));479  ConstantInt *TheConstant(ConstantInt::get(ConstantIntType, AndValue));480 481  Constant *TheConstantExpr(ConstantExpr::getPtrToInt(Func, ConstantIntType));482 483  Constant *C = ConstantFoldBinaryInstruction(Instruction::And, TheConstantExpr,484                                              TheConstant);485  bool Result = C && C->isNullValue();486 487  if (!TheModule) {488    // If the Module exists then it will delete the Function.489    delete Func;490  }491 492  return Result;493}494 495TEST(ConstantsTest, FoldFunctionPtrAlignUnknownAnd2) {496  LLVMContext Context;497  Module TheModule("TestModule", Context);498  // When the DataLayout doesn't specify a function pointer alignment we499  // assume in this case that it is 4 byte aligned. This is a bug but we can't500  // fix it directly because it causes a code size regression on X86.501  // FIXME: This test should be changed once existing targets have502  // appropriate defaults. See associated FIXME in ConstantFoldBinaryInstruction503  ASSERT_TRUE(foldFuncPtrAndConstToNull(Context, &TheModule, 2));504}505 506TEST(ConstantsTest, DontFoldFunctionPtrAlignUnknownAnd4) {507  LLVMContext Context;508  Module TheModule("TestModule", Context);509  ASSERT_FALSE(foldFuncPtrAndConstToNull(Context, &TheModule, 4));510}511 512TEST(ConstantsTest, FoldFunctionPtrAlign4) {513  LLVMContext Context;514  Module TheModule("TestModule", Context);515  const char *AlignmentStrings[] = {"Fi32", "Fn32"};516 517  for (unsigned AndValue = 1; AndValue <= 2; ++AndValue) {518    for (const char *AlignmentString : AlignmentStrings) {519      TheModule.setDataLayout(AlignmentString);520      ASSERT_TRUE(foldFuncPtrAndConstToNull(Context, &TheModule, AndValue));521    }522  }523}524 525TEST(ConstantsTest, DontFoldFunctionPtrAlign1) {526  LLVMContext Context;527  Module TheModule("TestModule", Context);528  const char *AlignmentStrings[] = {"Fi8", "Fn8"};529 530  for (const char *AlignmentString : AlignmentStrings) {531    TheModule.setDataLayout(AlignmentString);532    ASSERT_FALSE(foldFuncPtrAndConstToNull(Context, &TheModule, 2));533  }534}535 536TEST(ConstantsTest, FoldFunctionAlign4PtrAlignMultiple) {537  LLVMContext Context;538  Module TheModule("TestModule", Context);539  TheModule.setDataLayout("Fn8");540  ASSERT_TRUE(foldFuncPtrAndConstToNull(Context, &TheModule, 2, Align(4)));541}542 543TEST(ConstantsTest, DontFoldFunctionAlign4PtrAlignIndependent) {544  LLVMContext Context;545  Module TheModule("TestModule", Context);546  TheModule.setDataLayout("Fi8");547  ASSERT_FALSE(foldFuncPtrAndConstToNull(Context, &TheModule, 2, Align(4)));548}549 550TEST(ConstantsTest, DontFoldFunctionPtrIfNoModule) {551  LLVMContext Context;552  // Even though the function is explicitly 4 byte aligned, in the absence of a553  // DataLayout we can't assume that the function pointer is aligned.554  ASSERT_FALSE(foldFuncPtrAndConstToNull(Context, nullptr, 2, Align(4)));555}556 557TEST(ConstantsTest, FoldGlobalVariablePtr) {558  LLVMContext Context;559 560  IntegerType *IntType(Type::getInt32Ty(Context));561 562  std::unique_ptr<GlobalVariable> Global(563      new GlobalVariable(IntType, true, GlobalValue::ExternalLinkage));564 565  Global->setAlignment(Align(4));566 567  ConstantInt *TheConstant = ConstantInt::get(IntType, 2);568 569  Constant *PtrToInt = ConstantExpr::getPtrToInt(Global.get(), IntType);570  ASSERT_TRUE(571      ConstantFoldBinaryInstruction(Instruction::And, PtrToInt, TheConstant)572          ->isNullValue());573 574  Constant *PtrToAddr = ConstantExpr::getPtrToAddr(Global.get(), IntType);575  ASSERT_TRUE(576      ConstantFoldBinaryInstruction(Instruction::And, PtrToAddr, TheConstant)577          ->isNullValue());578}579 580// Check that containsUndefOrPoisonElement and containsPoisonElement is working581// great582 583TEST(ConstantsTest, containsUndefElemTest) {584  LLVMContext Context;585 586  Type *Int32Ty = Type::getInt32Ty(Context);587  Constant *CU = UndefValue::get(Int32Ty);588  Constant *CP = PoisonValue::get(Int32Ty);589  Constant *C1 = ConstantInt::get(Int32Ty, 1);590  Constant *C2 = ConstantInt::get(Int32Ty, 2);591 592  {593    Constant *V1 = ConstantVector::get({C1, C2});594    EXPECT_FALSE(V1->containsUndefOrPoisonElement());595    EXPECT_FALSE(V1->containsPoisonElement());596  }597 598  {599    Constant *V2 = ConstantVector::get({C1, CU});600    EXPECT_TRUE(V2->containsUndefOrPoisonElement());601    EXPECT_FALSE(V2->containsPoisonElement());602  }603 604  {605    Constant *V3 = ConstantVector::get({C1, CP});606    EXPECT_TRUE(V3->containsUndefOrPoisonElement());607    EXPECT_TRUE(V3->containsPoisonElement());608  }609 610  {611    Constant *V4 = ConstantVector::get({CU, CP});612    EXPECT_TRUE(V4->containsUndefOrPoisonElement());613    EXPECT_TRUE(V4->containsPoisonElement());614  }615}616 617// Check that poison elements in vector constants are matched618// correctly for both integer and floating-point types. Just don't619// crash on vectors of pointers (could be handled?).620 621TEST(ConstantsTest, isElementWiseEqual) {622  LLVMContext Context;623 624  Type *Int32Ty = Type::getInt32Ty(Context);625  Constant *CU = UndefValue::get(Int32Ty);626  Constant *CP = PoisonValue::get(Int32Ty);627  Constant *C1 = ConstantInt::get(Int32Ty, 1);628  Constant *C2 = ConstantInt::get(Int32Ty, 2);629 630  Constant *C1211 = ConstantVector::get({C1, C2, C1, C1});631  Constant *C12U1 = ConstantVector::get({C1, C2, CU, C1});632  Constant *C12U2 = ConstantVector::get({C1, C2, CU, C2});633  Constant *C12U21 = ConstantVector::get({C1, C2, CU, C2, C1});634  Constant *C12P1 = ConstantVector::get({C1, C2, CP, C1});635  Constant *C12P2 = ConstantVector::get({C1, C2, CP, C2});636  Constant *C12P21 = ConstantVector::get({C1, C2, CP, C2, C1});637 638  EXPECT_FALSE(C1211->isElementWiseEqual(C12U1));639  EXPECT_FALSE(C12U1->isElementWiseEqual(C1211));640  EXPECT_FALSE(C12U2->isElementWiseEqual(C12U1));641  EXPECT_FALSE(C12U1->isElementWiseEqual(C12U2));642  EXPECT_FALSE(C12U21->isElementWiseEqual(C12U2));643 644  EXPECT_TRUE(C1211->isElementWiseEqual(C12P1));645  EXPECT_TRUE(C12P1->isElementWiseEqual(C1211));646  EXPECT_FALSE(C12P2->isElementWiseEqual(C12P1));647  EXPECT_FALSE(C12P1->isElementWiseEqual(C12P2));648  EXPECT_FALSE(C12P21->isElementWiseEqual(C12P2));649 650  Type *FltTy = Type::getFloatTy(Context);651  Constant *CFU = UndefValue::get(FltTy);652  Constant *CFP = PoisonValue::get(FltTy);653  Constant *CF1 = ConstantFP::get(FltTy, 1.0);654  Constant *CF2 = ConstantFP::get(FltTy, 2.0);655 656  Constant *CF1211 = ConstantVector::get({CF1, CF2, CF1, CF1});657  Constant *CF12U1 = ConstantVector::get({CF1, CF2, CFU, CF1});658  Constant *CF12U2 = ConstantVector::get({CF1, CF2, CFU, CF2});659  Constant *CFUU1U = ConstantVector::get({CFU, CFU, CF1, CFU});660  Constant *CF12P1 = ConstantVector::get({CF1, CF2, CFP, CF1});661  Constant *CF12P2 = ConstantVector::get({CF1, CF2, CFP, CF2});662  Constant *CFPP1P = ConstantVector::get({CFP, CFP, CF1, CFP});663 664  EXPECT_FALSE(CF1211->isElementWiseEqual(CF12U1));665  EXPECT_FALSE(CF12U1->isElementWiseEqual(CF1211));666  EXPECT_FALSE(CFUU1U->isElementWiseEqual(CF12U1));667  EXPECT_FALSE(CF12U2->isElementWiseEqual(CF12U1));668  EXPECT_FALSE(CF12U1->isElementWiseEqual(CF12U2));669 670  EXPECT_TRUE(CF1211->isElementWiseEqual(CF12P1));671  EXPECT_TRUE(CF12P1->isElementWiseEqual(CF1211));672  EXPECT_TRUE(CFPP1P->isElementWiseEqual(CF12P1));673  EXPECT_FALSE(CF12P2->isElementWiseEqual(CF12P1));674  EXPECT_FALSE(CF12P1->isElementWiseEqual(CF12P2));675 676  PointerType *PtrTy = PointerType::get(Context, 0);677  Constant *CPU = UndefValue::get(PtrTy);678  Constant *CPP = PoisonValue::get(PtrTy);679  Constant *CP0 = ConstantPointerNull::get(PtrTy);680 681  Constant *CP0000 = ConstantVector::get({CP0, CP0, CP0, CP0});682  Constant *CP00U0 = ConstantVector::get({CP0, CP0, CPU, CP0});683  Constant *CP00U = ConstantVector::get({CP0, CP0, CPU});684  Constant *CP00P0 = ConstantVector::get({CP0, CP0, CPP, CP0});685  Constant *CP00P = ConstantVector::get({CP0, CP0, CPP});686 687  EXPECT_FALSE(CP0000->isElementWiseEqual(CP00U0));688  EXPECT_FALSE(CP00U0->isElementWiseEqual(CP0000));689  EXPECT_FALSE(CP0000->isElementWiseEqual(CP00U));690  EXPECT_FALSE(CP00U->isElementWiseEqual(CP00U0));691  EXPECT_FALSE(CP0000->isElementWiseEqual(CP00P0));692  EXPECT_FALSE(CP00P0->isElementWiseEqual(CP0000));693  EXPECT_FALSE(CP0000->isElementWiseEqual(CP00P));694  EXPECT_FALSE(CP00P->isElementWiseEqual(CP00P0));695}696 697// Check that vector/aggregate constants correctly store undef and poison698// elements.699 700TEST(ConstantsTest, CheckElementWiseUndefPoison) {701  LLVMContext Context;702 703  Type *Int32Ty = Type::getInt32Ty(Context);704  StructType *STy = StructType::get(Int32Ty, Int32Ty);705  ArrayType *ATy = ArrayType::get(Int32Ty, 2);706  Constant *CU = UndefValue::get(Int32Ty);707  Constant *CP = PoisonValue::get(Int32Ty);708 709  {710    Constant *CUU = ConstantVector::get({CU, CU});711    Constant *CPP = ConstantVector::get({CP, CP});712    Constant *CUP = ConstantVector::get({CU, CP});713    Constant *CPU = ConstantVector::get({CP, CU});714    EXPECT_EQ(CUU, UndefValue::get(CUU->getType()));715    EXPECT_EQ(CPP, PoisonValue::get(CPP->getType()));716    EXPECT_NE(CUP, UndefValue::get(CUP->getType()));717    EXPECT_NE(CPU, UndefValue::get(CPU->getType()));718  }719 720  {721    Constant *CUU = ConstantStruct::get(STy, {CU, CU});722    Constant *CPP = ConstantStruct::get(STy, {CP, CP});723    Constant *CUP = ConstantStruct::get(STy, {CU, CP});724    Constant *CPU = ConstantStruct::get(STy, {CP, CU});725    EXPECT_EQ(CUU, UndefValue::get(CUU->getType()));726    EXPECT_EQ(CPP, PoisonValue::get(CPP->getType()));727    EXPECT_NE(CUP, UndefValue::get(CUP->getType()));728    EXPECT_NE(CPU, UndefValue::get(CPU->getType()));729  }730 731  {732    Constant *CUU = ConstantArray::get(ATy, {CU, CU});733    Constant *CPP = ConstantArray::get(ATy, {CP, CP});734    Constant *CUP = ConstantArray::get(ATy, {CU, CP});735    Constant *CPU = ConstantArray::get(ATy, {CP, CU});736    EXPECT_EQ(CUU, UndefValue::get(CUU->getType()));737    EXPECT_EQ(CPP, PoisonValue::get(CPP->getType()));738    EXPECT_NE(CUP, UndefValue::get(CUP->getType()));739    EXPECT_NE(CPU, UndefValue::get(CPU->getType()));740  }741}742 743TEST(ConstantsTest, GetSplatValueRoundTrip) {744  LLVMContext Context;745 746  Type *FloatTy = Type::getFloatTy(Context);747  Type *Int32Ty = Type::getInt32Ty(Context);748  Type *Int8Ty = Type::getInt8Ty(Context);749 750  for (unsigned Min : {1, 2, 8}) {751    auto ScalableEC = ElementCount::getScalable(Min);752    auto FixedEC = ElementCount::getFixed(Min);753 754    for (auto EC : {ScalableEC, FixedEC}) {755      for (auto *Ty : {FloatTy, Int32Ty, Int8Ty}) {756        Constant *Zero = Constant::getNullValue(Ty);757        Constant *One = Constant::getAllOnesValue(Ty);758 759        for (auto *C : {Zero, One}) {760          Constant *Splat = ConstantVector::getSplat(EC, C);761          ASSERT_NE(nullptr, Splat);762 763          Constant *SplatVal = Splat->getSplatValue();764          EXPECT_NE(nullptr, SplatVal);765          EXPECT_EQ(SplatVal, C);766        }767      }768    }769  }770}771 772TEST(ConstantsTest, ComdatUserTracking) {773  LLVMContext Context;774  Module M("MyModule", Context);775 776  Comdat *C = M.getOrInsertComdat("comdat");777  const SmallPtrSetImpl<GlobalObject *> &Users = C->getUsers();778  EXPECT_TRUE(Users.size() == 0);779 780  Type *Ty = Type::getInt8Ty(Context);781  GlobalVariable *GV1 = M.getOrInsertGlobal("gv1", Ty);782  GV1->setComdat(C);783  EXPECT_TRUE(Users.size() == 1);784  EXPECT_TRUE(Users.contains(GV1));785 786  GlobalVariable *GV2 = M.getOrInsertGlobal("gv2", Ty);787  GV2->setComdat(C);788  EXPECT_TRUE(Users.size() == 2);789  EXPECT_TRUE(Users.contains(GV2));790 791  GV1->eraseFromParent();792  EXPECT_TRUE(Users.size() == 1);793  EXPECT_TRUE(Users.contains(GV2));794 795  GV2->eraseFromParent();796  EXPECT_TRUE(Users.size() == 0);797}798 799// Verify that the C API getters for BlockAddress work800TEST(ConstantsTest, BlockAddressCAPITest) {801  const char *BlockAddressIR = R"(802    define void @test_block_address_func() {803    entry:804      br label %block_bb_0805    block_bb_0:806      ret void807    }808  )";809 810  LLVMContext Context;811  SMDiagnostic Error;812  std::unique_ptr<Module> M =813      parseAssemblyString(BlockAddressIR, Error, Context);814 815  EXPECT_TRUE(M.get() != nullptr);816 817  // Get the function818  auto *Func = M->getFunction("test_block_address_func");819  EXPECT_TRUE(Func != nullptr);820 821  // Get the second basic block, since we can't use the entry one822  const BasicBlock &BB = *(++Func->begin());823  EXPECT_EQ(BB.getName(), "block_bb_0");824 825  // Construct the C API values826  LLVMValueRef BlockAddr = LLVMBlockAddress(wrap(Func), wrap(&BB));827  EXPECT_TRUE(LLVMIsABlockAddress(BlockAddr));828 829  // Get the Function/BasicBlock values back out830  auto *OutFunc = unwrap(LLVMGetBlockAddressFunction(BlockAddr));831  auto *OutBB = unwrap(LLVMGetBlockAddressBasicBlock(BlockAddr));832 833  // Verify that they round-tripped properly834  EXPECT_EQ(Func, OutFunc);835  EXPECT_EQ(&BB, OutBB);836}837 838} // end anonymous namespace839} // end namespace llvm840