Skip to content

Commit

Permalink
[MemCpyOpt] Add test for unreachable capture (NFC)
Browse files Browse the repository at this point in the history
This is based on the test from D90688, without the argmemonly
attribute. The argmemonly attribute would guaranteed no modref
by itself and the question of captures would not arise in the
first place.
  • Loading branch information
nikic committed May 16, 2021
1 parent 185ce8c commit aaf5fd4
Showing 1 changed file with 39 additions and 6 deletions.
45 changes: 39 additions & 6 deletions llvm/test/Transforms/MemCpyOpt/callslot.ll
Expand Up @@ -103,7 +103,7 @@ define void @throw_between_call_and_mempy(i8* dereferenceable(16) %dest.i8) {
; CHECK-NEXT: [[SRC:%.*]] = alloca [16 x i8], align 1
; CHECK-NEXT: [[SRC_I8:%.*]] = bitcast [16 x i8]* [[SRC]] to i8*
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[SRC_I8]], i8 0, i64 16, i1 false)
; CHECK-NEXT: call void @may_throw() [[ATTR2:#.*]]
; CHECK-NEXT: call void @may_throw() #[[ATTR2:[0-9]+]]
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[DEST_I8:%.*]], i8 0, i64 16, i1 false)
; CHECK-NEXT: ret void
;
Expand All @@ -123,7 +123,7 @@ define void @dest_is_gep_nounwind_call() {
; CHECK-NEXT: [[DEST_I8:%.*]] = getelementptr [16 x i8], [16 x i8]* [[DEST]], i64 0, i64 8
; CHECK-NEXT: [[DEST_I81:%.*]] = bitcast i8* [[DEST_I8]] to [8 x i8]*
; CHECK-NEXT: [[DEST_I812:%.*]] = bitcast [8 x i8]* [[DEST_I81]] to i8*
; CHECK-NEXT: call void @accept_ptr(i8* [[DEST_I812]]) [[ATTR3:#.*]]
; CHECK-NEXT: call void @accept_ptr(i8* [[DEST_I812]]) #[[ATTR3:[0-9]+]]
; CHECK-NEXT: ret void
;
%dest = alloca [16 x i8]
Expand Down Expand Up @@ -163,7 +163,7 @@ define void @dest_is_gep_requires_movement() {
; CHECK-NEXT: [[DEST_I8:%.*]] = getelementptr [16 x i8], [16 x i8]* [[DEST]], i64 0, i64 8
; CHECK-NEXT: [[DEST_I81:%.*]] = bitcast i8* [[DEST_I8]] to [8 x i8]*
; CHECK-NEXT: [[DEST_I812:%.*]] = bitcast [8 x i8]* [[DEST_I81]] to i8*
; CHECK-NEXT: call void @accept_ptr(i8* [[DEST_I812]]) [[ATTR3]]
; CHECK-NEXT: call void @accept_ptr(i8* [[DEST_I812]]) #[[ATTR3]]
; CHECK-NEXT: ret void
;
%dest = alloca [16 x i8]
Expand All @@ -183,7 +183,7 @@ define void @capture_before_call_argmemonly() {
; CHECK-NEXT: [[SRC_I8:%.*]] = bitcast [16 x i8]* [[SRC]] to i8*
; CHECK-NEXT: call void @accept_ptr(i8* [[DEST_I8]])
; CHECK-NEXT: [[DEST1:%.*]] = bitcast [16 x i8]* [[DEST]] to i8*
; CHECK-NEXT: call void @accept_ptr(i8* [[DEST1]]) [[ATTR4:#.*]]
; CHECK-NEXT: call void @accept_ptr(i8* [[DEST1]]) #[[ATTR4:[0-9]+]]
; CHECK-NEXT: ret void
;
%dest = alloca [16 x i8]
Expand All @@ -204,7 +204,7 @@ define void @capture_before_call_argmemonly_nounwind() {
; CHECK-NEXT: [[SRC_I8:%.*]] = bitcast [16 x i8]* [[SRC]] to i8*
; CHECK-NEXT: call void @accept_ptr(i8* [[DEST_I8]])
; CHECK-NEXT: [[DEST1:%.*]] = bitcast [16 x i8]* [[DEST]] to i8*
; CHECK-NEXT: call void @accept_ptr(i8* [[DEST1]]) [[ATTR5:#.*]]
; CHECK-NEXT: call void @accept_ptr(i8* [[DEST1]]) #[[ATTR5:[0-9]+]]
; CHECK-NEXT: ret void
;
%dest = alloca [16 x i8]
Expand All @@ -226,7 +226,7 @@ define void @capture_before_call_argmemonly_nounwind_willreturn() {
; CHECK-NEXT: [[SRC_I8:%.*]] = bitcast [16 x i8]* [[SRC]] to i8*
; CHECK-NEXT: call void @accept_ptr(i8* [[DEST_I8]])
; CHECK-NEXT: [[DEST1:%.*]] = bitcast [16 x i8]* [[DEST]] to i8*
; CHECK-NEXT: call void @accept_ptr(i8* [[DEST1]]) [[ATTR0:#.*]]
; CHECK-NEXT: call void @accept_ptr(i8* [[DEST1]]) #[[ATTR6:[0-9]+]]
; CHECK-NEXT: ret void
;
%dest = alloca [16 x i8]
Expand All @@ -239,6 +239,39 @@ define void @capture_before_call_argmemonly_nounwind_willreturn() {
ret void
}

; There is no path from the capture back to the memcpy.
; So we are allowed to perform the call slot optimization.
define void @capture_nopath_call(i1 %cond) {
; CHECK-LABEL: @capture_nopath_call(
; CHECK-NEXT: [[DEST:%.*]] = alloca [16 x i8], align 1
; CHECK-NEXT: [[SRC:%.*]] = alloca [16 x i8], align 1
; CHECK-NEXT: [[DEST_I8:%.*]] = bitcast [16 x i8]* [[DEST]] to i8*
; CHECK-NEXT: [[SRC_I8:%.*]] = bitcast [16 x i8]* [[SRC]] to i8*
; CHECK-NEXT: br i1 [[COND:%.*]], label [[CAPTURES:%.*]], label [[NOCAPTURES:%.*]]
; CHECK: captures:
; CHECK-NEXT: call void @accept_ptr(i8* [[DEST_I8]])
; CHECK-NEXT: ret void
; CHECK: nocaptures:
; CHECK-NEXT: call void @accept_ptr(i8* [[SRC_I8]]) #[[ATTR3]]
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DEST_I8]], i8* [[SRC_I8]], i64 16, i1 false)
; CHECK-NEXT: ret void
;
%dest = alloca [16 x i8]
%src = alloca [16 x i8]
%dest.i8 = bitcast [16 x i8]* %dest to i8*
%src.i8 = bitcast [16 x i8]* %src to i8*
br i1 %cond, label %captures, label %nocaptures

captures:
call void @accept_ptr(i8* %dest.i8) ; capture
ret void

nocaptures:
call void @accept_ptr(i8* %src.i8) nounwind
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dest.i8, i8* %src.i8, i64 16, i1 false)
ret void
}

declare void @may_throw()
declare void @accept_ptr(i8*)
declare void @llvm.memcpy.p0i8.p0i8.i64(i8*, i8*, i64, i1)
Expand Down

0 comments on commit aaf5fd4

Please sign in to comment.