https://gcc.gnu.org/g:2d995ac584d7623eefe3bf8f60d05941fa55a1b9
commit r17-2211-g2d995ac584d7623eefe3bf8f60d05941fa55a1b9 Author: Richard Biener <[email protected]> Date: Tue Jul 7 08:54:45 2026 +0200 Improve variadic function call handling in PTA The following fixes handling of __builtin_va_start handling and implements .VA_ARG handling in PTA constraint generation to improve precision around variadic calls. I've added a testcase for IPA PTA involving an indirect variadic call verifying precision. The pr99679-1.C no longer emits an expected error that was triggered by PTA calling aggregate_value_p on the .VA_ARG call which we no longer do. * gimple-ssa-pta-constraints.cc (find_func_aliases_for_builtin_call): Correctly use SCALAR rhs from the variadic argument part of the function info or from NONLOCAL in case of intra-PTA. (find_func_aliases_for_call): Handle .VA_ARG. * gcc.dg/ipa/ipa-pta-20.c: New testcase. * g++.target/i386/pr99679-1.C: Remove expected error. * g++.target/i386/pr99679-2.C: Likewise. Diff: --- gcc/gimple-ssa-pta-constraints.cc | 19 ++++++++++++++++-- gcc/testsuite/g++.target/i386/pr99679-1.C | 2 +- gcc/testsuite/g++.target/i386/pr99679-2.C | 2 +- gcc/testsuite/gcc.dg/ipa/ipa-pta-20.c | 33 +++++++++++++++++++++++++++++++ 4 files changed, 52 insertions(+), 4 deletions(-) diff --git a/gcc/gimple-ssa-pta-constraints.cc b/gcc/gimple-ssa-pta-constraints.cc index dec3b2f6f140..a377b891d802 100644 --- a/gcc/gimple-ssa-pta-constraints.cc +++ b/gcc/gimple-ssa-pta-constraints.cc @@ -2010,12 +2010,12 @@ find_func_aliases_for_builtin_call (struct function *fn, gcall *t) { fi = lookup_vi_for_tree (fn->decl); rhs = get_function_part_constraint (fi, ~0); - rhs.type = ADDRESSOF; + rhs.type = SCALAR; } else { rhs.var = nonlocal_id; - rhs.type = ADDRESSOF; + rhs.type = SCALAR; rhs.offset = 0; } FOR_EACH_VEC_ELT (lhsc, i, lhsp) @@ -2108,6 +2108,21 @@ find_func_aliases_for_call (struct function *fn, gcall *t) && find_func_aliases_for_builtin_call (fn, t)) return; + if (gimple_call_internal_p (t, IFN_VA_ARG) + && gimple_call_lhs (t)) + { + tree valist = gimple_call_arg (t, 0); + auto_vec<ce_s, 1> rhsc, lhsc; + get_constraint_for_rhs (valist, &rhsc); + do_deref (&rhsc); + get_constraint_for (gimple_call_lhs (t), &lhsc); + process_all_all_constraints (lhsc, rhsc); + /* va_list is used and clobbered. */ + make_constraint_to (get_call_use_vi (t)->id, valist); + make_constraint_to (get_call_clobber_vi (t)->id, valist); + return; + } + if (gimple_call_internal_p (t, IFN_DEFERRED_INIT)) return; diff --git a/gcc/testsuite/g++.target/i386/pr99679-1.C b/gcc/testsuite/g++.target/i386/pr99679-1.C index 36640a4e0a12..d3cd45b5d557 100644 --- a/gcc/testsuite/g++.target/i386/pr99679-1.C +++ b/gcc/testsuite/g++.target/i386/pr99679-1.C @@ -14,4 +14,4 @@ foo (int x, ...) ld = va_arg (ap, long double); if (ld) abort (); -} // { dg-error "x87 register return with x87 disabled" "" { target { ! ia32 } } } +} diff --git a/gcc/testsuite/g++.target/i386/pr99679-2.C b/gcc/testsuite/g++.target/i386/pr99679-2.C index cbd3c4958db8..2773b29470a7 100644 --- a/gcc/testsuite/g++.target/i386/pr99679-2.C +++ b/gcc/testsuite/g++.target/i386/pr99679-2.C @@ -14,4 +14,4 @@ foo (int x, ...) ld = va_arg (ap, double); // { dg-error "SSE register argument with SSE disabled" "" { target { ! ia32 } } } if (ld) abort (); -} // { dg-error "SSE register return with SSE disabled" "" { target { ! ia32 } } } +} diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-pta-20.c b/gcc/testsuite/gcc.dg/ipa/ipa-pta-20.c new file mode 100644 index 000000000000..694a7c3b53a5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/ipa-pta-20.c @@ -0,0 +1,33 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -fipa-pta -fdump-ipa-pta2-details" } */ + +#include <stdarg.h> + +static int __attribute__((noinline, noclone)) q (int n, ...) +{ + va_list va; + va_start (va, n); + int *a = va_arg (va, int *); + int *b = va_arg (va, int *); + va_end (va); + return *a + *b; +} + +static int __attribute__((noinline, noclone)) foo (int (*p)(int, ...)) +{ + int i = 1, j = 3; + return p(2, &i, &j); +} + +int main() +{ + if (foo (q) != 4) + __builtin_abort (); + return 0; +} + +/* Verify we properly handle variadic arguments for indirect calls and + .VA_ARG properly accesses only the variadic part. */ + +/* { dg-final { scan-ipa-dump "a_\[0-9\]\+ = { i j }" "pta2" } } */ +/* { dg-final { scan-ipa-dump "b_\[0-9\]\+ = { i j }" "pta2" } } */
