From 19443c1bcb863ba186abfe0bda3a1603488d17f7 Mon Sep 17 00:00:00 2001 From: David Blaikie Date: Thu, 2 Apr 2015 18:55:32 +0000 Subject: [PATCH] [opaque pointer type] API migration for GEP constant factories Require the pointee type to be passed explicitly and assert that it is correct. For now it's possible to pass nullptr here (and I've done so in a few places in this patch) but eventually that will be disallowed once all clients have been updated or removed. It'll be a long road to get all the way there... but if you have the cahnce to update your callers to pass the type explicitly without depending on a pointer's element type, that would be a good thing to do soon and a necessary thing to do eventually. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@233938 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Analysis/TargetFolder.h | 12 ++++---- include/llvm/IR/ConstantFolder.h | 12 ++++---- include/llvm/IR/Constants.h | 24 ++++++++-------- include/llvm/IR/GlobalValue.h | 12 ++++---- include/llvm/IR/NoFolder.h | 8 +++--- lib/Analysis/ConstantFolding.cpp | 20 +++++++------ lib/Analysis/InstructionSimplify.cpp | 25 ++++++++++------- lib/Analysis/ScalarEvolution.cpp | 2 +- lib/Analysis/ScalarEvolutionExpander.cpp | 3 +- lib/AsmParser/LLParser.cpp | 9 ++---- lib/Bitcode/Reader/BitcodeReader.cpp | 13 +++++---- lib/CodeGen/GlobalMerge.cpp | 3 +- lib/CodeGen/ShadowStackGCLowering.cpp | 2 +- lib/IR/ConstantFold.cpp | 18 ++++++------ lib/IR/Constants.cpp | 28 ++++++++++--------- lib/IR/Core.cpp | 6 ++-- .../NVPTX/NVPTXFavorNonGenericAddrSpaces.cpp | 5 ++-- lib/Target/XCore/XCoreISelLowering.cpp | 3 +- lib/Transforms/IPO/GlobalOpt.cpp | 15 ++++++---- lib/Transforms/IPO/LowerBitSets.cpp | 7 +++-- .../Instrumentation/AddressSanitizer.cpp | 2 +- lib/Transforms/Scalar/GVN.cpp | 6 ++-- lib/Transforms/Scalar/SCCP.cpp | 3 +- tools/bugpoint/Miscompilation.cpp | 3 +- unittests/IR/ConstantsTest.cpp | 8 ++++-- 25 files changed, 136 insertions(+), 113 deletions(-) diff --git a/include/llvm/Analysis/TargetFolder.h b/include/llvm/Analysis/TargetFolder.h index f69129690d3..6c132aba63e 100644 --- a/include/llvm/Analysis/TargetFolder.h +++ b/include/llvm/Analysis/TargetFolder.h @@ -132,32 +132,32 @@ public: Constant *CreateGetElementPtr(Constant *C, ArrayRef IdxList) const { - return Fold(ConstantExpr::getGetElementPtr(C, IdxList)); + return Fold(ConstantExpr::getGetElementPtr(nullptr, C, IdxList)); } Constant *CreateGetElementPtr(Constant *C, Constant *Idx) const { // This form of the function only exists to avoid ambiguous overload // warnings about whether to convert Idx to ArrayRef or // ArrayRef. - return Fold(ConstantExpr::getGetElementPtr(C, Idx)); + return Fold(ConstantExpr::getGetElementPtr(nullptr, C, Idx)); } Constant *CreateGetElementPtr(Constant *C, ArrayRef IdxList) const { - return Fold(ConstantExpr::getGetElementPtr(C, IdxList)); + return Fold(ConstantExpr::getGetElementPtr(nullptr, C, IdxList)); } Constant *CreateInBoundsGetElementPtr(Constant *C, ArrayRef IdxList) const { - return Fold(ConstantExpr::getInBoundsGetElementPtr(C, IdxList)); + return Fold(ConstantExpr::getInBoundsGetElementPtr(nullptr, C, IdxList)); } Constant *CreateInBoundsGetElementPtr(Constant *C, Constant *Idx) const { // This form of the function only exists to avoid ambiguous overload // warnings about whether to convert Idx to ArrayRef or // ArrayRef. - return Fold(ConstantExpr::getInBoundsGetElementPtr(C, Idx)); + return Fold(ConstantExpr::getInBoundsGetElementPtr(nullptr, C, Idx)); } Constant *CreateInBoundsGetElementPtr(Constant *C, ArrayRef IdxList) const { - return Fold(ConstantExpr::getInBoundsGetElementPtr(C, IdxList)); + return Fold(ConstantExpr::getInBoundsGetElementPtr(nullptr, C, IdxList)); } //===--------------------------------------------------------------------===// diff --git a/include/llvm/IR/ConstantFolder.h b/include/llvm/IR/ConstantFolder.h index e271a148211..aba38462c8b 100644 --- a/include/llvm/IR/ConstantFolder.h +++ b/include/llvm/IR/ConstantFolder.h @@ -120,32 +120,32 @@ public: Constant *CreateGetElementPtr(Constant *C, ArrayRef IdxList) const { - return ConstantExpr::getGetElementPtr(C, IdxList); + return ConstantExpr::getGetElementPtr(nullptr, C, IdxList); } Constant *CreateGetElementPtr(Constant *C, Constant *Idx) const { // This form of the function only exists to avoid ambiguous overload // warnings about whether to convert Idx to ArrayRef or // ArrayRef. - return ConstantExpr::getGetElementPtr(C, Idx); + return ConstantExpr::getGetElementPtr(nullptr, C, Idx); } Constant *CreateGetElementPtr(Constant *C, ArrayRef IdxList) const { - return ConstantExpr::getGetElementPtr(C, IdxList); + return ConstantExpr::getGetElementPtr(nullptr, C, IdxList); } Constant *CreateInBoundsGetElementPtr(Constant *C, ArrayRef IdxList) const { - return ConstantExpr::getInBoundsGetElementPtr(C, IdxList); + return ConstantExpr::getInBoundsGetElementPtr(nullptr, C, IdxList); } Constant *CreateInBoundsGetElementPtr(Constant *C, Constant *Idx) const { // This form of the function only exists to avoid ambiguous overload // warnings about whether to convert Idx to ArrayRef or // ArrayRef. - return ConstantExpr::getInBoundsGetElementPtr(C, Idx); + return ConstantExpr::getInBoundsGetElementPtr(nullptr, C, Idx); } Constant *CreateInBoundsGetElementPtr(Constant *C, ArrayRef IdxList) const { - return ConstantExpr::getInBoundsGetElementPtr(C, IdxList); + return ConstantExpr::getInBoundsGetElementPtr(nullptr, C, IdxList); } //===--------------------------------------------------------------------===// diff --git a/include/llvm/IR/Constants.h b/include/llvm/IR/Constants.h index 59be6531da3..21189752eb3 100644 --- a/include/llvm/IR/Constants.h +++ b/include/llvm/IR/Constants.h @@ -1057,41 +1057,43 @@ public: /// all elements must be Constant's. /// /// \param OnlyIfReducedTy see \a getWithOperands() docs. - static Constant *getGetElementPtr(Constant *C, ArrayRef IdxList, + static Constant *getGetElementPtr(Type *Ty, Constant *C, + ArrayRef IdxList, bool InBounds = false, Type *OnlyIfReducedTy = nullptr) { return getGetElementPtr( - C, makeArrayRef((Value * const *)IdxList.data(), IdxList.size()), + Ty, C, makeArrayRef((Value * const *)IdxList.data(), IdxList.size()), InBounds, OnlyIfReducedTy); } - static Constant *getGetElementPtr(Constant *C, Constant *Idx, + static Constant *getGetElementPtr(Type *Ty, Constant *C, Constant *Idx, bool InBounds = false, Type *OnlyIfReducedTy = nullptr) { // This form of the function only exists to avoid ambiguous overload // warnings about whether to convert Idx to ArrayRef or // ArrayRef. - return getGetElementPtr(C, cast(Idx), InBounds, OnlyIfReducedTy); + return getGetElementPtr(Ty, C, cast(Idx), InBounds, OnlyIfReducedTy); } - static Constant *getGetElementPtr(Constant *C, ArrayRef IdxList, + static Constant *getGetElementPtr(Type *Ty, Constant *C, + ArrayRef IdxList, bool InBounds = false, Type *OnlyIfReducedTy = nullptr); /// Create an "inbounds" getelementptr. See the documentation for the /// "inbounds" flag in LangRef.html for details. - static Constant *getInBoundsGetElementPtr(Constant *C, + static Constant *getInBoundsGetElementPtr(Type *Ty, Constant *C, ArrayRef IdxList) { - return getGetElementPtr(C, IdxList, true); + return getGetElementPtr(Ty, C, IdxList, true); } - static Constant *getInBoundsGetElementPtr(Constant *C, + static Constant *getInBoundsGetElementPtr(Type *Ty, Constant *C, Constant *Idx) { // This form of the function only exists to avoid ambiguous overload // warnings about whether to convert Idx to ArrayRef or // ArrayRef. - return getGetElementPtr(C, Idx, true); + return getGetElementPtr(Ty, C, Idx, true); } - static Constant *getInBoundsGetElementPtr(Constant *C, + static Constant *getInBoundsGetElementPtr(Type *Ty, Constant *C, ArrayRef IdxList) { - return getGetElementPtr(C, IdxList, true); + return getGetElementPtr(Ty, C, IdxList, true); } static Constant *getExtractElement(Constant *Vec, Constant *Idx, diff --git a/include/llvm/IR/GlobalValue.h b/include/llvm/IR/GlobalValue.h index 002e5e79fd4..3b2a2192d45 100644 --- a/include/llvm/IR/GlobalValue.h +++ b/include/llvm/IR/GlobalValue.h @@ -165,9 +165,9 @@ public: const char *getSection() const; /// Global values are always pointers. - inline PointerType *getType() const { - return cast(User::getType()); - } + PointerType *getType() const { return cast(User::getType()); } + + Type *getValueType() const { return getType()->getElementType(); } static LinkageTypes getLinkOnceLinkage(bool ODR) { return ODR ? LinkOnceODRLinkage : LinkOnceAnyLinkage; @@ -343,11 +343,11 @@ public: virtual void eraseFromParent() = 0; /// Get the module that this global value is contained inside of... - inline Module *getParent() { return Parent; } - inline const Module *getParent() const { return Parent; } + Module *getParent() { return Parent; } + const Module *getParent() const { return Parent; } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return V->getValueID() == Value::FunctionVal || V->getValueID() == Value::GlobalVariableVal || V->getValueID() == Value::GlobalAliasVal; diff --git a/include/llvm/IR/NoFolder.h b/include/llvm/IR/NoFolder.h index ab7bed6b94c..33eed293074 100644 --- a/include/llvm/IR/NoFolder.h +++ b/include/llvm/IR/NoFolder.h @@ -179,13 +179,13 @@ public: Constant *CreateGetElementPtr(Constant *C, ArrayRef IdxList) const { - return ConstantExpr::getGetElementPtr(C, IdxList); + return ConstantExpr::getGetElementPtr(nullptr, C, IdxList); } Constant *CreateGetElementPtr(Constant *C, Constant *Idx) const { // This form of the function only exists to avoid ambiguous overload // warnings about whether to convert Idx to ArrayRef or // ArrayRef. - return ConstantExpr::getGetElementPtr(C, Idx); + return ConstantExpr::getGetElementPtr(nullptr, C, Idx); } Instruction *CreateGetElementPtr(Constant *C, ArrayRef IdxList) const { @@ -194,13 +194,13 @@ public: Constant *CreateInBoundsGetElementPtr(Constant *C, ArrayRef IdxList) const { - return ConstantExpr::getInBoundsGetElementPtr(C, IdxList); + return ConstantExpr::getInBoundsGetElementPtr(nullptr, C, IdxList); } Constant *CreateInBoundsGetElementPtr(Constant *C, Constant *Idx) const { // This form of the function only exists to avoid ambiguous overload // warnings about whether to convert Idx to ArrayRef or // ArrayRef. - return ConstantExpr::getInBoundsGetElementPtr(C, Idx); + return ConstantExpr::getInBoundsGetElementPtr(nullptr, C, Idx); } Instruction *CreateInBoundsGetElementPtr(Constant *C, ArrayRef IdxList) const { diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp index 5bc84f43f9e..a85e8136de5 100644 --- a/lib/Analysis/ConstantFolding.cpp +++ b/lib/Analysis/ConstantFolding.cpp @@ -671,8 +671,8 @@ static Constant *SymbolicallyEvaluateBinop(unsigned Opc, Constant *Op0, /// If array indices are not pointer-sized integers, explicitly cast them so /// that they aren't implicitly casted by the getelementptr. -static Constant *CastGEPIndices(ArrayRef Ops, Type *ResultTy, - const DataLayout &DL, +static Constant *CastGEPIndices(Type *SrcTy, ArrayRef Ops, + Type *ResultTy, const DataLayout &DL, const TargetLibraryInfo *TLI) { Type *IntPtrTy = DL.getIntPtrType(ResultTy); @@ -698,7 +698,7 @@ static Constant *CastGEPIndices(ArrayRef Ops, Type *ResultTy, if (!Any) return nullptr; - Constant *C = ConstantExpr::getGetElementPtr(Ops[0], NewIdxs); + Constant *C = ConstantExpr::getGetElementPtr(SrcTy, Ops[0], NewIdxs); if (ConstantExpr *CE = dyn_cast(C)) { if (Constant *Folded = ConstantFoldConstantExpression(CE, DL, TLI)) C = Folded; @@ -724,7 +724,7 @@ static Constant* StripPtrCastKeepAS(Constant* Ptr) { } /// If we can symbolically evaluate the GEP constant expression, do so. -static Constant *SymbolicallyEvaluateGEP(ArrayRef Ops, +static Constant *SymbolicallyEvaluateGEP(Type *SrcTy, ArrayRef Ops, Type *ResultTy, const DataLayout &DL, const TargetLibraryInfo *TLI) { Constant *Ptr = Ops[0]; @@ -866,7 +866,7 @@ static Constant *SymbolicallyEvaluateGEP(ArrayRef Ops, return nullptr; // Create a GEP. - Constant *C = ConstantExpr::getGetElementPtr(Ptr, NewIdxs); + Constant *C = ConstantExpr::getGetElementPtr(SrcTy, Ptr, NewIdxs); assert(C->getType()->getPointerElementType() == Ty && "Computed GetElementPtr has unexpected type!"); @@ -1086,13 +1086,15 @@ Constant *llvm::ConstantFoldInstOperands(unsigned Opcode, Type *DestTy, return ConstantExpr::getInsertElement(Ops[0], Ops[1], Ops[2]); case Instruction::ShuffleVector: return ConstantExpr::getShuffleVector(Ops[0], Ops[1], Ops[2]); - case Instruction::GetElementPtr: - if (Constant *C = CastGEPIndices(Ops, DestTy, DL, TLI)) + case Instruction::GetElementPtr: { + Type *SrcTy = nullptr; + if (Constant *C = CastGEPIndices(SrcTy, Ops, DestTy, DL, TLI)) return C; - if (Constant *C = SymbolicallyEvaluateGEP(Ops, DestTy, DL, TLI)) + if (Constant *C = SymbolicallyEvaluateGEP(SrcTy, Ops, DestTy, DL, TLI)) return C; - return ConstantExpr::getGetElementPtr(Ops[0], Ops.slice(1)); + return ConstantExpr::getGetElementPtr(SrcTy, Ops[0], Ops.slice(1)); + } } } diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp index e88232368fd..d45f7bd66ff 100644 --- a/lib/Analysis/InstructionSimplify.cpp +++ b/lib/Analysis/InstructionSimplify.cpp @@ -2978,10 +2978,12 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS, // what constant folding can make out of it. Constant *Null = Constant::getNullValue(GLHS->getPointerOperandType()); SmallVector IndicesLHS(GLHS->idx_begin(), GLHS->idx_end()); - Constant *NewLHS = ConstantExpr::getGetElementPtr(Null, IndicesLHS); + Constant *NewLHS = ConstantExpr::getGetElementPtr( + GLHS->getSourceElementType(), Null, IndicesLHS); SmallVector IndicesRHS(GRHS->idx_begin(), GRHS->idx_end()); - Constant *NewRHS = ConstantExpr::getGetElementPtr(Null, IndicesRHS); + Constant *NewRHS = ConstantExpr::getGetElementPtr( + GLHS->getSourceElementType(), Null, IndicesRHS); return ConstantExpr::getICmp(Pred, NewLHS, NewRHS); } } @@ -3241,18 +3243,18 @@ Value *llvm::SimplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal, /// SimplifyGEPInst - Given operands for an GetElementPtrInst, see if we can /// fold the result. If not, this returns null. -static Value *SimplifyGEPInst(ArrayRef Ops, const Query &Q, unsigned) { +static Value *SimplifyGEPInst(Type *SrcTy, ArrayRef Ops, + const Query &Q, unsigned) { // The type of the GEP pointer operand. - PointerType *PtrTy = cast(Ops[0]->getType()->getScalarType()); - unsigned AS = PtrTy->getAddressSpace(); + unsigned AS = + cast(Ops[0]->getType()->getScalarType())->getAddressSpace(); // getelementptr P -> P. if (Ops.size() == 1) return Ops[0]; // Compute the (pointer) type returned by the GEP instruction. - Type *LastType = - GetElementPtrInst::getIndexedType(PtrTy->getElementType(), Ops.slice(1)); + Type *LastType = GetElementPtrInst::getIndexedType(SrcTy, Ops.slice(1)); Type *GEPTy = PointerType::get(LastType, AS); if (VectorType *VT = dyn_cast(Ops[0]->getType())) GEPTy = VectorType::get(GEPTy, VT->getNumElements()); @@ -3265,7 +3267,7 @@ static Value *SimplifyGEPInst(ArrayRef Ops, const Query &Q, unsigned) { if (match(Ops[1], m_Zero())) return Ops[0]; - Type *Ty = PtrTy->getElementType(); + Type *Ty = SrcTy; if (Ty->isSized()) { Value *P; uint64_t C; @@ -3319,14 +3321,17 @@ static Value *SimplifyGEPInst(ArrayRef Ops, const Query &Q, unsigned) { if (!isa(Ops[i])) return nullptr; - return ConstantExpr::getGetElementPtr(cast(Ops[0]), Ops.slice(1)); + return ConstantExpr::getGetElementPtr(SrcTy, cast(Ops[0]), + Ops.slice(1)); } Value *llvm::SimplifyGEPInst(ArrayRef Ops, const DataLayout &DL, const TargetLibraryInfo *TLI, const DominatorTree *DT, AssumptionCache *AC, const Instruction *CxtI) { - return ::SimplifyGEPInst(Ops, Query(DL, TLI, DT, AC, CxtI), RecursionLimit); + return ::SimplifyGEPInst( + cast(Ops[0]->getType()->getScalarType())->getElementType(), + Ops, Query(DL, TLI, DT, AC, CxtI), RecursionLimit); } /// SimplifyInsertValueInst - Given operands for an InsertValueInst, see if we diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp index 97332b7129b..37377f0b859 100644 --- a/lib/Analysis/ScalarEvolution.cpp +++ b/lib/Analysis/ScalarEvolution.cpp @@ -5690,7 +5690,7 @@ static Constant *BuildConstantFromSCEV(const SCEV *V) { if (PTy->getElementType()->isStructTy()) C2 = ConstantExpr::getIntegerCast( C2, Type::getInt32Ty(C->getContext()), true); - C = ConstantExpr::getGetElementPtr(C, C2); + C = ConstantExpr::getGetElementPtr(PTy->getElementType(), C, C2); } else C = ConstantExpr::getAdd(C, C2); } diff --git a/lib/Analysis/ScalarEvolutionExpander.cpp b/lib/Analysis/ScalarEvolutionExpander.cpp index a73ec9ecc02..1bdddebf9c9 100644 --- a/lib/Analysis/ScalarEvolutionExpander.cpp +++ b/lib/Analysis/ScalarEvolutionExpander.cpp @@ -488,7 +488,8 @@ Value *SCEVExpander::expandAddToGEP(const SCEV *const *op_begin, // Fold a GEP with constant operands. if (Constant *CLHS = dyn_cast(V)) if (Constant *CRHS = dyn_cast(Idx)) - return ConstantExpr::getGetElementPtr(CLHS, CRHS); + return ConstantExpr::getGetElementPtr(Type::getInt8Ty(Ty->getContext()), + CLHS, CRHS); // Do a quick scan to see if we have this GEP nearby. If so, reuse it. unsigned ScanLimit = 6; diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index ed1d0ff9ee6..d735063d5dc 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -2831,13 +2831,10 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { !BasePointerType->getElementType()->isSized(&Visited)) return Error(ID.Loc, "base element of getelementptr must be sized"); - if (!GetElementPtrInst::getIndexedType( - cast(Elts[0]->getType()->getScalarType()) - ->getElementType(), - Indices)) + if (!GetElementPtrInst::getIndexedType(Ty, Indices)) return Error(ID.Loc, "invalid getelementptr indices"); - ID.ConstantVal = ConstantExpr::getGetElementPtr(Elts[0], Indices, - InBounds); + ID.ConstantVal = + ConstantExpr::getGetElementPtr(Ty, Elts[0], Indices, InBounds); } else if (Opc == Instruction::Select) { if (Elts.size() != 3) return Error(ID.Loc, "expected three operands to select"); diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 09e3e75f99d..5771043e189 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -2313,14 +2313,17 @@ std::error_code BitcodeReader::ParseConstants() { Elts.push_back(ValueList.getConstantFwdRef(Record[OpNum++], ElTy)); } - ArrayRef Indices(Elts.begin() + 1, Elts.end()); - V = ConstantExpr::getGetElementPtr(Elts[0], Indices, - BitCode == - bitc::CST_CODE_CE_INBOUNDS_GEP); if (PointeeType && - PointeeType != cast(V)->getSourceElementType()) + PointeeType != + cast(Elts[0]->getType()->getScalarType()) + ->getElementType()) return Error("Explicit gep operator type does not match pointee type " "of pointer operand"); + + ArrayRef Indices(Elts.begin() + 1, Elts.end()); + V = ConstantExpr::getGetElementPtr(PointeeType, Elts[0], Indices, + BitCode == + bitc::CST_CODE_CE_INBOUNDS_GEP); break; } case bitc::CST_CODE_CE_SELECT: { // CE_SELECT: [opval#, opval#, opval#] diff --git a/lib/CodeGen/GlobalMerge.cpp b/lib/CodeGen/GlobalMerge.cpp index 32543b7723a..41953839010 100644 --- a/lib/CodeGen/GlobalMerge.cpp +++ b/lib/CodeGen/GlobalMerge.cpp @@ -222,7 +222,8 @@ bool GlobalMerge::doMerge(SmallVectorImpl &Globals, ConstantInt::get(Int32Ty, 0), ConstantInt::get(Int32Ty, k-i) }; - Constant *GEP = ConstantExpr::getInBoundsGetElementPtr(MergedGV, Idx); + Constant *GEP = + ConstantExpr::getInBoundsGetElementPtr(MergedTy, MergedGV, Idx); Globals[k]->replaceAllUsesWith(GEP); Globals[k]->eraseFromParent(); diff --git a/lib/CodeGen/ShadowStackGCLowering.cpp b/lib/CodeGen/ShadowStackGCLowering.cpp index 815a0a76c16..7c0b2bb4569 100644 --- a/lib/CodeGen/ShadowStackGCLowering.cpp +++ b/lib/CodeGen/ShadowStackGCLowering.cpp @@ -239,7 +239,7 @@ Constant *ShadowStackGCLowering::GetFrameMap(Function &F) { Constant *GEPIndices[2] = { ConstantInt::get(Type::getInt32Ty(F.getContext()), 0), ConstantInt::get(Type::getInt32Ty(F.getContext()), 0)}; - return ConstantExpr::getGetElementPtr(GV, GEPIndices); + return ConstantExpr::getGetElementPtr(FrameMap->getType(), GV, GEPIndices); } Type *ShadowStackGCLowering::GetConcreteStackEntryType(Function &F) { diff --git a/lib/IR/ConstantFold.cpp b/lib/IR/ConstantFold.cpp index 94a39441a13..d3caf04489d 100644 --- a/lib/IR/ConstantFold.cpp +++ b/lib/IR/ConstantFold.cpp @@ -132,7 +132,8 @@ static Constant *FoldBitCast(Constant *V, Type *DestTy) { if (ElTy == DPTy->getElementType()) // This GEP is inbounds because all indices are zero. - return ConstantExpr::getInBoundsGetElementPtr(V, IdxList); + return ConstantExpr::getInBoundsGetElementPtr(PTy->getElementType(), + V, IdxList); } // Handle casts from one vector constant to another. We know that the src @@ -2120,10 +2121,9 @@ static Constant *ConstantFoldGetElementPtrImpl(Constant *C, NewIndices.push_back(Combined); NewIndices.append(Idxs.begin() + 1, Idxs.end()); - return - ConstantExpr::getGetElementPtr(CE->getOperand(0), NewIndices, - inBounds && - cast(CE)->isInBounds()); + return ConstantExpr::getGetElementPtr( + cast(CE)->getSourceElementType(), CE->getOperand(0), + NewIndices, inBounds && cast(CE)->isInBounds()); } } @@ -2148,8 +2148,8 @@ static Constant *ConstantFoldGetElementPtrImpl(Constant *C, if (SrcArrayTy && DstArrayTy && SrcArrayTy->getElementType() == DstArrayTy->getElementType() && SrcPtrTy->getAddressSpace() == DstPtrTy->getAddressSpace()) - return ConstantExpr::getGetElementPtr((Constant*)CE->getOperand(0), - Idxs, inBounds); + return ConstantExpr::getGetElementPtr( + SrcArrayTy, (Constant *)CE->getOperand(0), Idxs, inBounds); } } } @@ -2215,7 +2215,7 @@ static Constant *ConstantFoldGetElementPtrImpl(Constant *C, if (!NewIdxs.empty()) { for (unsigned i = 0, e = Idxs.size(); i != e; ++i) if (!NewIdxs[i]) NewIdxs[i] = cast(Idxs[i]); - return ConstantExpr::getGetElementPtr(C, NewIdxs, inBounds); + return ConstantExpr::getGetElementPtr(nullptr, C, NewIdxs, inBounds); } // If all indices are known integers and normalized, we can do a simple @@ -2223,7 +2223,7 @@ static Constant *ConstantFoldGetElementPtrImpl(Constant *C, if (!Unknown && !inBounds) if (auto *GV = dyn_cast(C)) if (!GV->hasExternalWeakLinkage() && isInBoundsIndices(Idxs)) - return ConstantExpr::getInBoundsGetElementPtr(C, Idxs); + return ConstantExpr::getInBoundsGetElementPtr(nullptr, C, Idxs); return nullptr; } diff --git a/lib/IR/Constants.cpp b/lib/IR/Constants.cpp index 8c6eda2a772..3f8d1f1ca6a 100644 --- a/lib/IR/Constants.cpp +++ b/lib/IR/Constants.cpp @@ -1252,7 +1252,7 @@ Constant *ConstantExpr::getWithOperands(ArrayRef Ops, Type *Ty, return ConstantExpr::getShuffleVector(Ops[0], Ops[1], Ops[2], OnlyIfReducedTy); case Instruction::GetElementPtr: - return ConstantExpr::getGetElementPtr(Ops[0], Ops.slice(1), + return ConstantExpr::getGetElementPtr(nullptr, Ops[0], Ops.slice(1), cast(this)->isInBounds(), OnlyIfReducedTy); case Instruction::ICmp: @@ -1925,7 +1925,7 @@ Constant *ConstantExpr::getSizeOf(Type* Ty) { // Note that a non-inbounds gep is used, as null isn't within any object. Constant *GEPIdx = ConstantInt::get(Type::getInt32Ty(Ty->getContext()), 1); Constant *GEP = getGetElementPtr( - Constant::getNullValue(PointerType::getUnqual(Ty)), GEPIdx); + Ty, Constant::getNullValue(PointerType::getUnqual(Ty)), GEPIdx); return getPtrToInt(GEP, Type::getInt64Ty(Ty->getContext())); } @@ -1939,7 +1939,7 @@ Constant *ConstantExpr::getAlignOf(Type* Ty) { Constant *Zero = ConstantInt::get(Type::getInt64Ty(Ty->getContext()), 0); Constant *One = ConstantInt::get(Type::getInt32Ty(Ty->getContext()), 1); Constant *Indices[2] = { Zero, One }; - Constant *GEP = getGetElementPtr(NullPtr, Indices); + Constant *GEP = getGetElementPtr(AligningTy, NullPtr, Indices); return getPtrToInt(GEP, Type::getInt64Ty(Ty->getContext())); } @@ -1957,7 +1957,7 @@ Constant *ConstantExpr::getOffsetOf(Type* Ty, Constant *FieldNo) { FieldNo }; Constant *GEP = getGetElementPtr( - Constant::getNullValue(PointerType::getUnqual(Ty)), GEPIdx); + Ty, Constant::getNullValue(PointerType::getUnqual(Ty)), GEPIdx); return getPtrToInt(GEP, Type::getInt64Ty(Ty->getContext())); } @@ -2001,20 +2001,22 @@ Constant *ConstantExpr::getSelect(Constant *C, Constant *V1, Constant *V2, return pImpl->ExprConstants.getOrCreate(V1->getType(), Key); } -Constant *ConstantExpr::getGetElementPtr(Constant *C, ArrayRef Idxs, - bool InBounds, Type *OnlyIfReducedTy) { - assert(C->getType()->isPtrOrPtrVectorTy() && - "Non-pointer type for constant GetElementPtr expression"); - +Constant *ConstantExpr::getGetElementPtr(Type *Ty, Constant *C, + ArrayRef Idxs, bool InBounds, + Type *OnlyIfReducedTy) { if (Constant *FC = ConstantFoldGetElementPtr(C, InBounds, Idxs)) return FC; // Fold a few common cases. + if (!Ty) + Ty = cast(C->getType()->getScalarType())->getElementType(); + else + assert(Ty == + cast(C->getType()->getScalarType())->getElementType()); // Get the result type of the getelementptr! - Type *Ty = GetElementPtrInst::getIndexedType( - cast(C->getType()->getScalarType())->getElementType(), Idxs); - assert(Ty && "GEP indices invalid!"); + Type *DestTy = GetElementPtrInst::getIndexedType(Ty, Idxs); + assert(DestTy && "GEP indices invalid!"); unsigned AS = C->getType()->getPointerAddressSpace(); - Type *ReqTy = Ty->getPointerTo(AS); + Type *ReqTy = DestTy->getPointerTo(AS); if (VectorType *VecTy = dyn_cast(C->getType())) ReqTy = VectorType::get(ReqTy, VecTy->getNumElements()); diff --git a/lib/IR/Core.cpp b/lib/IR/Core.cpp index fcb1aa54914..caaf13f7932 100644 --- a/lib/IR/Core.cpp +++ b/lib/IR/Core.cpp @@ -1153,8 +1153,8 @@ LLVMValueRef LLVMConstGEP(LLVMValueRef ConstantVal, LLVMValueRef *ConstantIndices, unsigned NumIndices) { ArrayRef IdxList(unwrap(ConstantIndices, NumIndices), NumIndices); - return wrap(ConstantExpr::getGetElementPtr(unwrap(ConstantVal), - IdxList)); + return wrap(ConstantExpr::getGetElementPtr( + nullptr, unwrap(ConstantVal), IdxList)); } LLVMValueRef LLVMConstInBoundsGEP(LLVMValueRef ConstantVal, @@ -1163,7 +1163,7 @@ LLVMValueRef LLVMConstInBoundsGEP(LLVMValueRef ConstantVal, Constant* Val = unwrap(ConstantVal); ArrayRef IdxList(unwrap(ConstantIndices, NumIndices), NumIndices); - return wrap(ConstantExpr::getInBoundsGetElementPtr(Val, IdxList)); + return wrap(ConstantExpr::getInBoundsGetElementPtr(nullptr, Val, IdxList)); } LLVMValueRef LLVMConstTrunc(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { diff --git a/lib/Target/NVPTX/NVPTXFavorNonGenericAddrSpaces.cpp b/lib/Target/NVPTX/NVPTXFavorNonGenericAddrSpaces.cpp index 6d7c99c6f3f..ae63caec132 100644 --- a/lib/Target/NVPTX/NVPTXFavorNonGenericAddrSpaces.cpp +++ b/lib/Target/NVPTX/NVPTXFavorNonGenericAddrSpaces.cpp @@ -132,9 +132,8 @@ bool NVPTXFavorNonGenericAddrSpaces::hoistAddrSpaceCastFromGEP( } else { // GEP is a constant expression. Constant *NewGEPCE = ConstantExpr::getGetElementPtr( - cast(Cast->getOperand(0)), - Indices, - GEP->isInBounds()); + GEP->getSourceElementType(), cast(Cast->getOperand(0)), + Indices, GEP->isInBounds()); GEP->replaceAllUsesWith( ConstantExpr::getAddrSpaceCast(NewGEPCE, GEP->getType())); } diff --git a/lib/Target/XCore/XCoreISelLowering.cpp b/lib/Target/XCore/XCoreISelLowering.cpp index 6e8a95a0859..c8cc9f35657 100644 --- a/lib/Target/XCore/XCoreISelLowering.cpp +++ b/lib/Target/XCore/XCoreISelLowering.cpp @@ -308,7 +308,8 @@ LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const Constant *GA = ConstantExpr::getBitCast(const_cast(GV), Ty); Ty = Type::getInt32Ty(*DAG.getContext()); Constant *Idx = ConstantInt::get(Ty, Offset); - Constant *GAI = ConstantExpr::getGetElementPtr(GA, Idx); + Constant *GAI = ConstantExpr::getGetElementPtr( + Type::getInt8Ty(*DAG.getContext()), GA, Idx); SDValue CP = DAG.getConstantPool(GAI, MVT::i32); return DAG.getLoad(getPointerTy(), DL, DAG.getEntryNode(), CP, MachinePointerInfo(), false, false, false, 0); diff --git a/lib/Transforms/IPO/GlobalOpt.cpp b/lib/Transforms/IPO/GlobalOpt.cpp index 20b41fb1ea4..b8c4f5da39e 100644 --- a/lib/Transforms/IPO/GlobalOpt.cpp +++ b/lib/Transforms/IPO/GlobalOpt.cpp @@ -564,6 +564,7 @@ static GlobalVariable *SRAGlobal(GlobalVariable *GV, const DataLayout &DL) { if (Val >= NewGlobals.size()) Val = 0; // Out of bound array access. Value *NewPtr = NewGlobals[Val]; + Type *NewTy = NewGlobals[Val]->getType(); // Form a shorter GEP if needed. if (GEP->getNumOperands() > 3) { @@ -572,7 +573,9 @@ static GlobalVariable *SRAGlobal(GlobalVariable *GV, const DataLayout &DL) { Idxs.push_back(NullInt); for (unsigned i = 3, e = CE->getNumOperands(); i != e; ++i) Idxs.push_back(CE->getOperand(i)); - NewPtr = ConstantExpr::getGetElementPtr(cast(NewPtr), Idxs); + NewPtr = + ConstantExpr::getGetElementPtr(NewTy, cast(NewPtr), Idxs); + NewTy = GetElementPtrInst::getIndexedType(NewTy, Idxs); } else { GetElementPtrInst *GEPI = cast(GEP); SmallVector Idxs; @@ -721,8 +724,8 @@ static bool OptimizeAwayTrappingUsesOfValue(Value *V, Constant *NewV) { else break; if (Idxs.size() == GEPI->getNumOperands()-1) - Changed |= OptimizeAwayTrappingUsesOfValue(GEPI, - ConstantExpr::getGetElementPtr(NewV, Idxs)); + Changed |= OptimizeAwayTrappingUsesOfValue( + GEPI, ConstantExpr::getGetElementPtr(nullptr, NewV, Idxs)); if (GEPI->use_empty()) { Changed = true; GEPI->eraseFromParent(); @@ -2338,7 +2341,7 @@ bool Evaluator::EvaluateBlock(BasicBlock::iterator CurInst, Constant *IdxZero = ConstantInt::get(IdxTy, 0, false); Constant * const IdxList[] = {IdxZero, IdxZero}; - Ptr = ConstantExpr::getGetElementPtr(Ptr, IdxList); + Ptr = ConstantExpr::getGetElementPtr(nullptr, Ptr, IdxList); if (ConstantExpr *CE = dyn_cast(Ptr)) Ptr = ConstantFoldConstantExpression(CE, DL, TLI); @@ -2402,8 +2405,8 @@ bool Evaluator::EvaluateBlock(BasicBlock::iterator CurInst, i != e; ++i) GEPOps.push_back(getVal(*i)); InstResult = - ConstantExpr::getGetElementPtr(P, GEPOps, - cast(GEP)->isInBounds()); + ConstantExpr::getGetElementPtr(GEP->getSourceElementType(), P, GEPOps, + cast(GEP)->isInBounds()); DEBUG(dbgs() << "Found a GEP! Simplifying: " << *InstResult << "\n"); } else if (LoadInst *LI = dyn_cast(CurInst)) { diff --git a/lib/Transforms/IPO/LowerBitSets.cpp b/lib/Transforms/IPO/LowerBitSets.cpp index fe00d92f70b..fae75a8ac41 100644 --- a/lib/Transforms/IPO/LowerBitSets.cpp +++ b/lib/Transforms/IPO/LowerBitSets.cpp @@ -349,7 +349,8 @@ void LowerBitSets::allocateByteArrays() { Constant *Idxs[] = {ConstantInt::get(IntPtrTy, 0), ConstantInt::get(IntPtrTy, ByteArrayOffsets[I])}; - Constant *GEP = ConstantExpr::getInBoundsGetElementPtr(ByteArray, Idxs); + Constant *GEP = ConstantExpr::getInBoundsGetElementPtr( + ByteArrayConst->getType(), ByteArray, Idxs); // Create an alias instead of RAUW'ing the gep directly. On x86 this ensures // that the pc-relative displacement is folded into the lea instead of the @@ -546,8 +547,8 @@ void LowerBitSets::buildBitSetsFromGlobals( // Multiply by 2 to account for padding elements. Constant *CombinedGlobalIdxs[] = {ConstantInt::get(Int32Ty, 0), ConstantInt::get(Int32Ty, I * 2)}; - Constant *CombinedGlobalElemPtr = - ConstantExpr::getGetElementPtr(CombinedGlobal, CombinedGlobalIdxs); + Constant *CombinedGlobalElemPtr = ConstantExpr::getGetElementPtr( + NewInit->getType(), CombinedGlobal, CombinedGlobalIdxs); if (LinkerSubsectionsViaSymbols) { Globals[I]->replaceAllUsesWith(CombinedGlobalElemPtr); } else { diff --git a/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/lib/Transforms/Instrumentation/AddressSanitizer.cpp index f29fd050806..e483d6f9e3b 100644 --- a/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -1326,7 +1326,7 @@ bool AddressSanitizerModule::InstrumentGlobals(IRBuilder<> &IRB, Module &M) { Indices2[1] = IRB.getInt32(0); G->replaceAllUsesWith( - ConstantExpr::getGetElementPtr(NewGlobal, Indices2, true)); + ConstantExpr::getGetElementPtr(NewTy, NewGlobal, Indices2, true)); NewGlobal->takeName(G); G->eraseFromParent(); diff --git a/lib/Transforms/Scalar/GVN.cpp b/lib/Transforms/Scalar/GVN.cpp index c73e60f95bd..97d5b6d59fa 100644 --- a/lib/Transforms/Scalar/GVN.cpp +++ b/lib/Transforms/Scalar/GVN.cpp @@ -1102,7 +1102,8 @@ static int AnalyzeLoadFromClobberingMemInst(Type *LoadTy, Value *LoadPtr, Type::getInt8PtrTy(Src->getContext(), AS)); Constant *OffsetCst = ConstantInt::get(Type::getInt64Ty(Src->getContext()), (unsigned)Offset); - Src = ConstantExpr::getGetElementPtr(Src, OffsetCst); + Src = ConstantExpr::getGetElementPtr(Type::getInt8Ty(Src->getContext()), Src, + OffsetCst); Src = ConstantExpr::getBitCast(Src, PointerType::get(LoadTy, AS)); if (ConstantFoldLoadFromConstPtr(Src, DL)) return Offset; @@ -1263,7 +1264,8 @@ static Value *GetMemInstValueForLoad(MemIntrinsic *SrcInst, unsigned Offset, Type::getInt8PtrTy(Src->getContext(), AS)); Constant *OffsetCst = ConstantInt::get(Type::getInt64Ty(Src->getContext()), (unsigned)Offset); - Src = ConstantExpr::getGetElementPtr(Src, OffsetCst); + Src = ConstantExpr::getGetElementPtr(Type::getInt8Ty(Src->getContext()), Src, + OffsetCst); Src = ConstantExpr::getBitCast(Src, PointerType::get(LoadTy, AS)); return ConstantFoldLoadFromConstPtr(Src, DL); } diff --git a/lib/Transforms/Scalar/SCCP.cpp b/lib/Transforms/Scalar/SCCP.cpp index 875a0078741..bc068f78c57 100644 --- a/lib/Transforms/Scalar/SCCP.cpp +++ b/lib/Transforms/Scalar/SCCP.cpp @@ -1012,7 +1012,8 @@ void SCCPSolver::visitGetElementPtrInst(GetElementPtrInst &I) { Constant *Ptr = Operands[0]; auto Indices = makeArrayRef(Operands.begin() + 1, Operands.end()); - markConstant(&I, ConstantExpr::getGetElementPtr(Ptr, Indices)); + markConstant(&I, ConstantExpr::getGetElementPtr(I.getSourceElementType(), Ptr, + Indices)); } void SCCPSolver::visitStoreInst(StoreInst &SI) { diff --git a/tools/bugpoint/Miscompilation.cpp b/tools/bugpoint/Miscompilation.cpp index 98061bd585a..53631d25c39 100644 --- a/tools/bugpoint/Miscompilation.cpp +++ b/tools/bugpoint/Miscompilation.cpp @@ -852,7 +852,8 @@ static void CleanupAndPrepareModules(BugDriver &BD, Module *&Test, // GetElementPtr *funcName, ulong 0, ulong 0 std::vector GEPargs(2, Constant::getNullValue(Type::getInt32Ty(F->getContext()))); - Value *GEP = ConstantExpr::getGetElementPtr(funcName, GEPargs); + Value *GEP = ConstantExpr::getGetElementPtr(InitArray->getType(), + funcName, GEPargs); std::vector ResolverArgs; ResolverArgs.push_back(GEP); diff --git a/unittests/IR/ConstantsTest.cpp b/unittests/IR/ConstantsTest.cpp index 0e040bc9f46..0c7777d7678 100644 --- a/unittests/IR/ConstantsTest.cpp +++ b/unittests/IR/ConstantsTest.cpp @@ -249,7 +249,8 @@ TEST(ConstantsTest, AsInstructionsTest) { // not a normal one! //CHECK(ConstantExpr::getGetElementPtr(Global, V, false), // "getelementptr i32*, i32** @dummy, i32 1"); - CHECK(ConstantExpr::getInBoundsGetElementPtr(Global, V), + CHECK(ConstantExpr::getInBoundsGetElementPtr(PointerType::getUnqual(Int32Ty), + Global, V), "getelementptr inbounds i32*, i32** @dummy, i32 1"); CHECK(ConstantExpr::getExtractElement(P6, One), "extractelement <2 x i16> " @@ -266,7 +267,8 @@ TEST(ConstantsTest, ReplaceWithConstantTest) { Constant *Global = M->getOrInsertGlobal("dummy", PointerType::getUnqual(Int32Ty)); - Constant *GEP = ConstantExpr::getGetElementPtr(Global, One); + Constant *GEP = ConstantExpr::getGetElementPtr( + PointerType::getUnqual(Int32Ty), Global, One); EXPECT_DEATH(Global->replaceAllUsesWith(GEP), "this->replaceAllUsesWith\\(expr\\(this\\)\\) is NOT valid!"); } @@ -333,7 +335,7 @@ TEST(ConstantsTest, GEPReplaceWithConstant) { auto *C1 = ConstantInt::get(IntTy, 1); auto *Placeholder = new GlobalVariable( *M, IntTy, false, GlobalValue::ExternalWeakLinkage, nullptr); - auto *GEP = ConstantExpr::getGetElementPtr(Placeholder, C1); + auto *GEP = ConstantExpr::getGetElementPtr(IntTy, Placeholder, C1); ASSERT_EQ(GEP->getOperand(0), Placeholder); auto *Ref = -- 2.34.1