[PATCH] D55063: [IR] Set nocapture attribute for va_start, va_end, and va_copy

Eugene Sharygin via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 29 09:47:20 PST 2018


eush created this revision.
eush added reviewers: craig.topper, davide, echristo, RKSimon.

This adds nocapture attribute to the definitions of intrinsics `va_start`,
`va_end`, and `va_copy`, which indicates that they do not make any copies of
pointers to `va_list` that outlive the call.

This allows TailCallElim to mark tail calls in variadic functions as such, and
targets to successfully eliminate these calls if it's otherwise possible.

Currently unmarked tail calls in variadic functions are not recognized because
TailCallElim conservatively extends the lifetime of `va_list` local to the end
of the function.


Repository:
  rL LLVM

https://reviews.llvm.org/D55063

Files:
  docs/LangRef.rst
  include/llvm/IR/Intrinsics.td
  test/Transforms/TailCallElim/basic.ll


Index: test/Transforms/TailCallElim/basic.ll
===================================================================
--- test/Transforms/TailCallElim/basic.ll
+++ test/Transforms/TailCallElim/basic.ll
@@ -237,5 +237,20 @@
   ret void
 }
 
+; Argument pointer is not captured by va_start or va_end, and the call can be
+; marked tail.
+define void @test16(...) {
+; CHECK-LABEL: @test16
+; CHECK: tail call void @noarg()
+entry:
+  %ap = alloca i8
+  call void @llvm.va_start(i8* %ap)
+  call void @llvm.va_end(i8* %ap)
+  call void @noarg()
+  ret void
+}
+
 declare void @bar(%struct.foo* byval)
 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i1)
+declare void @llvm.va_start(i8* nocapture)
+declare void @llvm.va_end(i8* nocapture)
Index: include/llvm/IR/Intrinsics.td
===================================================================
--- include/llvm/IR/Intrinsics.td
+++ include/llvm/IR/Intrinsics.td
@@ -303,10 +303,10 @@
 //===--------------- Variable Argument Handling Intrinsics ----------------===//
 //
 
-def int_vastart : Intrinsic<[], [llvm_ptr_ty], [], "llvm.va_start">;
-def int_vacopy  : Intrinsic<[], [llvm_ptr_ty, llvm_ptr_ty], [],
-                            "llvm.va_copy">;
-def int_vaend   : Intrinsic<[], [llvm_ptr_ty], [], "llvm.va_end">;
+def int_vastart : Intrinsic<[], [llvm_ptr_ty], [NoCapture<0>], "llvm.va_start">;
+def int_vacopy : Intrinsic<[], [llvm_ptr_ty, llvm_ptr_ty],
+                           [NoCapture<0>, NoCapture<1>], "llvm.va_copy">;
+def int_vaend   : Intrinsic<[], [llvm_ptr_ty], [NoCapture<0>], "llvm.va_end">;
 
 //===------------------- Garbage Collection Intrinsics --------------------===//
 //
Index: docs/LangRef.rst
===================================================================
--- docs/LangRef.rst
+++ docs/LangRef.rst
@@ -10081,7 +10081,7 @@
 
 ::
 
-      declare void @llvm.va_start(i8* <arglist>)
+      declare void @llvm.va_start(i8* nocapture <arglist>)
 
 Overview:
 """""""""
@@ -10113,7 +10113,7 @@
 
 ::
 
-      declare void @llvm.va_end(i8* <arglist>)
+      declare void @llvm.va_end(i8* nocapture <arglist>)
 
 Overview:
 """""""""
@@ -10146,7 +10146,7 @@
 
 ::
 
-      declare void @llvm.va_copy(i8* <destarglist>, i8* <srcarglist>)
+      declare void @llvm.va_copy(i8* nocapture <destarglist>, i8* nocapture <srcarglist>)
 
 Overview:
 """""""""


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D55063.175894.patch
Type: text/x-patch
Size: 2375 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20181129/86e41966/attachment.bin>


More information about the llvm-commits mailing list