[llvm] r321942 - [InlineFunction] Preserve attributes when forwarding VarArgs.

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Sat Jan 6 12:46:00 PST 2018


Author: fhahn
Date: Sat Jan  6 12:46:00 2018
New Revision: 321942

URL: http://llvm.org/viewvc/llvm-project?rev=321942&view=rev
Log:
[InlineFunction] Preserve attributes when forwarding VarArgs.

Reviewers: rnk, efriedma

Reviewed By: rnk

Differential Revision: https://reviews.llvm.org/D41555


Modified:
    llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp
    llvm/trunk/test/Transforms/Inline/inline-varargs.ll

Modified: llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp?rev=321942&r1=321941&r2=321942&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp Sat Jan  6 12:46:00 2018
@@ -1811,9 +1811,12 @@ bool llvm::InlineFunction(CallSite CS, I
   }
 
   SmallVector<Value*,4> VarArgsToForward;
+  SmallVector<AttributeSet, 4> VarArgsAttrs;
   for (unsigned i = CalledFunc->getFunctionType()->getNumParams();
-       i < CS.getNumArgOperands(); i++)
+       i < CS.getNumArgOperands(); i++) {
     VarArgsToForward.push_back(CS.getArgOperand(i));
+    VarArgsAttrs.push_back(CS.getAttributes().getParamAttributes(i));
+  }
 
   bool InlinedMustTailCalls = false, InlinedDeoptimizeCalls = false;
   if (InlinedFunctionInfo.ContainsCalls) {
@@ -1835,15 +1838,31 @@ bool llvm::InlineFunction(CallSite CS, I
             ((ForwardVarArgsTo &&
               CI->getCalledFunction() == ForwardVarArgsTo) ||
              CI->isMustTailCall())) {
+          // Collect attributes for non-vararg parameters.
+          AttributeList Attrs = CI->getAttributes();
+          SmallVector<AttributeSet, 8> ArgAttrs;
+          if (!Attrs.isEmpty()) {
+            for (unsigned ArgNo = 0;
+                 ArgNo < CI->getFunctionType()->getNumParams(); ++ArgNo)
+              ArgAttrs.push_back(Attrs.getParamAttributes(ArgNo));
+          }
+
+          // Add VarArg attributes.
+          ArgAttrs.append(VarArgsAttrs.begin(), VarArgsAttrs.end());
+          Attrs = AttributeList::get(CI->getContext(), Attrs.getFnAttributes(),
+                                     Attrs.getRetAttributes(), ArgAttrs);
+          // Add VarArgs to existing parameters.
           SmallVector<Value *, 6> Params(CI->arg_operands());
           Params.append(VarArgsToForward.begin(), VarArgsToForward.end());
-          CallInst *Call =
+          CallInst *NewCI =
               CallInst::Create(CI->getCalledFunction() ? CI->getCalledFunction()
                                                        : CI->getCalledValue(),
                                Params, "", CI);
-          Call->setDebugLoc(CI->getDebugLoc());
-          CI->replaceAllUsesWith(Call);
+          NewCI->setDebugLoc(CI->getDebugLoc());
+          NewCI->setAttributes(Attrs);
+          CI->replaceAllUsesWith(NewCI);
           CI->eraseFromParent();
+          CI = NewCI;
         }
 
         if (Function *F = CI->getCalledFunction())

Modified: llvm/trunk/test/Transforms/Inline/inline-varargs.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Inline/inline-varargs.ll?rev=321942&r1=321941&r2=321942&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/Inline/inline-varargs.ll (original)
+++ llvm/trunk/test/Transforms/Inline/inline-varargs.ll Sat Jan  6 12:46:00 2018
@@ -2,11 +2,11 @@
 ; RUN: opt < %s -passes='cgscc(inline,function(instcombine))' -S | FileCheck %s
 
 declare void @ext_method(i8*, i32)
-declare void @vararg_fn(i8*, ...)
+declare signext i16 @vararg_fn(...) #0
 
 define linkonce_odr void @thunk(i8* %this, ...) {
   %this_adj = getelementptr i8, i8* %this, i32 4
-  musttail call void (i8*, ...) bitcast (void (i8*, i32)* @ext_method to void (i8*, ...)*)(i8* %this_adj, ...)
+  musttail call void (i8*, ...) bitcast (void (i8*, i32)* @ext_method to void (i8*, ...)*)(i8* nonnull %this_adj, ...)
   ret void
 }
 
@@ -15,21 +15,31 @@ define void @thunk_caller(i8* %p) {
   ret void
 }
 ; CHECK-LABEL: define void @thunk_caller(i8* %p)
-; CHECK: call void (i8*, ...) bitcast (void (i8*, i32)* @ext_method to void (i8*, ...)*)(i8* %this_adj.i, i32 42)
+; CHECK: call void (i8*, ...) bitcast (void (i8*, i32)* @ext_method to void (i8*, ...)*)(i8* nonnull %this_adj.i, i32 42)
 
-define void @test_callee_2(i8* %this, ...) {
-  %this_adj = getelementptr i8, i8* %this, i32 4
-  musttail call void (i8*, ...) @vararg_fn(i8* %this_adj, ...)
+define signext i16 @test_callee_2(...) {
+  %res = musttail call signext i16 (...) @vararg_fn(...) #0
+  ret i16 %res
+}
+
+define void @test_caller_2(i8* %p, i8* %q, i16 %r) {
+  call signext i16 (...) @test_callee_2(i8* %p, i8* byval %q, i16 signext %r)
   ret void
 }
+; CHECK-LABEL: define void @test_caller_2
+; CHECK: call signext i16 (...) @vararg_fn(i8* %p, i8* byval %q, i16 signext %r) [[FN_ATTRS:#[0-9]+]]
 
-define void @test_caller_2(i8* %p) {
-  call void (i8*, ...) @test_callee_2(i8* %p)
+define void @test_callee_3(i8* %p, ...) {
+  call signext i16 (...) @vararg_fn()
   ret void
 }
-; CHECK-LABEL: define void @test_caller_2(i8* %p)
-; CHECK: call void (i8*, ...) @vararg_fn(i8* %this_adj.i)
 
+define void @test_caller_3(i8* %p, i8* %q) {
+  call void (i8*, ...) @test_callee_3(i8* nonnull %p, i8* %q)
+  ret void
+}
+; CHECK-LABEL: define void @test_caller_3
+; CHECK: call signext i16 (...) @vararg_fn()
 
 define internal i32 @varg_accessed(...) {
 entry:
@@ -50,3 +60,6 @@ define i32 @call_vargs() {
 
 declare void @llvm.va_start(i8*)
 declare void @llvm.va_end(i8*)
+
+; CHECK: attributes [[FN_ATTRS]] = { "foo"="bar" }
+attributes #0 = { "foo"="bar" }




More information about the llvm-commits mailing list