[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