[PATCH] D81409: CallPromotion: Don't try to pass sret args to varargs functions
Hans Wennborg via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 8 09:56:54 PDT 2020
hans created this revision.
hans added reviewers: mtrofin, xur.
Herald added subscribers: llvm-commits, hiraditya.
Herald added a project: LLVM.
It's not allowed by the verifier. We hit this in Chromium.
https://reviews.llvm.org/D81409
Files:
llvm/lib/Transforms/Utils/CallPromotionUtils.cpp
llvm/test/Transforms/PGOProfile/icp_vararg_sret.ll
Index: llvm/test/Transforms/PGOProfile/icp_vararg_sret.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/PGOProfile/icp_vararg_sret.ll
@@ -0,0 +1,28 @@
+; 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
+
+ %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}
Index: llvm/lib/Transforms/Utils/CallPromotionUtils.cpp
===================================================================
--- llvm/lib/Transforms/Utils/CallPromotionUtils.cpp
+++ llvm/lib/Transforms/Utils/CallPromotionUtils.cpp
@@ -403,9 +403,12 @@
// 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 @@
// 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 @@
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;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D81409.269272.patch
Type: text/x-patch
Size: 2715 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200608/d40aff98/attachment.bin>
More information about the llvm-commits
mailing list