diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp index ceed375aef4..1c6709c9fa1 100644 --- a/lib/Analysis/ConstantFolding.cpp +++ b/lib/Analysis/ConstantFolding.cpp @@ -867,8 +867,7 @@ Constant *CastGEPIndices(Type *SrcElemTy, ArrayRef Ops, } /// Strip the pointer casts, but preserve the address space information. -Constant *StripPtrCastKeepAS(Constant *Ptr, Type *&ElemTy, - bool ForLoadOperand) { +Constant *StripPtrCastKeepAS(Constant *Ptr, bool ForLoadOperand) { assert(Ptr->getType()->isPointerTy() && "Not a pointer type"); auto *OldPtrTy = cast(Ptr->getType()); Ptr = cast(Ptr->stripPointerCasts()); @@ -881,8 +880,6 @@ Constant *StripPtrCastKeepAS(Constant *Ptr, Type *&ElemTy, auto *NewPtrTy = cast(Ptr->getType()); - ElemTy = NewPtrTy->getPointerElementType(); - // Preserve the address space number of the pointer. if (NewPtrTy->getAddressSpace() != OldPtrTy->getAddressSpace()) { Ptr = ConstantExpr::getPointerCast( @@ -942,7 +939,7 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP, DL.getIndexedOffsetInType( SrcElemTy, makeArrayRef((Value * const *)Ops.data() + 1, Ops.size() - 1))); - Ptr = StripPtrCastKeepAS(Ptr, SrcElemTy, ForLoadOperand); + Ptr = StripPtrCastKeepAS(Ptr, ForLoadOperand); // If this is a GEP of a GEP, fold it all into a single GEP. while (auto *GEP = dyn_cast(Ptr)) { @@ -964,7 +961,7 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP, Ptr = cast(GEP->getOperand(0)); SrcElemTy = GEP->getSourceElementType(); Offset += APInt(BitWidth, DL.getIndexedOffsetInType(SrcElemTy, NestedOps)); - Ptr = StripPtrCastKeepAS(Ptr, SrcElemTy, ForLoadOperand); + Ptr = StripPtrCastKeepAS(Ptr, ForLoadOperand); } // If the base value for this address is a literal integer value, fold the @@ -988,8 +985,9 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP, // we eliminate over-indexing of the notional static type array bounds. // This makes it easy to determine if the getelementptr is "inbounds". // Also, this helps GlobalOpt do SROA on GlobalVariables. - Type *Ty = PTy; SmallVector NewIdxs; + Type *Ty = PTy; + SrcElemTy = PTy->getElementType(); do { if (!Ty->isStructTy()) { @@ -1074,7 +1072,7 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP, // If we ended up indexing a member with a type that doesn't match // the type of what the original indices indexed, add a cast. - if (Ty != ResElemTy) + if (C->getType() != ResTy) C = FoldBitCast(C, ResTy, DL); return C; diff --git a/test/Transforms/InstCombine/opaque-ptr.ll b/test/Transforms/InstCombine/opaque-ptr.ll index cd8e3c27345..079f731a454 100644 --- a/test/Transforms/InstCombine/opaque-ptr.ll +++ b/test/Transforms/InstCombine/opaque-ptr.ll @@ -49,3 +49,17 @@ define ptr @bitcast_typed_to_opaque_constexpr() { ; %b = addrspacecast ptr addrspace(1) %a to i8* ; ret i8* %b ;} + +define ptr @gep_constexpr_1(ptr %a) { +; CHECK-LABEL: @gep_constexpr_1( +; CHECK-NEXT: ret ptr inttoptr (i64 6 to ptr) +; + ret ptr getelementptr (i16, ptr null, i32 3) +} + +define ptr @gep_constexpr_2(ptr %a) { +; CHECK-LABEL: @gep_constexpr_2( +; CHECK-NEXT: ret ptr bitcast (i8* getelementptr (i8, i8* @g, i64 3) to ptr) +; + ret ptr getelementptr (i8, ptr bitcast (i8* @g to ptr), i32 3) +}