[llvm] fc202c5 - [PGO] CallPromotion: Don't try to pass sret args to varargs functions

Hans Wennborg via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 8 12:10:54 PDT 2020


Author: Hans Wennborg
Date: 2020-06-08T21:10:27+02:00
New Revision: fc202c5fec07c8dd24c6cb2e33c3bbdb5d54db6e

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

LOG: [PGO] CallPromotion: Don't try to pass sret args to varargs functions

It's not allowed by the verifier.

Differential revision: https://reviews.llvm.org/D81409

Added: 
    llvm/test/Transforms/PGOProfile/icp_vararg_sret.ll

Modified: 
    llvm/lib/Transforms/Utils/CallPromotionUtils.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Utils/CallPromotionUtils.cpp b/llvm/lib/Transforms/Utils/CallPromotionUtils.cpp
index a7a0290ee475..5a47c1fd0b6c 100644
--- a/llvm/lib/Transforms/Utils/CallPromotionUtils.cpp
+++ b/llvm/lib/Transforms/Utils/CallPromotionUtils.cpp
@@ -403,9 +403,12 @@ bool llvm::isLegalToPromote(const CallBase &CB, Function *Callee,
   // The number of formal arguments of the callee.
   unsigned NumParams = Callee->getFunctionType()->getNumParams();
 
+  // The number of actual arguments in the call.
+  unsigned NumArgs = CB.arg_size();
+
   // Check the number of arguments. The callee and call site must agree on the
   // number of arguments.
-  if (CB.arg_size() != NumParams && !Callee->isVarArg()) {
+  if (NumArgs != NumParams && !Callee->isVarArg()) {
     if (FailureReason)
       *FailureReason = "The number of arguments mismatch";
     return false;
@@ -414,7 +417,8 @@ bool llvm::isLegalToPromote(const CallBase &CB, Function *Callee,
   // Check the argument types. The callee's formal argument types must be
   // bitcast compatible with the corresponding actual argument types of the call
   // site.
-  for (unsigned I = 0; I < NumParams; ++I) {
+  unsigned I = 0;
+  for (; I < NumParams; ++I) {
     Type *FormalTy = Callee->getFunctionType()->getFunctionParamType(I);
     Type *ActualTy = CB.getArgOperand(I)->getType();
     if (FormalTy == ActualTy)
@@ -425,6 +429,14 @@ bool llvm::isLegalToPromote(const CallBase &CB, Function *Callee,
       return false;
     }
   }
+  for (; I < NumArgs; I++) {
+    // Vararg functions can have more arguments than paramters.
+    assert(Callee->isVarArg());
+    if (CB.paramHasAttr(I, Attribute::StructRet)) {
+      *FailureReason = "SRet arg to vararg function";
+      return false;
+    }
+  }
 
   return true;
 }

diff  --git a/llvm/test/Transforms/PGOProfile/icp_vararg_sret.ll b/llvm/test/Transforms/PGOProfile/icp_vararg_sret.ll
new file mode 100644
index 000000000000..5f1232a09e58
--- /dev/null
+++ b/llvm/test/Transforms/PGOProfile/icp_vararg_sret.ll
@@ -0,0 +1,29 @@
+; RUN: opt < %s -pgo-icall-prom -S | FileCheck %s
+; RUN: opt < %s -passes=pgo-icall-prom -S | FileCheck %s
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @va_func(i32 %num, ...) {
+entry:
+  ret void
+}
+
+%struct = type { i32 }
+ at func_ptr = common global void (i32, %struct*)* null, align 8
+
+define void @test() {
+; Even though value profiling suggests @va_func is the call target, don't do
+; call promotion because the sret argument is not compatible with the varargs
+; function.
+; CHECK-LABEL: @test
+; CHECK-NOT: call void (i32, ...) @va_func
+; CHECK: call void %tmp
+; CHECK: ret void
+
+  %s = alloca %struct
+  %tmp = load void (i32, %struct*)*, void (i32, %struct*)** @func_ptr, align 8
+  call void %tmp(i32 1, %struct* sret %s), !prof !1
+  ret void
+}
+
+!1 = !{!"VP", i32 0, i64 12345, i64 989055279648259519, i64 12345}


        


More information about the llvm-commits mailing list