From 77f1b9c4770b3fc9da2b4490af484dc4d23d6932 Mon Sep 17 00:00:00 2001 From: Nadav Rotem Date: Mon, 30 Jul 2012 07:25:20 +0000 Subject: [PATCH] When constant folding GEP expressions, keep the address space information of pointers. Together with Ran Chachick llvm-svn: 160954 --- llvm/lib/Analysis/ConstantFolding.cpp | 22 ++++++++++++++++--- .../InstCombine/2012-07-30-addrsp-bitcast.ll | 10 +++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 llvm/test/Transforms/InstCombine/2012-07-30-addrsp-bitcast.ll diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp index a7c9e550432d..f5e619c6736c 100644 --- a/llvm/lib/Analysis/ConstantFolding.cpp +++ b/llvm/lib/Analysis/ConstantFolding.cpp @@ -603,6 +603,22 @@ static Constant *CastGEPIndices(ArrayRef Ops, 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(Ptr->getType()); + Ptr = cast(Ptr->stripPointerCasts()); + PointerType *NewPtrTy = cast(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 /// constant expression, do so. static Constant *SymbolicallyEvaluateGEP(ArrayRef Ops, @@ -639,13 +655,13 @@ static Constant *SymbolicallyEvaluateGEP(ArrayRef Ops, } return 0; } - + unsigned BitWidth = TD->getTypeSizeInBits(IntPtrTy); APInt Offset = APInt(BitWidth, TD->getIndexedOffset(Ptr->getType(), makeArrayRef((Value **)Ops.data() + 1, Ops.size() - 1))); - Ptr = cast(Ptr->stripPointerCasts()); + Ptr = StripPtrCastKeepAS(Ptr); // If this is a GEP of a GEP, fold it all into a single GEP. while (GEPOperator *GEP = dyn_cast(Ptr)) { @@ -664,7 +680,7 @@ static Constant *SymbolicallyEvaluateGEP(ArrayRef Ops, Ptr = cast(GEP->getOperand(0)); Offset += APInt(BitWidth, TD->getIndexedOffset(Ptr->getType(), NestedOps)); - Ptr = cast(Ptr->stripPointerCasts()); + Ptr = StripPtrCastKeepAS(Ptr); } // If the base value for this address is a literal integer value, fold the diff --git a/llvm/test/Transforms/InstCombine/2012-07-30-addrsp-bitcast.ll b/llvm/test/Transforms/InstCombine/2012-07-30-addrsp-bitcast.ll new file mode 100644 index 000000000000..6f3df5b2fd99 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/2012-07-30-addrsp-bitcast.ll @@ -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 +}