[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
This commit is contained in:
David Blaikie 2015-04-02 18:55:32 +00:00
parent fa8f2103a5
commit 19443c1bcb
25 changed files with 136 additions and 113 deletions

View File

@ -132,32 +132,32 @@ public:
Constant *CreateGetElementPtr(Constant *C, Constant *CreateGetElementPtr(Constant *C,
ArrayRef<Constant *> IdxList) const { ArrayRef<Constant *> IdxList) const {
return Fold(ConstantExpr::getGetElementPtr(C, IdxList)); return Fold(ConstantExpr::getGetElementPtr(nullptr, C, IdxList));
} }
Constant *CreateGetElementPtr(Constant *C, Constant *Idx) const { Constant *CreateGetElementPtr(Constant *C, Constant *Idx) const {
// This form of the function only exists to avoid ambiguous overload // This form of the function only exists to avoid ambiguous overload
// warnings about whether to convert Idx to ArrayRef<Constant *> or // warnings about whether to convert Idx to ArrayRef<Constant *> or
// ArrayRef<Value *>. // ArrayRef<Value *>.
return Fold(ConstantExpr::getGetElementPtr(C, Idx)); return Fold(ConstantExpr::getGetElementPtr(nullptr, C, Idx));
} }
Constant *CreateGetElementPtr(Constant *C, Constant *CreateGetElementPtr(Constant *C,
ArrayRef<Value *> IdxList) const { ArrayRef<Value *> IdxList) const {
return Fold(ConstantExpr::getGetElementPtr(C, IdxList)); return Fold(ConstantExpr::getGetElementPtr(nullptr, C, IdxList));
} }
Constant *CreateInBoundsGetElementPtr(Constant *C, Constant *CreateInBoundsGetElementPtr(Constant *C,
ArrayRef<Constant *> IdxList) const { ArrayRef<Constant *> IdxList) const {
return Fold(ConstantExpr::getInBoundsGetElementPtr(C, IdxList)); return Fold(ConstantExpr::getInBoundsGetElementPtr(nullptr, C, IdxList));
} }
Constant *CreateInBoundsGetElementPtr(Constant *C, Constant *Idx) const { Constant *CreateInBoundsGetElementPtr(Constant *C, Constant *Idx) const {
// This form of the function only exists to avoid ambiguous overload // This form of the function only exists to avoid ambiguous overload
// warnings about whether to convert Idx to ArrayRef<Constant *> or // warnings about whether to convert Idx to ArrayRef<Constant *> or
// ArrayRef<Value *>. // ArrayRef<Value *>.
return Fold(ConstantExpr::getInBoundsGetElementPtr(C, Idx)); return Fold(ConstantExpr::getInBoundsGetElementPtr(nullptr, C, Idx));
} }
Constant *CreateInBoundsGetElementPtr(Constant *C, Constant *CreateInBoundsGetElementPtr(Constant *C,
ArrayRef<Value *> IdxList) const { ArrayRef<Value *> IdxList) const {
return Fold(ConstantExpr::getInBoundsGetElementPtr(C, IdxList)); return Fold(ConstantExpr::getInBoundsGetElementPtr(nullptr, C, IdxList));
} }
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//

View File

@ -120,32 +120,32 @@ public:
Constant *CreateGetElementPtr(Constant *C, Constant *CreateGetElementPtr(Constant *C,
ArrayRef<Constant *> IdxList) const { ArrayRef<Constant *> IdxList) const {
return ConstantExpr::getGetElementPtr(C, IdxList); return ConstantExpr::getGetElementPtr(nullptr, C, IdxList);
} }
Constant *CreateGetElementPtr(Constant *C, Constant *Idx) const { Constant *CreateGetElementPtr(Constant *C, Constant *Idx) const {
// This form of the function only exists to avoid ambiguous overload // This form of the function only exists to avoid ambiguous overload
// warnings about whether to convert Idx to ArrayRef<Constant *> or // warnings about whether to convert Idx to ArrayRef<Constant *> or
// ArrayRef<Value *>. // ArrayRef<Value *>.
return ConstantExpr::getGetElementPtr(C, Idx); return ConstantExpr::getGetElementPtr(nullptr, C, Idx);
} }
Constant *CreateGetElementPtr(Constant *C, Constant *CreateGetElementPtr(Constant *C,
ArrayRef<Value *> IdxList) const { ArrayRef<Value *> IdxList) const {
return ConstantExpr::getGetElementPtr(C, IdxList); return ConstantExpr::getGetElementPtr(nullptr, C, IdxList);
} }
Constant *CreateInBoundsGetElementPtr(Constant *C, Constant *CreateInBoundsGetElementPtr(Constant *C,
ArrayRef<Constant *> IdxList) const { ArrayRef<Constant *> IdxList) const {
return ConstantExpr::getInBoundsGetElementPtr(C, IdxList); return ConstantExpr::getInBoundsGetElementPtr(nullptr, C, IdxList);
} }
Constant *CreateInBoundsGetElementPtr(Constant *C, Constant *Idx) const { Constant *CreateInBoundsGetElementPtr(Constant *C, Constant *Idx) const {
// This form of the function only exists to avoid ambiguous overload // This form of the function only exists to avoid ambiguous overload
// warnings about whether to convert Idx to ArrayRef<Constant *> or // warnings about whether to convert Idx to ArrayRef<Constant *> or
// ArrayRef<Value *>. // ArrayRef<Value *>.
return ConstantExpr::getInBoundsGetElementPtr(C, Idx); return ConstantExpr::getInBoundsGetElementPtr(nullptr, C, Idx);
} }
Constant *CreateInBoundsGetElementPtr(Constant *C, Constant *CreateInBoundsGetElementPtr(Constant *C,
ArrayRef<Value *> IdxList) const { ArrayRef<Value *> IdxList) const {
return ConstantExpr::getInBoundsGetElementPtr(C, IdxList); return ConstantExpr::getInBoundsGetElementPtr(nullptr, C, IdxList);
} }
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//

View File

@ -1057,41 +1057,43 @@ public:
/// all elements must be Constant's. /// all elements must be Constant's.
/// ///
/// \param OnlyIfReducedTy see \a getWithOperands() docs. /// \param OnlyIfReducedTy see \a getWithOperands() docs.
static Constant *getGetElementPtr(Constant *C, ArrayRef<Constant *> IdxList, static Constant *getGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Constant *> IdxList,
bool InBounds = false, bool InBounds = false,
Type *OnlyIfReducedTy = nullptr) { Type *OnlyIfReducedTy = nullptr) {
return getGetElementPtr( return getGetElementPtr(
C, makeArrayRef((Value * const *)IdxList.data(), IdxList.size()), Ty, C, makeArrayRef((Value * const *)IdxList.data(), IdxList.size()),
InBounds, OnlyIfReducedTy); InBounds, OnlyIfReducedTy);
} }
static Constant *getGetElementPtr(Constant *C, Constant *Idx, static Constant *getGetElementPtr(Type *Ty, Constant *C, Constant *Idx,
bool InBounds = false, bool InBounds = false,
Type *OnlyIfReducedTy = nullptr) { Type *OnlyIfReducedTy = nullptr) {
// This form of the function only exists to avoid ambiguous overload // This form of the function only exists to avoid ambiguous overload
// warnings about whether to convert Idx to ArrayRef<Constant *> or // warnings about whether to convert Idx to ArrayRef<Constant *> or
// ArrayRef<Value *>. // ArrayRef<Value *>.
return getGetElementPtr(C, cast<Value>(Idx), InBounds, OnlyIfReducedTy); return getGetElementPtr(Ty, C, cast<Value>(Idx), InBounds, OnlyIfReducedTy);
} }
static Constant *getGetElementPtr(Constant *C, ArrayRef<Value *> IdxList, static Constant *getGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Value *> IdxList,
bool InBounds = false, bool InBounds = false,
Type *OnlyIfReducedTy = nullptr); Type *OnlyIfReducedTy = nullptr);
/// Create an "inbounds" getelementptr. See the documentation for the /// Create an "inbounds" getelementptr. See the documentation for the
/// "inbounds" flag in LangRef.html for details. /// "inbounds" flag in LangRef.html for details.
static Constant *getInBoundsGetElementPtr(Constant *C, static Constant *getInBoundsGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Constant *> IdxList) { ArrayRef<Constant *> 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) { Constant *Idx) {
// This form of the function only exists to avoid ambiguous overload // This form of the function only exists to avoid ambiguous overload
// warnings about whether to convert Idx to ArrayRef<Constant *> or // warnings about whether to convert Idx to ArrayRef<Constant *> or
// ArrayRef<Value *>. // ArrayRef<Value *>.
return getGetElementPtr(C, Idx, true); return getGetElementPtr(Ty, C, Idx, true);
} }
static Constant *getInBoundsGetElementPtr(Constant *C, static Constant *getInBoundsGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Value *> IdxList) { ArrayRef<Value *> IdxList) {
return getGetElementPtr(C, IdxList, true); return getGetElementPtr(Ty, C, IdxList, true);
} }
static Constant *getExtractElement(Constant *Vec, Constant *Idx, static Constant *getExtractElement(Constant *Vec, Constant *Idx,

View File

@ -165,9 +165,9 @@ public:
const char *getSection() const; const char *getSection() const;
/// Global values are always pointers. /// Global values are always pointers.
inline PointerType *getType() const { PointerType *getType() const { return cast<PointerType>(User::getType()); }
return cast<PointerType>(User::getType());
} Type *getValueType() const { return getType()->getElementType(); }
static LinkageTypes getLinkOnceLinkage(bool ODR) { static LinkageTypes getLinkOnceLinkage(bool ODR) {
return ODR ? LinkOnceODRLinkage : LinkOnceAnyLinkage; return ODR ? LinkOnceODRLinkage : LinkOnceAnyLinkage;
@ -343,11 +343,11 @@ public:
virtual void eraseFromParent() = 0; virtual void eraseFromParent() = 0;
/// Get the module that this global value is contained inside of... /// Get the module that this global value is contained inside of...
inline Module *getParent() { return Parent; } Module *getParent() { return Parent; }
inline const Module *getParent() const { return Parent; } const Module *getParent() const { return Parent; }
// Methods for support type inquiry through isa, cast, and dyn_cast: // 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 || return V->getValueID() == Value::FunctionVal ||
V->getValueID() == Value::GlobalVariableVal || V->getValueID() == Value::GlobalVariableVal ||
V->getValueID() == Value::GlobalAliasVal; V->getValueID() == Value::GlobalAliasVal;

View File

@ -179,13 +179,13 @@ public:
Constant *CreateGetElementPtr(Constant *C, Constant *CreateGetElementPtr(Constant *C,
ArrayRef<Constant *> IdxList) const { ArrayRef<Constant *> IdxList) const {
return ConstantExpr::getGetElementPtr(C, IdxList); return ConstantExpr::getGetElementPtr(nullptr, C, IdxList);
} }
Constant *CreateGetElementPtr(Constant *C, Constant *Idx) const { Constant *CreateGetElementPtr(Constant *C, Constant *Idx) const {
// This form of the function only exists to avoid ambiguous overload // This form of the function only exists to avoid ambiguous overload
// warnings about whether to convert Idx to ArrayRef<Constant *> or // warnings about whether to convert Idx to ArrayRef<Constant *> or
// ArrayRef<Value *>. // ArrayRef<Value *>.
return ConstantExpr::getGetElementPtr(C, Idx); return ConstantExpr::getGetElementPtr(nullptr, C, Idx);
} }
Instruction *CreateGetElementPtr(Constant *C, Instruction *CreateGetElementPtr(Constant *C,
ArrayRef<Value *> IdxList) const { ArrayRef<Value *> IdxList) const {
@ -194,13 +194,13 @@ public:
Constant *CreateInBoundsGetElementPtr(Constant *C, Constant *CreateInBoundsGetElementPtr(Constant *C,
ArrayRef<Constant *> IdxList) const { ArrayRef<Constant *> IdxList) const {
return ConstantExpr::getInBoundsGetElementPtr(C, IdxList); return ConstantExpr::getInBoundsGetElementPtr(nullptr, C, IdxList);
} }
Constant *CreateInBoundsGetElementPtr(Constant *C, Constant *Idx) const { Constant *CreateInBoundsGetElementPtr(Constant *C, Constant *Idx) const {
// This form of the function only exists to avoid ambiguous overload // This form of the function only exists to avoid ambiguous overload
// warnings about whether to convert Idx to ArrayRef<Constant *> or // warnings about whether to convert Idx to ArrayRef<Constant *> or
// ArrayRef<Value *>. // ArrayRef<Value *>.
return ConstantExpr::getInBoundsGetElementPtr(C, Idx); return ConstantExpr::getInBoundsGetElementPtr(nullptr, C, Idx);
} }
Instruction *CreateInBoundsGetElementPtr(Constant *C, Instruction *CreateInBoundsGetElementPtr(Constant *C,
ArrayRef<Value *> IdxList) const { ArrayRef<Value *> IdxList) const {

View File

@ -671,8 +671,8 @@ static Constant *SymbolicallyEvaluateBinop(unsigned Opc, Constant *Op0,
/// If array indices are not pointer-sized integers, explicitly cast them so /// If array indices are not pointer-sized integers, explicitly cast them so
/// that they aren't implicitly casted by the getelementptr. /// that they aren't implicitly casted by the getelementptr.
static Constant *CastGEPIndices(ArrayRef<Constant *> Ops, Type *ResultTy, static Constant *CastGEPIndices(Type *SrcTy, ArrayRef<Constant *> Ops,
const DataLayout &DL, Type *ResultTy, const DataLayout &DL,
const TargetLibraryInfo *TLI) { const TargetLibraryInfo *TLI) {
Type *IntPtrTy = DL.getIntPtrType(ResultTy); Type *IntPtrTy = DL.getIntPtrType(ResultTy);
@ -698,7 +698,7 @@ static Constant *CastGEPIndices(ArrayRef<Constant *> Ops, Type *ResultTy,
if (!Any) if (!Any)
return nullptr; return nullptr;
Constant *C = ConstantExpr::getGetElementPtr(Ops[0], NewIdxs); Constant *C = ConstantExpr::getGetElementPtr(SrcTy, Ops[0], NewIdxs);
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) { if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
if (Constant *Folded = ConstantFoldConstantExpression(CE, DL, TLI)) if (Constant *Folded = ConstantFoldConstantExpression(CE, DL, TLI))
C = Folded; C = Folded;
@ -724,7 +724,7 @@ static Constant* StripPtrCastKeepAS(Constant* Ptr) {
} }
/// If we can symbolically evaluate the GEP constant expression, do so. /// If we can symbolically evaluate the GEP constant expression, do so.
static Constant *SymbolicallyEvaluateGEP(ArrayRef<Constant *> Ops, static Constant *SymbolicallyEvaluateGEP(Type *SrcTy, ArrayRef<Constant *> Ops,
Type *ResultTy, const DataLayout &DL, Type *ResultTy, const DataLayout &DL,
const TargetLibraryInfo *TLI) { const TargetLibraryInfo *TLI) {
Constant *Ptr = Ops[0]; Constant *Ptr = Ops[0];
@ -866,7 +866,7 @@ static Constant *SymbolicallyEvaluateGEP(ArrayRef<Constant *> Ops,
return nullptr; return nullptr;
// Create a GEP. // Create a GEP.
Constant *C = ConstantExpr::getGetElementPtr(Ptr, NewIdxs); Constant *C = ConstantExpr::getGetElementPtr(SrcTy, Ptr, NewIdxs);
assert(C->getType()->getPointerElementType() == Ty && assert(C->getType()->getPointerElementType() == Ty &&
"Computed GetElementPtr has unexpected type!"); "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]); return ConstantExpr::getInsertElement(Ops[0], Ops[1], Ops[2]);
case Instruction::ShuffleVector: case Instruction::ShuffleVector:
return ConstantExpr::getShuffleVector(Ops[0], Ops[1], Ops[2]); return ConstantExpr::getShuffleVector(Ops[0], Ops[1], Ops[2]);
case Instruction::GetElementPtr: case Instruction::GetElementPtr: {
if (Constant *C = CastGEPIndices(Ops, DestTy, DL, TLI)) Type *SrcTy = nullptr;
if (Constant *C = CastGEPIndices(SrcTy, Ops, DestTy, DL, TLI))
return C; return C;
if (Constant *C = SymbolicallyEvaluateGEP(Ops, DestTy, DL, TLI)) if (Constant *C = SymbolicallyEvaluateGEP(SrcTy, Ops, DestTy, DL, TLI))
return C; return C;
return ConstantExpr::getGetElementPtr(Ops[0], Ops.slice(1)); return ConstantExpr::getGetElementPtr(SrcTy, Ops[0], Ops.slice(1));
}
} }
} }

View File

@ -2978,10 +2978,12 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
// what constant folding can make out of it. // what constant folding can make out of it.
Constant *Null = Constant::getNullValue(GLHS->getPointerOperandType()); Constant *Null = Constant::getNullValue(GLHS->getPointerOperandType());
SmallVector<Value *, 4> IndicesLHS(GLHS->idx_begin(), GLHS->idx_end()); SmallVector<Value *, 4> IndicesLHS(GLHS->idx_begin(), GLHS->idx_end());
Constant *NewLHS = ConstantExpr::getGetElementPtr(Null, IndicesLHS); Constant *NewLHS = ConstantExpr::getGetElementPtr(
GLHS->getSourceElementType(), Null, IndicesLHS);
SmallVector<Value *, 4> IndicesRHS(GRHS->idx_begin(), GRHS->idx_end()); SmallVector<Value *, 4> 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); 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 /// SimplifyGEPInst - Given operands for an GetElementPtrInst, see if we can
/// fold the result. If not, this returns null. /// fold the result. If not, this returns null.
static Value *SimplifyGEPInst(ArrayRef<Value *> Ops, const Query &Q, unsigned) { static Value *SimplifyGEPInst(Type *SrcTy, ArrayRef<Value *> Ops,
const Query &Q, unsigned) {
// The type of the GEP pointer operand. // The type of the GEP pointer operand.
PointerType *PtrTy = cast<PointerType>(Ops[0]->getType()->getScalarType()); unsigned AS =
unsigned AS = PtrTy->getAddressSpace(); cast<PointerType>(Ops[0]->getType()->getScalarType())->getAddressSpace();
// getelementptr P -> P. // getelementptr P -> P.
if (Ops.size() == 1) if (Ops.size() == 1)
return Ops[0]; return Ops[0];
// Compute the (pointer) type returned by the GEP instruction. // Compute the (pointer) type returned by the GEP instruction.
Type *LastType = Type *LastType = GetElementPtrInst::getIndexedType(SrcTy, Ops.slice(1));
GetElementPtrInst::getIndexedType(PtrTy->getElementType(), Ops.slice(1));
Type *GEPTy = PointerType::get(LastType, AS); Type *GEPTy = PointerType::get(LastType, AS);
if (VectorType *VT = dyn_cast<VectorType>(Ops[0]->getType())) if (VectorType *VT = dyn_cast<VectorType>(Ops[0]->getType()))
GEPTy = VectorType::get(GEPTy, VT->getNumElements()); GEPTy = VectorType::get(GEPTy, VT->getNumElements());
@ -3265,7 +3267,7 @@ static Value *SimplifyGEPInst(ArrayRef<Value *> Ops, const Query &Q, unsigned) {
if (match(Ops[1], m_Zero())) if (match(Ops[1], m_Zero()))
return Ops[0]; return Ops[0];
Type *Ty = PtrTy->getElementType(); Type *Ty = SrcTy;
if (Ty->isSized()) { if (Ty->isSized()) {
Value *P; Value *P;
uint64_t C; uint64_t C;
@ -3319,14 +3321,17 @@ static Value *SimplifyGEPInst(ArrayRef<Value *> Ops, const Query &Q, unsigned) {
if (!isa<Constant>(Ops[i])) if (!isa<Constant>(Ops[i]))
return nullptr; return nullptr;
return ConstantExpr::getGetElementPtr(cast<Constant>(Ops[0]), Ops.slice(1)); return ConstantExpr::getGetElementPtr(SrcTy, cast<Constant>(Ops[0]),
Ops.slice(1));
} }
Value *llvm::SimplifyGEPInst(ArrayRef<Value *> Ops, const DataLayout &DL, Value *llvm::SimplifyGEPInst(ArrayRef<Value *> Ops, const DataLayout &DL,
const TargetLibraryInfo *TLI, const TargetLibraryInfo *TLI,
const DominatorTree *DT, AssumptionCache *AC, const DominatorTree *DT, AssumptionCache *AC,
const Instruction *CxtI) { const Instruction *CxtI) {
return ::SimplifyGEPInst(Ops, Query(DL, TLI, DT, AC, CxtI), RecursionLimit); return ::SimplifyGEPInst(
cast<PointerType>(Ops[0]->getType()->getScalarType())->getElementType(),
Ops, Query(DL, TLI, DT, AC, CxtI), RecursionLimit);
} }
/// SimplifyInsertValueInst - Given operands for an InsertValueInst, see if we /// SimplifyInsertValueInst - Given operands for an InsertValueInst, see if we

View File

@ -5690,7 +5690,7 @@ static Constant *BuildConstantFromSCEV(const SCEV *V) {
if (PTy->getElementType()->isStructTy()) if (PTy->getElementType()->isStructTy())
C2 = ConstantExpr::getIntegerCast( C2 = ConstantExpr::getIntegerCast(
C2, Type::getInt32Ty(C->getContext()), true); C2, Type::getInt32Ty(C->getContext()), true);
C = ConstantExpr::getGetElementPtr(C, C2); C = ConstantExpr::getGetElementPtr(PTy->getElementType(), C, C2);
} else } else
C = ConstantExpr::getAdd(C, C2); C = ConstantExpr::getAdd(C, C2);
} }

View File

@ -488,7 +488,8 @@ Value *SCEVExpander::expandAddToGEP(const SCEV *const *op_begin,
// Fold a GEP with constant operands. // Fold a GEP with constant operands.
if (Constant *CLHS = dyn_cast<Constant>(V)) if (Constant *CLHS = dyn_cast<Constant>(V))
if (Constant *CRHS = dyn_cast<Constant>(Idx)) if (Constant *CRHS = dyn_cast<Constant>(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. // Do a quick scan to see if we have this GEP nearby. If so, reuse it.
unsigned ScanLimit = 6; unsigned ScanLimit = 6;

View File

@ -2831,13 +2831,10 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
!BasePointerType->getElementType()->isSized(&Visited)) !BasePointerType->getElementType()->isSized(&Visited))
return Error(ID.Loc, "base element of getelementptr must be sized"); return Error(ID.Loc, "base element of getelementptr must be sized");
if (!GetElementPtrInst::getIndexedType( if (!GetElementPtrInst::getIndexedType(Ty, Indices))
cast<PointerType>(Elts[0]->getType()->getScalarType())
->getElementType(),
Indices))
return Error(ID.Loc, "invalid getelementptr indices"); return Error(ID.Loc, "invalid getelementptr indices");
ID.ConstantVal = ConstantExpr::getGetElementPtr(Elts[0], Indices, ID.ConstantVal =
InBounds); ConstantExpr::getGetElementPtr(Ty, Elts[0], Indices, InBounds);
} else if (Opc == Instruction::Select) { } else if (Opc == Instruction::Select) {
if (Elts.size() != 3) if (Elts.size() != 3)
return Error(ID.Loc, "expected three operands to select"); return Error(ID.Loc, "expected three operands to select");

View File

@ -2313,14 +2313,17 @@ std::error_code BitcodeReader::ParseConstants() {
Elts.push_back(ValueList.getConstantFwdRef(Record[OpNum++], ElTy)); Elts.push_back(ValueList.getConstantFwdRef(Record[OpNum++], ElTy));
} }
ArrayRef<Constant *> Indices(Elts.begin() + 1, Elts.end());
V = ConstantExpr::getGetElementPtr(Elts[0], Indices,
BitCode ==
bitc::CST_CODE_CE_INBOUNDS_GEP);
if (PointeeType && if (PointeeType &&
PointeeType != cast<GEPOperator>(V)->getSourceElementType()) PointeeType !=
cast<SequentialType>(Elts[0]->getType()->getScalarType())
->getElementType())
return Error("Explicit gep operator type does not match pointee type " return Error("Explicit gep operator type does not match pointee type "
"of pointer operand"); "of pointer operand");
ArrayRef<Constant *> Indices(Elts.begin() + 1, Elts.end());
V = ConstantExpr::getGetElementPtr(PointeeType, Elts[0], Indices,
BitCode ==
bitc::CST_CODE_CE_INBOUNDS_GEP);
break; break;
} }
case bitc::CST_CODE_CE_SELECT: { // CE_SELECT: [opval#, opval#, opval#] case bitc::CST_CODE_CE_SELECT: { // CE_SELECT: [opval#, opval#, opval#]

View File

@ -222,7 +222,8 @@ bool GlobalMerge::doMerge(SmallVectorImpl<GlobalVariable*> &Globals,
ConstantInt::get(Int32Ty, 0), ConstantInt::get(Int32Ty, 0),
ConstantInt::get(Int32Ty, k-i) ConstantInt::get(Int32Ty, k-i)
}; };
Constant *GEP = ConstantExpr::getInBoundsGetElementPtr(MergedGV, Idx); Constant *GEP =
ConstantExpr::getInBoundsGetElementPtr(MergedTy, MergedGV, Idx);
Globals[k]->replaceAllUsesWith(GEP); Globals[k]->replaceAllUsesWith(GEP);
Globals[k]->eraseFromParent(); Globals[k]->eraseFromParent();

View File

@ -239,7 +239,7 @@ Constant *ShadowStackGCLowering::GetFrameMap(Function &F) {
Constant *GEPIndices[2] = { Constant *GEPIndices[2] = {
ConstantInt::get(Type::getInt32Ty(F.getContext()), 0), ConstantInt::get(Type::getInt32Ty(F.getContext()), 0),
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) { Type *ShadowStackGCLowering::GetConcreteStackEntryType(Function &F) {

View File

@ -132,7 +132,8 @@ static Constant *FoldBitCast(Constant *V, Type *DestTy) {
if (ElTy == DPTy->getElementType()) if (ElTy == DPTy->getElementType())
// This GEP is inbounds because all indices are zero. // 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 // 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.push_back(Combined);
NewIndices.append(Idxs.begin() + 1, Idxs.end()); NewIndices.append(Idxs.begin() + 1, Idxs.end());
return return ConstantExpr::getGetElementPtr(
ConstantExpr::getGetElementPtr(CE->getOperand(0), NewIndices, cast<GEPOperator>(CE)->getSourceElementType(), CE->getOperand(0),
inBounds && NewIndices, inBounds && cast<GEPOperator>(CE)->isInBounds());
cast<GEPOperator>(CE)->isInBounds());
} }
} }
@ -2148,8 +2148,8 @@ static Constant *ConstantFoldGetElementPtrImpl(Constant *C,
if (SrcArrayTy && DstArrayTy if (SrcArrayTy && DstArrayTy
&& SrcArrayTy->getElementType() == DstArrayTy->getElementType() && SrcArrayTy->getElementType() == DstArrayTy->getElementType()
&& SrcPtrTy->getAddressSpace() == DstPtrTy->getAddressSpace()) && SrcPtrTy->getAddressSpace() == DstPtrTy->getAddressSpace())
return ConstantExpr::getGetElementPtr((Constant*)CE->getOperand(0), return ConstantExpr::getGetElementPtr(
Idxs, inBounds); SrcArrayTy, (Constant *)CE->getOperand(0), Idxs, inBounds);
} }
} }
} }
@ -2215,7 +2215,7 @@ static Constant *ConstantFoldGetElementPtrImpl(Constant *C,
if (!NewIdxs.empty()) { if (!NewIdxs.empty()) {
for (unsigned i = 0, e = Idxs.size(); i != e; ++i) for (unsigned i = 0, e = Idxs.size(); i != e; ++i)
if (!NewIdxs[i]) NewIdxs[i] = cast<Constant>(Idxs[i]); if (!NewIdxs[i]) NewIdxs[i] = cast<Constant>(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 // 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 (!Unknown && !inBounds)
if (auto *GV = dyn_cast<GlobalVariable>(C)) if (auto *GV = dyn_cast<GlobalVariable>(C))
if (!GV->hasExternalWeakLinkage() && isInBoundsIndices(Idxs)) if (!GV->hasExternalWeakLinkage() && isInBoundsIndices(Idxs))
return ConstantExpr::getInBoundsGetElementPtr(C, Idxs); return ConstantExpr::getInBoundsGetElementPtr(nullptr, C, Idxs);
return nullptr; return nullptr;
} }

View File

@ -1252,7 +1252,7 @@ Constant *ConstantExpr::getWithOperands(ArrayRef<Constant *> Ops, Type *Ty,
return ConstantExpr::getShuffleVector(Ops[0], Ops[1], Ops[2], return ConstantExpr::getShuffleVector(Ops[0], Ops[1], Ops[2],
OnlyIfReducedTy); OnlyIfReducedTy);
case Instruction::GetElementPtr: case Instruction::GetElementPtr:
return ConstantExpr::getGetElementPtr(Ops[0], Ops.slice(1), return ConstantExpr::getGetElementPtr(nullptr, Ops[0], Ops.slice(1),
cast<GEPOperator>(this)->isInBounds(), cast<GEPOperator>(this)->isInBounds(),
OnlyIfReducedTy); OnlyIfReducedTy);
case Instruction::ICmp: 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. // 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 *GEPIdx = ConstantInt::get(Type::getInt32Ty(Ty->getContext()), 1);
Constant *GEP = getGetElementPtr( Constant *GEP = getGetElementPtr(
Constant::getNullValue(PointerType::getUnqual(Ty)), GEPIdx); Ty, Constant::getNullValue(PointerType::getUnqual(Ty)), GEPIdx);
return getPtrToInt(GEP, return getPtrToInt(GEP,
Type::getInt64Ty(Ty->getContext())); Type::getInt64Ty(Ty->getContext()));
} }
@ -1939,7 +1939,7 @@ Constant *ConstantExpr::getAlignOf(Type* Ty) {
Constant *Zero = ConstantInt::get(Type::getInt64Ty(Ty->getContext()), 0); Constant *Zero = ConstantInt::get(Type::getInt64Ty(Ty->getContext()), 0);
Constant *One = ConstantInt::get(Type::getInt32Ty(Ty->getContext()), 1); Constant *One = ConstantInt::get(Type::getInt32Ty(Ty->getContext()), 1);
Constant *Indices[2] = { Zero, One }; Constant *Indices[2] = { Zero, One };
Constant *GEP = getGetElementPtr(NullPtr, Indices); Constant *GEP = getGetElementPtr(AligningTy, NullPtr, Indices);
return getPtrToInt(GEP, return getPtrToInt(GEP,
Type::getInt64Ty(Ty->getContext())); Type::getInt64Ty(Ty->getContext()));
} }
@ -1957,7 +1957,7 @@ Constant *ConstantExpr::getOffsetOf(Type* Ty, Constant *FieldNo) {
FieldNo FieldNo
}; };
Constant *GEP = getGetElementPtr( Constant *GEP = getGetElementPtr(
Constant::getNullValue(PointerType::getUnqual(Ty)), GEPIdx); Ty, Constant::getNullValue(PointerType::getUnqual(Ty)), GEPIdx);
return getPtrToInt(GEP, return getPtrToInt(GEP,
Type::getInt64Ty(Ty->getContext())); Type::getInt64Ty(Ty->getContext()));
} }
@ -2001,20 +2001,22 @@ Constant *ConstantExpr::getSelect(Constant *C, Constant *V1, Constant *V2,
return pImpl->ExprConstants.getOrCreate(V1->getType(), Key); return pImpl->ExprConstants.getOrCreate(V1->getType(), Key);
} }
Constant *ConstantExpr::getGetElementPtr(Constant *C, ArrayRef<Value *> Idxs, Constant *ConstantExpr::getGetElementPtr(Type *Ty, Constant *C,
bool InBounds, Type *OnlyIfReducedTy) { ArrayRef<Value *> Idxs, bool InBounds,
assert(C->getType()->isPtrOrPtrVectorTy() && Type *OnlyIfReducedTy) {
"Non-pointer type for constant GetElementPtr expression");
if (Constant *FC = ConstantFoldGetElementPtr(C, InBounds, Idxs)) if (Constant *FC = ConstantFoldGetElementPtr(C, InBounds, Idxs))
return FC; // Fold a few common cases. return FC; // Fold a few common cases.
if (!Ty)
Ty = cast<PointerType>(C->getType()->getScalarType())->getElementType();
else
assert(Ty ==
cast<PointerType>(C->getType()->getScalarType())->getElementType());
// Get the result type of the getelementptr! // Get the result type of the getelementptr!
Type *Ty = GetElementPtrInst::getIndexedType( Type *DestTy = GetElementPtrInst::getIndexedType(Ty, Idxs);
cast<PointerType>(C->getType()->getScalarType())->getElementType(), Idxs); assert(DestTy && "GEP indices invalid!");
assert(Ty && "GEP indices invalid!");
unsigned AS = C->getType()->getPointerAddressSpace(); unsigned AS = C->getType()->getPointerAddressSpace();
Type *ReqTy = Ty->getPointerTo(AS); Type *ReqTy = DestTy->getPointerTo(AS);
if (VectorType *VecTy = dyn_cast<VectorType>(C->getType())) if (VectorType *VecTy = dyn_cast<VectorType>(C->getType()))
ReqTy = VectorType::get(ReqTy, VecTy->getNumElements()); ReqTy = VectorType::get(ReqTy, VecTy->getNumElements());

View File

@ -1153,8 +1153,8 @@ LLVMValueRef LLVMConstGEP(LLVMValueRef ConstantVal,
LLVMValueRef *ConstantIndices, unsigned NumIndices) { LLVMValueRef *ConstantIndices, unsigned NumIndices) {
ArrayRef<Constant *> IdxList(unwrap<Constant>(ConstantIndices, NumIndices), ArrayRef<Constant *> IdxList(unwrap<Constant>(ConstantIndices, NumIndices),
NumIndices); NumIndices);
return wrap(ConstantExpr::getGetElementPtr(unwrap<Constant>(ConstantVal), return wrap(ConstantExpr::getGetElementPtr(
IdxList)); nullptr, unwrap<Constant>(ConstantVal), IdxList));
} }
LLVMValueRef LLVMConstInBoundsGEP(LLVMValueRef ConstantVal, LLVMValueRef LLVMConstInBoundsGEP(LLVMValueRef ConstantVal,
@ -1163,7 +1163,7 @@ LLVMValueRef LLVMConstInBoundsGEP(LLVMValueRef ConstantVal,
Constant* Val = unwrap<Constant>(ConstantVal); Constant* Val = unwrap<Constant>(ConstantVal);
ArrayRef<Constant *> IdxList(unwrap<Constant>(ConstantIndices, NumIndices), ArrayRef<Constant *> IdxList(unwrap<Constant>(ConstantIndices, NumIndices),
NumIndices); NumIndices);
return wrap(ConstantExpr::getInBoundsGetElementPtr(Val, IdxList)); return wrap(ConstantExpr::getInBoundsGetElementPtr(nullptr, Val, IdxList));
} }
LLVMValueRef LLVMConstTrunc(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { LLVMValueRef LLVMConstTrunc(LLVMValueRef ConstantVal, LLVMTypeRef ToType) {

View File

@ -132,9 +132,8 @@ bool NVPTXFavorNonGenericAddrSpaces::hoistAddrSpaceCastFromGEP(
} else { } else {
// GEP is a constant expression. // GEP is a constant expression.
Constant *NewGEPCE = ConstantExpr::getGetElementPtr( Constant *NewGEPCE = ConstantExpr::getGetElementPtr(
cast<Constant>(Cast->getOperand(0)), GEP->getSourceElementType(), cast<Constant>(Cast->getOperand(0)),
Indices, Indices, GEP->isInBounds());
GEP->isInBounds());
GEP->replaceAllUsesWith( GEP->replaceAllUsesWith(
ConstantExpr::getAddrSpaceCast(NewGEPCE, GEP->getType())); ConstantExpr::getAddrSpaceCast(NewGEPCE, GEP->getType()));
} }

View File

@ -308,7 +308,8 @@ LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const
Constant *GA = ConstantExpr::getBitCast(const_cast<GlobalValue*>(GV), Ty); Constant *GA = ConstantExpr::getBitCast(const_cast<GlobalValue*>(GV), Ty);
Ty = Type::getInt32Ty(*DAG.getContext()); Ty = Type::getInt32Ty(*DAG.getContext());
Constant *Idx = ConstantInt::get(Ty, Offset); 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); SDValue CP = DAG.getConstantPool(GAI, MVT::i32);
return DAG.getLoad(getPointerTy(), DL, DAG.getEntryNode(), CP, return DAG.getLoad(getPointerTy(), DL, DAG.getEntryNode(), CP,
MachinePointerInfo(), false, false, false, 0); MachinePointerInfo(), false, false, false, 0);

View File

@ -564,6 +564,7 @@ static GlobalVariable *SRAGlobal(GlobalVariable *GV, const DataLayout &DL) {
if (Val >= NewGlobals.size()) Val = 0; // Out of bound array access. if (Val >= NewGlobals.size()) Val = 0; // Out of bound array access.
Value *NewPtr = NewGlobals[Val]; Value *NewPtr = NewGlobals[Val];
Type *NewTy = NewGlobals[Val]->getType();
// Form a shorter GEP if needed. // Form a shorter GEP if needed.
if (GEP->getNumOperands() > 3) { if (GEP->getNumOperands() > 3) {
@ -572,7 +573,9 @@ static GlobalVariable *SRAGlobal(GlobalVariable *GV, const DataLayout &DL) {
Idxs.push_back(NullInt); Idxs.push_back(NullInt);
for (unsigned i = 3, e = CE->getNumOperands(); i != e; ++i) for (unsigned i = 3, e = CE->getNumOperands(); i != e; ++i)
Idxs.push_back(CE->getOperand(i)); Idxs.push_back(CE->getOperand(i));
NewPtr = ConstantExpr::getGetElementPtr(cast<Constant>(NewPtr), Idxs); NewPtr =
ConstantExpr::getGetElementPtr(NewTy, cast<Constant>(NewPtr), Idxs);
NewTy = GetElementPtrInst::getIndexedType(NewTy, Idxs);
} else { } else {
GetElementPtrInst *GEPI = cast<GetElementPtrInst>(GEP); GetElementPtrInst *GEPI = cast<GetElementPtrInst>(GEP);
SmallVector<Value*, 8> Idxs; SmallVector<Value*, 8> Idxs;
@ -721,8 +724,8 @@ static bool OptimizeAwayTrappingUsesOfValue(Value *V, Constant *NewV) {
else else
break; break;
if (Idxs.size() == GEPI->getNumOperands()-1) if (Idxs.size() == GEPI->getNumOperands()-1)
Changed |= OptimizeAwayTrappingUsesOfValue(GEPI, Changed |= OptimizeAwayTrappingUsesOfValue(
ConstantExpr::getGetElementPtr(NewV, Idxs)); GEPI, ConstantExpr::getGetElementPtr(nullptr, NewV, Idxs));
if (GEPI->use_empty()) { if (GEPI->use_empty()) {
Changed = true; Changed = true;
GEPI->eraseFromParent(); GEPI->eraseFromParent();
@ -2338,7 +2341,7 @@ bool Evaluator::EvaluateBlock(BasicBlock::iterator CurInst,
Constant *IdxZero = ConstantInt::get(IdxTy, 0, false); Constant *IdxZero = ConstantInt::get(IdxTy, 0, false);
Constant * const IdxList[] = {IdxZero, IdxZero}; Constant * const IdxList[] = {IdxZero, IdxZero};
Ptr = ConstantExpr::getGetElementPtr(Ptr, IdxList); Ptr = ConstantExpr::getGetElementPtr(nullptr, Ptr, IdxList);
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Ptr)) if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Ptr))
Ptr = ConstantFoldConstantExpression(CE, DL, TLI); Ptr = ConstantFoldConstantExpression(CE, DL, TLI);
@ -2402,7 +2405,7 @@ bool Evaluator::EvaluateBlock(BasicBlock::iterator CurInst,
i != e; ++i) i != e; ++i)
GEPOps.push_back(getVal(*i)); GEPOps.push_back(getVal(*i));
InstResult = InstResult =
ConstantExpr::getGetElementPtr(P, GEPOps, ConstantExpr::getGetElementPtr(GEP->getSourceElementType(), P, GEPOps,
cast<GEPOperator>(GEP)->isInBounds()); cast<GEPOperator>(GEP)->isInBounds());
DEBUG(dbgs() << "Found a GEP! Simplifying: " << *InstResult DEBUG(dbgs() << "Found a GEP! Simplifying: " << *InstResult
<< "\n"); << "\n");

View File

@ -349,7 +349,8 @@ void LowerBitSets::allocateByteArrays() {
Constant *Idxs[] = {ConstantInt::get(IntPtrTy, 0), Constant *Idxs[] = {ConstantInt::get(IntPtrTy, 0),
ConstantInt::get(IntPtrTy, ByteArrayOffsets[I])}; 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 // 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 // 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. // Multiply by 2 to account for padding elements.
Constant *CombinedGlobalIdxs[] = {ConstantInt::get(Int32Ty, 0), Constant *CombinedGlobalIdxs[] = {ConstantInt::get(Int32Ty, 0),
ConstantInt::get(Int32Ty, I * 2)}; ConstantInt::get(Int32Ty, I * 2)};
Constant *CombinedGlobalElemPtr = Constant *CombinedGlobalElemPtr = ConstantExpr::getGetElementPtr(
ConstantExpr::getGetElementPtr(CombinedGlobal, CombinedGlobalIdxs); NewInit->getType(), CombinedGlobal, CombinedGlobalIdxs);
if (LinkerSubsectionsViaSymbols) { if (LinkerSubsectionsViaSymbols) {
Globals[I]->replaceAllUsesWith(CombinedGlobalElemPtr); Globals[I]->replaceAllUsesWith(CombinedGlobalElemPtr);
} else { } else {

View File

@ -1326,7 +1326,7 @@ bool AddressSanitizerModule::InstrumentGlobals(IRBuilder<> &IRB, Module &M) {
Indices2[1] = IRB.getInt32(0); Indices2[1] = IRB.getInt32(0);
G->replaceAllUsesWith( G->replaceAllUsesWith(
ConstantExpr::getGetElementPtr(NewGlobal, Indices2, true)); ConstantExpr::getGetElementPtr(NewTy, NewGlobal, Indices2, true));
NewGlobal->takeName(G); NewGlobal->takeName(G);
G->eraseFromParent(); G->eraseFromParent();

View File

@ -1102,7 +1102,8 @@ static int AnalyzeLoadFromClobberingMemInst(Type *LoadTy, Value *LoadPtr,
Type::getInt8PtrTy(Src->getContext(), AS)); Type::getInt8PtrTy(Src->getContext(), AS));
Constant *OffsetCst = Constant *OffsetCst =
ConstantInt::get(Type::getInt64Ty(Src->getContext()), (unsigned)Offset); 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)); Src = ConstantExpr::getBitCast(Src, PointerType::get(LoadTy, AS));
if (ConstantFoldLoadFromConstPtr(Src, DL)) if (ConstantFoldLoadFromConstPtr(Src, DL))
return Offset; return Offset;
@ -1263,7 +1264,8 @@ static Value *GetMemInstValueForLoad(MemIntrinsic *SrcInst, unsigned Offset,
Type::getInt8PtrTy(Src->getContext(), AS)); Type::getInt8PtrTy(Src->getContext(), AS));
Constant *OffsetCst = Constant *OffsetCst =
ConstantInt::get(Type::getInt64Ty(Src->getContext()), (unsigned)Offset); 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)); Src = ConstantExpr::getBitCast(Src, PointerType::get(LoadTy, AS));
return ConstantFoldLoadFromConstPtr(Src, DL); return ConstantFoldLoadFromConstPtr(Src, DL);
} }

View File

@ -1012,7 +1012,8 @@ void SCCPSolver::visitGetElementPtrInst(GetElementPtrInst &I) {
Constant *Ptr = Operands[0]; Constant *Ptr = Operands[0];
auto Indices = makeArrayRef(Operands.begin() + 1, Operands.end()); 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) { void SCCPSolver::visitStoreInst(StoreInst &SI) {

View File

@ -852,7 +852,8 @@ static void CleanupAndPrepareModules(BugDriver &BD, Module *&Test,
// GetElementPtr *funcName, ulong 0, ulong 0 // GetElementPtr *funcName, ulong 0, ulong 0
std::vector<Constant*> GEPargs(2, std::vector<Constant*> GEPargs(2,
Constant::getNullValue(Type::getInt32Ty(F->getContext()))); Constant::getNullValue(Type::getInt32Ty(F->getContext())));
Value *GEP = ConstantExpr::getGetElementPtr(funcName, GEPargs); Value *GEP = ConstantExpr::getGetElementPtr(InitArray->getType(),
funcName, GEPargs);
std::vector<Value*> ResolverArgs; std::vector<Value*> ResolverArgs;
ResolverArgs.push_back(GEP); ResolverArgs.push_back(GEP);

View File

@ -249,7 +249,8 @@ TEST(ConstantsTest, AsInstructionsTest) {
// not a normal one! // not a normal one!
//CHECK(ConstantExpr::getGetElementPtr(Global, V, false), //CHECK(ConstantExpr::getGetElementPtr(Global, V, false),
// "getelementptr i32*, i32** @dummy, i32 1"); // "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"); "getelementptr inbounds i32*, i32** @dummy, i32 1");
CHECK(ConstantExpr::getExtractElement(P6, One), "extractelement <2 x i16> " CHECK(ConstantExpr::getExtractElement(P6, One), "extractelement <2 x i16> "
@ -266,7 +267,8 @@ TEST(ConstantsTest, ReplaceWithConstantTest) {
Constant *Global = Constant *Global =
M->getOrInsertGlobal("dummy", PointerType::getUnqual(Int32Ty)); 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), EXPECT_DEATH(Global->replaceAllUsesWith(GEP),
"this->replaceAllUsesWith\\(expr\\(this\\)\\) is NOT valid!"); "this->replaceAllUsesWith\\(expr\\(this\\)\\) is NOT valid!");
} }
@ -333,7 +335,7 @@ TEST(ConstantsTest, GEPReplaceWithConstant) {
auto *C1 = ConstantInt::get(IntTy, 1); auto *C1 = ConstantInt::get(IntTy, 1);
auto *Placeholder = new GlobalVariable( auto *Placeholder = new GlobalVariable(
*M, IntTy, false, GlobalValue::ExternalWeakLinkage, nullptr); *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); ASSERT_EQ(GEP->getOperand(0), Placeholder);
auto *Ref = auto *Ref =