[PATCH] SROA: Prevent a cross address space bitcast

Tom Stellard tom at stellard.net
Mon Oct 14 18:58:55 PDT 2013


From: Tom Stellard <thomas.stellard at amd.com>

Patch by: Michael Ferguson

This is a modified version of Michael's patch posted here:
http://www.llvm.org/bugs/show_bug.cgi?id=15907#c1 I removed the bitcast
wrapper and left only what was necessary to fix the bug.

http://www.llvm.org/bugs/show_bug.cgi?id=15907
---
 lib/Transforms/Scalar/SROA.cpp             |  9 ++++--
 test/Transforms/SROA/sroa-addrspace-bug.ll | 52 ++++++++++++++++++++++++++++++
 2 files changed, 59 insertions(+), 2 deletions(-)
 create mode 100644 test/Transforms/SROA/sroa-addrspace-bug.ll

diff --git a/lib/Transforms/Scalar/SROA.cpp b/lib/Transforms/Scalar/SROA.cpp
index a0be2c6..3990942 100644
--- a/lib/Transforms/Scalar/SROA.cpp
+++ b/lib/Transforms/Scalar/SROA.cpp
@@ -1416,8 +1416,9 @@ static Value *getAdjustedPtr(IRBuilderTy &IRB, const DataLayout &DL,
 
   if (!OffsetPtr) {
     if (!Int8Ptr) {
-      Int8Ptr = IRB.CreateBitCast(Ptr, IRB.getInt8PtrTy(),
-                                  "raw_cast");
+      unsigned PtrAS = Ptr->getType()->getPointerAddressSpace();
+      Int8Ptr = IRB.CreateBitCast(Ptr, IRB.getInt8PtrTy(PtrAS),
+                                 "raw_cast");
       Int8PtrOffset = Offset;
     }
 
@@ -2485,6 +2486,7 @@ private:
     // Strip all inbounds GEPs and pointer casts to try to dig out any root
     // alloca that should be re-examined after rewriting this instruction.
     Value *OtherPtr = IsDest ? II.getRawSource() : II.getRawDest();
+    unsigned OtherAS = OtherPtr->getType()->getPointerAddressSpace();
     if (AllocaInst *AI
           = dyn_cast<AllocaInst>(OtherPtr->stripInBoundsOffsets()))
       Pass.Worklist.insert(AI);
@@ -2538,6 +2540,9 @@ private:
       OtherPtrTy = SubIntTy->getPointerTo();
     }
 
+    // Fix OtherPtrTy to be in OtherAS address space.
+    OtherPtrTy = OtherPtrTy->getPointerElementType()->getPointerTo(OtherAS);
+
     Value *SrcPtr = getAdjustedPtr(IRB, DL, OtherPtr, RelOffset, OtherPtrTy);
     Value *DstPtr = &NewAI;
     if (!IsDest)
diff --git a/test/Transforms/SROA/sroa-addrspace-bug.ll b/test/Transforms/SROA/sroa-addrspace-bug.ll
new file mode 100644
index 0000000..34e8d82
--- /dev/null
+++ b/test/Transforms/SROA/sroa-addrspace-bug.ll
@@ -0,0 +1,52 @@
+; RUN: opt < %s -sroa -S | FileCheck %s
+
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-v16:16:16-v24:32:32-v32:32:32-v48:64:64-v64:64:64-v96:128:128-v128:128:128-v192:256:256-v256:256:256-v512:512:512-v1024:1024:1024-v2048:2048:2048-n32:64"
+target triple = "r600"
+
+%struct.Block = type { i32, i32, i32 }
+
+; CHECK-NOT: bitcast i8 addrspace(1)* {{%[a-zA-z0-9._]+}} to i32*
+
+; Function Attrs: nounwind
+define void @struct_assign_copy(%struct.Block addrspace(1)* nocapture readonly %ip, i32 addrspace(1)* nocapture %out) #0 {
+entry:
+  %block2 = alloca %struct.Block, align 8
+  %tmp = alloca i32, align 4
+  %block = alloca %struct.Block, align 4
+  %0 = bitcast %struct.Block* %block to i8*
+  %1 = bitcast %struct.Block addrspace(1)* %ip to i8 addrspace(1)*
+  call void @llvm.memcpy.p0i8.p1i8.i32(i8* %0, i8 addrspace(1)* %1, i32 12, i32 4, i1 false)
+  %2 = load i32 addrspace(1)* %out, align 4
+  store i32 %2, i32* %tmp, align 4
+  %tmp3 = bitcast %struct.Block* %block2 to i8*
+  %tmp4 = bitcast %struct.Block* %block to i8*
+  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %tmp3, i8* %tmp4, i64 12, i32 1, i1 false)
+  %f0.i = getelementptr inbounds %struct.Block* %block2, i32 0, i32 0
+  %3 = load i32* %f0.i, align 4
+  %cmp.i = icmp eq i32 %3, 42
+  br i1 %cmp.i, label %if.then.i, label %process.exit
+
+if.then.i:                                        ; preds = %entry
+  store i32 1, i32* %tmp, align 4
+  br label %process.exit
+
+process.exit:                                     ; preds = %entry, %if.then.i
+  %4 = load i32* %tmp, align 4
+  store i32 %4, i32 addrspace(1)* %out, align 4
+  ret void
+}
+
+; Function Attrs: nounwind
+declare void @llvm.memcpy.p0i8.p1i8.i32(i8* nocapture, i8 addrspace(1)* nocapture readonly, i32, i32, i1) #1
+
+; Function Attrs: nounwind
+declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32, i1) #1
+
+attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { nounwind }
+
+!opencl.kernels = !{!0}
+
+!0 = metadata !{void (%struct.Block addrspace(1)*, i32 addrspace(1)*)* @struct_assign_copy}
+
+
-- 
1.7.11.4




More information about the llvm-commits mailing list