From 614ea99da71a5ce2a259b79ca42ee0c0a0e79112 Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Wed, 30 Oct 2013 19:05:41 +0000 Subject: [PATCH] Fix GVN creating bitcast between address spaces llvm-svn: 193710 --- llvm/lib/Transforms/Scalar/GVN.cpp | 12 +++++++----- llvm/test/Transforms/GVN/rle.ll | 20 +++++++++++++++++--- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp index aa4e18505eb5..731a6d0141c4 100644 --- a/llvm/lib/Transforms/Scalar/GVN.cpp +++ b/llvm/lib/Transforms/Scalar/GVN.cpp @@ -1088,14 +1088,15 @@ static int AnalyzeLoadFromClobberingMemInst(Type *LoadTy, Value *LoadPtr, if (Offset == -1) return Offset; + unsigned AS = Src->getType()->getPointerAddressSpace(); // Otherwise, see if we can constant fold a load from the constant with the // offset applied as appropriate. Src = ConstantExpr::getBitCast(Src, - llvm::Type::getInt8PtrTy(Src->getContext())); + Type::getInt8PtrTy(Src->getContext(), AS)); Constant *OffsetCst = ConstantInt::get(Type::getInt64Ty(Src->getContext()), (unsigned)Offset); Src = ConstantExpr::getGetElementPtr(Src, OffsetCst); - Src = ConstantExpr::getBitCast(Src, PointerType::getUnqual(LoadTy)); + Src = ConstantExpr::getBitCast(Src, PointerType::get(LoadTy, AS)); if (ConstantFoldLoadFromConstPtr(Src, &TD)) return Offset; return -1; @@ -1247,15 +1248,16 @@ static Value *GetMemInstValueForLoad(MemIntrinsic *SrcInst, unsigned Offset, // Otherwise, this is a memcpy/memmove from a constant global. MemTransferInst *MTI = cast(SrcInst); Constant *Src = cast(MTI->getSource()); + unsigned AS = Src->getType()->getPointerAddressSpace(); // Otherwise, see if we can constant fold a load from the constant with the // offset applied as appropriate. Src = ConstantExpr::getBitCast(Src, - llvm::Type::getInt8PtrTy(Src->getContext())); + Type::getInt8PtrTy(Src->getContext(), AS)); Constant *OffsetCst = - ConstantInt::get(Type::getInt64Ty(Src->getContext()), (unsigned)Offset); + ConstantInt::get(Type::getInt64Ty(Src->getContext()), (unsigned)Offset); Src = ConstantExpr::getGetElementPtr(Src, OffsetCst); - Src = ConstantExpr::getBitCast(Src, PointerType::getUnqual(LoadTy)); + Src = ConstantExpr::getBitCast(Src, PointerType::get(LoadTy, AS)); return ConstantFoldLoadFromConstPtr(Src, &TD); } diff --git a/llvm/test/Transforms/GVN/rle.ll b/llvm/test/Transforms/GVN/rle.ll index a928a165560b..8d289b06997c 100644 --- a/llvm/test/Transforms/GVN/rle.ll +++ b/llvm/test/Transforms/GVN/rle.ll @@ -1,5 +1,5 @@ -; RUN: opt < %s -default-data-layout="e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-n8:16:32" -basicaa -gvn -S -die | FileCheck %s -; RUN: opt < %s -default-data-layout="E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-n32" -basicaa -gvn -S -die | FileCheck %s +; RUN: opt < %s -default-data-layout="e-p:32:32:32-p1:16:16:16-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-n8:16:32" -basicaa -gvn -S -die | FileCheck %s +; RUN: opt < %s -default-data-layout="E-p:32:32:32-p1:16:16:16-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-n32" -basicaa -gvn -S -die | FileCheck %s ;; Trivial RLE test. define i32 @test0(i32 %V, i32* %P) { @@ -195,6 +195,7 @@ Cont: } @GCst = constant {i32, float, i32 } { i32 42, float 14., i32 97 } +@GCst_as1 = addrspace(1) constant {i32, float, i32 } { i32 42, float 14., i32 97 } ; memset -> float forwarding. define float @memcpy_to_float_local(float* %A) nounwind ssp { @@ -209,7 +210,18 @@ entry: ; CHECK: ret float 1.400000e+01 } - +; memcpy from address space 1 +define float @memcpy_to_float_local_as1(float* %A) nounwind ssp { +entry: + %conv = bitcast float* %A to i8* ; [#uses=1] + tail call void @llvm.memcpy.p0i8.p1i8.i64(i8* %conv, i8 addrspace(1)* bitcast ({i32, float, i32 } addrspace(1)* @GCst_as1 to i8 addrspace(1)*), i64 12, i32 1, i1 false) + %arrayidx = getelementptr inbounds float* %A, i64 1 ; [#uses=1] + %tmp2 = load float* %arrayidx ; [#uses=1] + ret float %tmp2 +; CHECK-LABEL: @memcpy_to_float_local_as1( +; CHECK-NOT: load +; CHECK: ret float 1.400000e+01 +} ;; non-local i32/float -> i8 load forwarding. define i8 @coerce_mustalias_nonlocal0(i32* %P, i1 %cond) { @@ -647,6 +659,8 @@ entry: declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind +declare void @llvm.memcpy.p0i8.p1i8.i64(i8* nocapture, i8 addrspace(1)* nocapture, i64, i32, i1) nounwind + ;;===----------------------------------------------------------------------===;; ;; Load -> Store dependency which isn't interfered with by a call that happens