1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-18 18:42:46 +02:00

[ConstantFold] Delay fetching pointer element type

Don't do this while stipping pointer casts, instead fetch it at
the end. This improves compatibility with opaque pointers for the
case where the base object is not opaque.
This commit is contained in:
Nikita Popov 2021-06-22 12:00:42 +02:00
parent c651fde72b
commit dca0f3abd1
2 changed files with 20 additions and 8 deletions

View File

@ -867,8 +867,7 @@ Constant *CastGEPIndices(Type *SrcElemTy, ArrayRef<Constant *> 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<PointerType>(Ptr->getType());
Ptr = cast<Constant>(Ptr->stripPointerCasts());
@ -881,8 +880,6 @@ Constant *StripPtrCastKeepAS(Constant *Ptr, Type *&ElemTy,
auto *NewPtrTy = cast<PointerType>(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<GEPOperator>(Ptr)) {
@ -964,7 +961,7 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP,
Ptr = cast<Constant>(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<Constant *, 32> 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;

View File

@ -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)
}