]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Improve variadic function call handling in PTA
authorRichard Biener <rguenther@suse.de>
Tue, 7 Jul 2026 06:54:45 +0000 (08:54 +0200)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 8 Jul 2026 07:02:35 +0000 (09:02 +0200)
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.

gcc/gimple-ssa-pta-constraints.cc
gcc/testsuite/g++.target/i386/pr99679-1.C
gcc/testsuite/g++.target/i386/pr99679-2.C
gcc/testsuite/gcc.dg/ipa/ipa-pta-20.c [new file with mode: 0644]

index dec3b2f6f14044b104e17c47ee3c833ccac2aa39..a377b891d8025d01097013b49c2060c2704fd12c 100644 (file)
@@ -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;
 
index 36640a4e0a12b3d46e64b2bc1d37cb9dce962122..d3cd45b5d55740d12df170dd3d56366e7d61ac7a 100644 (file)
@@ -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 } } }
+}
index cbd3c4958db878af7e8ea0fcd11e2a840992b315..2773b29470a77ca50bf58f40026b770a9c8bfb5b 100644 (file)
@@ -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 (file)
index 0000000..694a7c3
--- /dev/null
@@ -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" } } */