[PATCH] SROA fix to avoid invalid bitcast generation when converting a load from a double pointer bitcasted with an address space change of the pointee pointee

Michele Scandale michele.scandale at gmail.com
Fri Mar 7 02:42:01 PST 2014


Hi chandlerc, arsenm,

Here's a fix for SROA to avoid the generation of invalid bitcast between pointers in different address spaces.
The case is the following:

  %p.addr = alloca <2 x float> addrspace(1)*, align 8
  ; ...
  %p.new = bitcast <2 x float> addrspace(1)** %p.addr to <2 x float>**
  %val = load <2 x float>** %p.new, align 8

SROA identifies an AllocaSlice of `%p.addr` and `%val` and tries to rewrite it removing the `load`. The problem is that the source type of the loaded value is `<2 x float> addrspace(1)*` and the destination type is `<2 x float>*`, thus a `bitcast` between those types is invalid.
The proposed fix catches these cases generating a `ptrtoint`+`inttoptr` pair instead of an `addrspacecast` to keep the common bits of the value immutated.

http://llvm-reviews.chandlerc.com/D3002

Files:
  lib/Transforms/Scalar/SROA.cpp
  test/Transforms/SROA/union_ptr_as.ll

Index: lib/Transforms/Scalar/SROA.cpp
===================================================================
--- lib/Transforms/Scalar/SROA.cpp
+++ lib/Transforms/Scalar/SROA.cpp
@@ -1613,6 +1613,13 @@
     return IRB.CreatePtrToInt(V, NewTy);
   }
 
+  // If both types are pointers in different address spaces use the pair
+  // ptrtoint+inttoptr to keep common bits of the value immutated.
+  if (OldTy->isPtrOrPtrVectorTy() && NewTy->isPtrOrPtrVectorTy() &&
+      OldTy->getPointerAddressSpace() != NewTy->getPointerAddressSpace())
+    return IRB.CreateIntToPtr(IRB.CreatePtrToInt(V, DL.getIntPtrType(OldTy)),
+                              NewTy);
+
   return IRB.CreateBitCast(V, NewTy);
 }
 
Index: test/Transforms/SROA/union_ptr_as.ll
===================================================================
--- test/Transforms/SROA/union_ptr_as.ll
+++ test/Transforms/SROA/union_ptr_as.ll
@@ -0,0 +1,32 @@
+; RUN: opt -S -sroa < %s | FileCheck %s
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @union_cvt_float2(<2 x float> addrspace(1)* %p) {
+; CHECK: @union_cvt_float2
+; CHECK: %[[int:.*]] = ptrtoint <2 x float> addrspace(1)* %p to i64
+; CHECK-NEXT: %[[nptr:.*]] = inttoptr i64 %[[int]] to <2 x float>*
+
+  %p.addr = alloca <2 x float> addrspace(1)*, align 8
+  store <2 x float> addrspace(1)* %p, <2 x float> addrspace(1)** %p.addr, align 8
+  %1 = bitcast <2 x float> addrspace(1)** %p.addr to <2 x float>**
+  %2 = load <2 x float>** %1, align 8
+  call void @ext_call_float2(<2 x float>* %2)
+  ret void
+}
+
+define void @union_cvt_v2ptr(<2 x i8 addrspace(1)*> %p) {
+; CHECK: union_cvt_v2ptr
+; CHECK: %[[int:.*]] = ptrtoint <2 x i8 addrspace(1)*> %p to <2 x i64>
+; CHECK-NEXT: %[[nptr:.*]] = inttoptr <2 x i64> %[[int]] to <2 x i8*>
+
+  %p.addr = alloca <2 x i8 addrspace(1)*>, align 8
+  store <2 x i8 addrspace(1)*> %p, <2 x i8 addrspace(1)*>* %p.addr
+  %1 = bitcast <2 x i8 addrspace(1)*>* %p.addr to <2 x i8*>*
+  %2 = load <2 x i8*>* %1, align 8
+  call void @ext_call_v2ptr(<2 x i8*> %2)
+  ret void
+}
+
+declare void @ext_call_float2(<2 x float>*)
+declare void @ext_call_v2ptr(<2 x i8*>)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D3002.1.patch
Type: text/x-patch
Size: 2190 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140307/fae3c330/attachment.bin>


More information about the llvm-commits mailing list