[PATCH] Teach InstCombine visitGetElementPtr about address spaces
Eli Friedman
eli.friedman at gmail.com
Mon Aug 19 14:13:34 PDT 2013
@@ -1330,7 +1336,8 @@
if (BitCastInst *BCI = dyn_cast<BitCastInst>(PtrOp)) {
Value *Operand = BCI->getOperand(0);
PointerType *OpType = cast<PointerType>(Operand->getType());
- unsigned OffsetBits = TD->getPointerSizeInBits();
+ unsigned OffsetBits
+ = TD->getPointerSizeInBits(OpType->getPointerAddressSpace());
getPointerTypeSizeInBits()?
Otherwise, LGTM.
-Eli
On Fri, Aug 16, 2013 at 11:27 AM, Matt Arsenault
<Matthew.Arsenault at amd.com>wrote:
> Partially extracted from http://llvm-reviews.chandlerc.com/D1250,
> partially stuff missed before
>
> http://llvm-reviews.chandlerc.com/D1429
>
> Files:
> lib/Transforms/InstCombine/InstCombine.h
> lib/Transforms/InstCombine/InstCombineCasts.cpp
> lib/Transforms/InstCombine/InstructionCombining.cpp
> test/Transforms/InstCombine/cast.ll
>
> Index: lib/Transforms/InstCombine/InstCombine.h
> ===================================================================
> --- lib/Transforms/InstCombine/InstCombine.h
> +++ lib/Transforms/InstCombine/InstCombine.h
> @@ -212,8 +212,8 @@
> bool ShouldChangeType(Type *From, Type *To) const;
> Value *dyn_castNegVal(Value *V) const;
> Value *dyn_castFNegVal(Value *V, bool NoSignedZero=false) const;
> - Type *FindElementAtOffset(Type *Ty, int64_t Offset,
> - SmallVectorImpl<Value*> &NewIndices);
> + Type *FindElementAtOffset(Type *PtrTy, int64_t Offset,
> + SmallVectorImpl<Value*> &NewIndices);
> Instruction *FoldOpIntoSelect(Instruction &Op, SelectInst *SI);
>
> /// ShouldOptimizeCast - Return true if the cast from "V to Ty" actually
> Index: lib/Transforms/InstCombine/InstCombineCasts.cpp
> ===================================================================
> --- lib/Transforms/InstCombine/InstCombineCasts.cpp
> +++ lib/Transforms/InstCombine/InstCombineCasts.cpp
> @@ -1385,9 +1385,10 @@
> GEP->accumulateConstantOffset(*TD, Offset)) {
> // Get the base pointer input of the bitcast, and the type it
> points to.
> Value *OrigBase = BCI->getOperand(0);
> - Type *GEPIdxTy = OrigBase->getType()->getPointerElementType();
> SmallVector<Value*, 8> NewIndices;
> - if (FindElementAtOffset(GEPIdxTy, Offset.getSExtValue(),
> NewIndices)) {
> + if (FindElementAtOffset(OrigBase->getType(),
> + Offset.getSExtValue(),
> + NewIndices)) {
> // If we were able to index down into an element, create the GEP
> // and bitcast the result. This eliminates one bitcast,
> potentially
> // two.
> Index: lib/Transforms/InstCombine/InstructionCombining.cpp
> ===================================================================
> --- lib/Transforms/InstCombine/InstructionCombining.cpp
> +++ lib/Transforms/InstCombine/InstructionCombining.cpp
> @@ -755,19 +755,25 @@
> return ReplaceInstUsesWith(I, NewPN);
> }
>
> -/// FindElementAtOffset - Given a type and a constant offset, determine
> whether
> -/// or not there is a sequence of GEP indices into the type that will
> land us at
> -/// the specified offset. If so, fill them into NewIndices and return the
> -/// resultant element type, otherwise return null.
> -Type *InstCombiner::FindElementAtOffset(Type *Ty, int64_t Offset,
> - SmallVectorImpl<Value*>
> &NewIndices) {
> - if (!TD) return 0;
> - if (!Ty->isSized()) return 0;
> +/// FindElementAtOffset - Given a pointer type and a constant offset,
> determine
> +/// whether or not there is a sequence of GEP indices into the pointed
> type that
> +/// will land us at the specified offset. If so, fill them into
> NewIndices and
> +/// return the resultant element type, otherwise return null.
> +Type *InstCombiner::FindElementAtOffset(Type *PtrTy, int64_t Offset,
> + SmallVectorImpl<Value*>
> &NewIndices) {
> + assert(PtrTy->isPtrOrPtrVectorTy());
> +
> + if (!TD)
> + return 0;
> +
> + Type *Ty = PtrTy->getPointerElementType();
> + if (!Ty->isSized())
> + return 0;
>
> // Start with the index over the outer type. Note that the type size
> // might be zero (even if the offset isn't zero) if the indexed type
> // is something like [0 x {int, int}]
> - Type *IntPtrTy = TD->getIntPtrType(Ty->getContext());
> + Type *IntPtrTy = TD->getIntPtrType(PtrTy);
> int64_t FirstIdx = 0;
> if (int64_t TySize = TD->getTypeAllocSize(Ty)) {
> FirstIdx = Offset/TySize;
> @@ -1235,7 +1241,7 @@
> if (TD && SrcElTy->isArrayTy() &&
> TD->getTypeAllocSize(SrcElTy->getArrayElementType()) ==
> TD->getTypeAllocSize(ResElTy)) {
> - Type *IdxType = TD->getIntPtrType(GEP.getContext());
> + Type *IdxType = TD->getIntPtrType(GEP.getType());
> Value *Idx[2] = { Constant::getNullValue(IdxType),
> GEP.getOperand(1) };
> Value *NewGEP = GEP.isInBounds() ?
> Builder->CreateInBoundsGEP(StrippedPtr, Idx, GEP.getName()) :
> @@ -1260,7 +1266,7 @@
>
> // Earlier transforms ensure that the index has type
> IntPtrType, which
> // considerably simplifies the logic by eliminating implicit
> casts.
> - assert(Idx->getType() == TD->getIntPtrType(GEP.getContext()) &&
> + assert(Idx->getType() == TD->getIntPtrType(GEP.getType()) &&
> "Index not cast to pointer width?");
>
> bool NSW;
> @@ -1295,16 +1301,16 @@
>
> // Earlier transforms ensure that the index has type
> IntPtrType, which
> // considerably simplifies the logic by eliminating implicit
> casts.
> - assert(Idx->getType() == TD->getIntPtrType(GEP.getContext()) &&
> + assert(Idx->getType() == TD->getIntPtrType(GEP.getType()) &&
> "Index not cast to pointer width?");
>
> bool NSW;
> if (Value *NewIdx = Descale(Idx, APInt(BitWidth, Scale), NSW)) {
> // Successfully decomposed Idx as NewIdx * Scale, form a new
> GEP.
> // If the multiplication NewIdx * Scale may overflow then the
> new
> // GEP may not be "inbounds".
> Value *Off[2] = {
> - Constant::getNullValue(TD->getIntPtrType(GEP.getContext())),
> + Constant::getNullValue(TD->getIntPtrType(GEP.getType())),
> NewIdx
> };
>
> @@ -1330,7 +1336,8 @@
> if (BitCastInst *BCI = dyn_cast<BitCastInst>(PtrOp)) {
> Value *Operand = BCI->getOperand(0);
> PointerType *OpType = cast<PointerType>(Operand->getType());
> - unsigned OffsetBits = TD->getPointerSizeInBits();
> + unsigned OffsetBits
> + = TD->getPointerSizeInBits(OpType->getPointerAddressSpace());
> APInt Offset(OffsetBits, 0);
> if (!isa<BitCastInst>(Operand) &&
> GEP.accumulateConstantOffset(*TD, Offset) &&
> @@ -1359,8 +1366,7 @@
> // field at Offset in 'A's type. If so, we can pull the cast
> through the
> // GEP.
> SmallVector<Value*, 8> NewIndices;
> - Type *InTy = OpType->getElementType();
> - if (FindElementAtOffset(InTy, Offset.getSExtValue(), NewIndices)) {
> + if (FindElementAtOffset(OpType, Offset.getSExtValue(), NewIndices))
> {
> Value *NGEP = GEP.isInBounds() ?
> Builder->CreateInBoundsGEP(Operand, NewIndices) :
> Builder->CreateGEP(Operand, NewIndices);
> Index: test/Transforms/InstCombine/cast.ll
> ===================================================================
> --- test/Transforms/InstCombine/cast.ll
> +++ test/Transforms/InstCombine/cast.ll
> @@ -1,6 +1,6 @@
> ; Tests to make sure elimination of casts is working correctly
> ; RUN: opt < %s -instcombine -S | FileCheck %s
> -target datalayout =
> "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128-n8:16:32:64"
> +target datalayout =
> "E-p:64:64:64-p1:32:32:32-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128-n8:16:32:64"
>
> @inbuf = external global [32832 x i8] ; <[32832 x i8]*>
> [#uses=1]
>
> @@ -708,6 +708,19 @@
> ; CHECK-NEXT: ret %s
> }
>
> +define %s @test68_as1(%s addrspace(1)* %p, i32 %i) {
> +; CHECK-LABEL: @test68_as1(
> + %o = mul i32 %i, 12
> + %q = bitcast %s addrspace(1)* %p to i8 addrspace(1)*
> + %pp = getelementptr inbounds i8 addrspace(1)* %q, i32 %o
> +; CHECK-NEXT: getelementptr %s addrspace(1)*
> + %r = bitcast i8 addrspace(1)* %pp to %s addrspace(1)*
> + %l = load %s addrspace(1)* %r
> +; CHECK-NEXT: load %s addrspace(1)*
> + ret %s %l
> +; CHECK-NEXT: ret %s
> +}
> +
> define double @test69(double *%p, i64 %i) {
> ; CHECK-LABEL: @test69(
> %o = shl nsw i64 %i, 3
> @@ -890,6 +903,20 @@
> ; CHECK-NEXT: ret double
> }
>
> +define double @test80_as1([100 x double] addrspace(1)* %p, i16 %i) {
> +; CHECK-LABEL: @test80_as1(
> + %tmp = mul nsw i16 %i, 8
> +; CHECK-NEXT: sext i16 %i to i32
> + %q = bitcast [100 x double] addrspace(1)* %p to i8 addrspace(1)*
> + %pp = getelementptr i8 addrspace(1)* %q, i16 %tmp
> +; CHECK-NEXT: getelementptr [100 x double] addrspace(1)*
> + %r = bitcast i8 addrspace(1)* %pp to double addrspace(1)*
> + %l = load double addrspace(1)* %r
> +; CHECK-NEXT: load double addrspace(1)*
> + ret double %l
> +; CHECK-NEXT: ret double
> +}
> +
> define double @test81(double *%p, float %f) {
> %i = fptosi float %f to i64
> %q = bitcast double* %p to i8*
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130819/bd743a07/attachment.html>
More information about the llvm-commits
mailing list