[llvm] aaf5fd4 - [MemCpyOpt] Add test for unreachable capture (NFC)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Sun May 16 01:50:45 PDT 2021


Author: Nikita Popov
Date: 2021-05-16T10:48:52+02:00
New Revision: aaf5fd4316917506160078139ac2d860d6096bb3

URL: https://github.com/llvm/llvm-project/commit/aaf5fd4316917506160078139ac2d860d6096bb3
DIFF: https://github.com/llvm/llvm-project/commit/aaf5fd4316917506160078139ac2d860d6096bb3.diff

LOG: [MemCpyOpt] Add test for unreachable capture (NFC)

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.

Added: 
    

Modified: 
    llvm/test/Transforms/MemCpyOpt/callslot.ll

Removed: 
    


################################################################################
diff  --git a/llvm/test/Transforms/MemCpyOpt/callslot.ll b/llvm/test/Transforms/MemCpyOpt/callslot.ll
index 944e653e4b733..037a95ec5176c 100644
--- a/llvm/test/Transforms/MemCpyOpt/callslot.ll
+++ b/llvm/test/Transforms/MemCpyOpt/callslot.ll
@@ -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
 ;
@@ -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]
@@ -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]
@@ -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]
@@ -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]
@@ -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]
@@ -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)


        


More information about the llvm-commits mailing list