summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Stellard <thomas.stellard@amd.com>2013-10-14 15:38:21 -0700
committerTom Stellard <thomas.stellard@amd.com>2013-10-15 08:59:39 -0700
commit7b6094566257c0e320b242cbdf097580a8c35432 (patch)
tree8543e03642c8041484bdaab36e9da3df5323db04
parentf7c9f8f53ac1f7cd315ae142914113146b13ee76 (diff)
SROA: Prevent a cross address space bitcastmaster-testing
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
-rw-r--r--lib/Transforms/Scalar/SROA.cpp9
-rw-r--r--test/Transforms/SROA/sroa-addrspace-bug.ll52
2 files changed, 59 insertions, 2 deletions
diff --git a/lib/Transforms/Scalar/SROA.cpp b/lib/Transforms/Scalar/SROA.cpp
index a0be2c6947e..399094220b8 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 00000000000..34e8d82cf59
--- /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}
+
+