Skip to content

Commit

Permalink
Don't eliminate memcpy's when the address of the pointer may itself b…
Browse files Browse the repository at this point in the history
…e relevant. Fixes PR18304. Patch by David Wiberg!

llvm-svn: 212970
  • Loading branch information
nlewycky committed Jul 14, 2014
1 parent 0e767b1 commit 703e488
Show file tree
Hide file tree
Showing 7 changed files with 35 additions and 7 deletions.
6 changes: 6 additions & 0 deletions llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,12 @@ bool MemCpyOpt::performCallSlotOptzn(Instruction *cpy,
}
}

// Check that src isn't captured by the called function since the
// transformation can cause aliasing issues in that case.
for (unsigned i = 0, e = CS.arg_size(); i != e; ++i)
if (CS.getArgument(i) == cpySrc && !CS.doesNotCapture(i))
return false;

// Since we're changing the parameter to the callsite, we need to make sure
// that what would be the new parameter dominates the callsite.
DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ target triple = "i386-pc-linux-gnu"

%0 = type { x86_fp80, x86_fp80 }

define internal fastcc void @initialize(%0* noalias sret %agg.result) nounwind {
define internal fastcc void @initialize(%0* noalias nocapture sret %agg.result) nounwind {
entry:
%agg.result.03 = getelementptr %0* %agg.result, i32 0, i32 0
store x86_fp80 0xK00000000000000000000, x86_fp80* %agg.result.03
Expand All @@ -15,7 +15,7 @@ entry:
ret void
}

declare fastcc x86_fp80 @passed_uninitialized(%0*) nounwind
declare fastcc x86_fp80 @passed_uninitialized(%0* nocapture) nounwind

define fastcc void @badly_optimized() nounwind {
entry:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f3
%a = type { i32 }
%b = type { float }

declare void @g(%a*)
declare void @g(%a* nocapture)

define float @f() {
entry:
Expand Down
22 changes: 22 additions & 0 deletions llvm/test/Transforms/MemCpyOpt/capturing-func.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
; RUN: opt < %s -basicaa -memcpyopt -S | FileCheck %s

target datalayout = "e"

declare void @foo(i8*)
declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind

define void @test() {
%ptr1 = alloca i8
%ptr2 = alloca i8
call void @foo(i8* %ptr2)
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %ptr1, i8* %ptr2, i32 1, i32 1, i1 false)
call void @foo(i8* %ptr1)
ret void

; Check that the transformation isn't applied if the called function can
; capture the pointer argument (i.e. the nocapture attribute isn't present)
; CHECK-LABEL: @test(
; CHECK: call void @foo(i8* %ptr2)
; CHECK-NEXT: call void @llvm.memcpy
; CHECK-NEXT: call void @foo(i8* %ptr1)
}
2 changes: 1 addition & 1 deletion llvm/test/Transforms/MemCpyOpt/loadstore-sret.ll
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ _ZNSt8auto_ptrIiED1Ev.exit:
ret void
}

declare void @_Z3barv(%"class.std::auto_ptr"* sret)
declare void @_Z3barv(%"class.std::auto_ptr"* nocapture sret)
4 changes: 2 additions & 2 deletions llvm/test/Transforms/MemCpyOpt/memcpy.ll
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ entry:
; CHECK: ret void
}

declare void @ccoshl(%0* sret , x86_fp80, x86_fp80) nounwind
declare void @ccoshl(%0* nocapture sret, x86_fp80, x86_fp80) nounwind


; The intermediate alloca and one of the memcpy's should be eliminated, the
Expand Down Expand Up @@ -202,7 +202,7 @@ define void @test10(%opaque* noalias nocapture sret %x, i32 %y) {
ret void
}

declare void @f1(%struct.big* sret)
declare void @f1(%struct.big* nocapture sret)
declare void @f2(%struct.big*)

; CHECK: attributes [[NUW]] = { nounwind }
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/MemCpyOpt/sret.ll
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@ entry:
ret void
}

declare void @ccoshl(%0* noalias sret, %0* byval) nounwind
declare void @ccoshl(%0* noalias nocapture sret, %0* byval) nounwind

declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind

0 comments on commit 703e488

Please sign in to comment.