When constant folding GEP expressions, keep the address space information of pointers.

Together with Ran Chachick <ran.chachick@intel.com>



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@160954 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Nadav Rotem 2012-07-30 07:25:20 +00:00
parent 818f609459
commit 97baaeaeb2
2 changed files with 29 additions and 3 deletions

View File

@ -603,6 +603,22 @@ static Constant *CastGEPIndices(ArrayRef<Constant *> Ops,
return C; return C;
} }
/// Strip the pointer casts, but preserve the address space information.
static Constant* StripPtrCastKeepAS(Constant* Ptr) {
assert(Ptr->getType()->isPointerTy() && "Not a pointer type");
PointerType *OldPtrTy = cast<PointerType>(Ptr->getType());
Ptr = cast<Constant>(Ptr->stripPointerCasts());
PointerType *NewPtrTy = cast<PointerType>(Ptr->getType());
// Preserve the address space number of the pointer.
if (NewPtrTy->getAddressSpace() != OldPtrTy->getAddressSpace()) {
NewPtrTy = NewPtrTy->getElementType()->getPointerTo(
OldPtrTy->getAddressSpace());
Ptr = ConstantExpr::getBitCast(Ptr, NewPtrTy);
}
return Ptr;
}
/// SymbolicallyEvaluateGEP - If we can symbolically evaluate the specified GEP /// SymbolicallyEvaluateGEP - If we can symbolically evaluate the specified GEP
/// constant expression, do so. /// constant expression, do so.
static Constant *SymbolicallyEvaluateGEP(ArrayRef<Constant *> Ops, static Constant *SymbolicallyEvaluateGEP(ArrayRef<Constant *> Ops,
@ -639,13 +655,13 @@ static Constant *SymbolicallyEvaluateGEP(ArrayRef<Constant *> Ops,
} }
return 0; return 0;
} }
unsigned BitWidth = TD->getTypeSizeInBits(IntPtrTy); unsigned BitWidth = TD->getTypeSizeInBits(IntPtrTy);
APInt Offset = APInt Offset =
APInt(BitWidth, TD->getIndexedOffset(Ptr->getType(), APInt(BitWidth, TD->getIndexedOffset(Ptr->getType(),
makeArrayRef((Value **)Ops.data() + 1, makeArrayRef((Value **)Ops.data() + 1,
Ops.size() - 1))); Ops.size() - 1)));
Ptr = cast<Constant>(Ptr->stripPointerCasts()); Ptr = StripPtrCastKeepAS(Ptr);
// If this is a GEP of a GEP, fold it all into a single GEP. // If this is a GEP of a GEP, fold it all into a single GEP.
while (GEPOperator *GEP = dyn_cast<GEPOperator>(Ptr)) { while (GEPOperator *GEP = dyn_cast<GEPOperator>(Ptr)) {
@ -664,7 +680,7 @@ static Constant *SymbolicallyEvaluateGEP(ArrayRef<Constant *> Ops,
Ptr = cast<Constant>(GEP->getOperand(0)); Ptr = cast<Constant>(GEP->getOperand(0));
Offset += APInt(BitWidth, Offset += APInt(BitWidth,
TD->getIndexedOffset(Ptr->getType(), NestedOps)); TD->getIndexedOffset(Ptr->getType(), NestedOps));
Ptr = cast<Constant>(Ptr->stripPointerCasts()); Ptr = StripPtrCastKeepAS(Ptr);
} }
// If the base value for this address is a literal integer value, fold the // If the base value for this address is a literal integer value, fold the

View File

@ -0,0 +1,10 @@
; RUN: opt < %s -instcombine -S | FileCheck %s
; CHECK: bitcast
@base = internal addrspace(3) unnamed_addr global [16 x i32] zeroinitializer, align 16
declare void @foo(i32*)
define void @test() nounwind {
call void @foo(i32* getelementptr (i32* bitcast ([16 x i32] addrspace(3)* @base to i32*), i64 2147483647)) nounwind
ret void
}