mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-24 14:20:17 +00:00
[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
This commit is contained in:
parent
c07339c675
commit
fc202c5fec
@ -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;
|
||||
}
|
||||
|
29
llvm/test/Transforms/PGOProfile/icp_vararg_sret.ll
Normal file
29
llvm/test/Transforms/PGOProfile/icp_vararg_sret.ll
Normal file
@ -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 }
|
||||
@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}
|
Loading…
Reference in New Issue
Block a user