[gcc r17-2211] Improve variadic function call handling in PTA

Richard Biener via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
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" } } */
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.