[PATCH] Check address space when optimizing gep+cast

Jingyue Wu jingyue at google.com
Fri Mar 28 14:25:47 PDT 2014


Hi Matt,

That makes sense, and here's a more constructive patch.

Jingyue


On Fri, Mar 28, 2014 at 12:07 PM, Matt Arsenault
<Matthew.Arsenault at amd.com>wrote:

>  On 03/28/2014 12:01 PM, Jingyue Wu wrote:
>
>  Fixing PR19270. This issue is blocking a waiting patch of mine that
> implements the optimization we discussed in
> http://lists.cs.uiuc.edu/pipermail/llvmdev/2014-March/071440.html.
>
>  visitGetElementPtr in InstructionCombining.cpp gets rid of unnecessary
> pointer casts in gep (cast X). However, this optimization may change the
> address space of the result pointer type, and cause type mismatch.
>
>  e.g.,
> getelementptr [256 x float]* addrspacecast ([256 x float] addrspace(3)*
> @array to [256 x float]*), i64 0, i64 %i
> returns a float*, but the optimized instruction
> getelementptr [256 x float] addrspace(3)* @array, i64 0, i64 %i
>  returns a float addrspace(3)*
>
> The attached patch disables this optimization when the address space of
> the source is different from that of the destination.
>
>  Jingyue
>
>
> If we're doing what I suggested and trying to do operations in the
> original address space, then instead of disabling this, why don't you make
> this instead just move the addrspacecast to after the GEP? Do the GEP in
> addrspace(3), and then addrspacecast that.
>
> -Matt
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140328/e9601277/attachment.html>
-------------- next part --------------
diff --git a/lib/Transforms/InstCombine/InstructionCombining.cpp b/lib/Transforms/InstCombine/InstructionCombining.cpp
index 0cab81b..ed23882 100644
--- a/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -1241,7 +1241,10 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
           GetElementPtrInst *Res =
             GetElementPtrInst::Create(StrippedPtr, Idx, GEP.getName());
           Res->setIsInBounds(GEP.isInBounds());
-          return Res;
+          if (StrippedPtrTy->getAddressSpace() == GEP.getAddressSpace())
+            return Res;
+          // Insert Res, and create an addrspacecast.
+          return new AddrSpaceCastInst(Builder->Insert(Res), GEP.getType());
         }
 
         if (ArrayType *XATy =
@@ -1253,8 +1256,18 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
             // to an array of the same type as the destination pointer
             // array.  Because the array type is never stepped over (there
             // is a leading zero) we can fold the cast into this GEP.
-            GEP.setOperand(0, StrippedPtr);
-            return &GEP;
+            if (StrippedPtrTy->getAddressSpace() == GEP.getAddressSpace()) {
+              GEP.setOperand(0, StrippedPtr);
+              return &GEP;
+            }
+            // Cannot replace the base pointer directly because StrippedPtr's
+            // address space is different. Instead, create a new GEP followed by
+            // an addrspacecast.
+            SmallVector<Value*, 8> Idx(GEP.idx_begin(), GEP.idx_end());
+            Value *NewGEP = GEP.isInBounds() ?
+              Builder->CreateInBoundsGEP(StrippedPtr, Idx, GEP.getName()) :
+              Builder->CreateGEP(StrippedPtr, Idx, GEP.getName());
+            return new AddrSpaceCastInst(NewGEP, GEP.getType());
           }
         }
       }
diff --git a/test/Transforms/InstCombine/gep-addrspace.ll b/test/Transforms/InstCombine/gep-addrspace.ll
index 24c355d..efc3180 100644
--- a/test/Transforms/InstCombine/gep-addrspace.ll
+++ b/test/Transforms/InstCombine/gep-addrspace.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -instcombine -S
+; RUN: opt < %s -instcombine -S | FileCheck %s
 
 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
 target triple = "x86_64-pc-win32"
@@ -17,3 +17,13 @@ ST:
   ret void
 }
 
+ at array = internal addrspace(3) global [256 x float] zeroinitializer, align 4
+
+define float* @keep_necessary_addrspacecast(i64 %i) {
+entry:
+; CHECK-LABEL: @keep_necessary_addrspacecast
+; CHECK: addrspacecast float addrspace(3)* %{{[0-9]+}} to float*
+  %0 = getelementptr [256 x float]* addrspacecast ([256 x float] addrspace(3)* @array to [256 x float]*), i64 0, i64 %i
+  ret float* %0
+}
+


More information about the llvm-commits mailing list