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.
Bootstrapped and tested on x86_64-unknown-linux-gnu, LTO bootstrapped
with IPA PTA enabled and no testsuite differences when testing with
IPA PTA enabled.
Pushed.
* 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++.dg/target/pr99679-1.C: Remove expected error.
* g++.dg/target/pr99679-2.C: Likewise.
---
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(-)
create mode 100644 gcc/testsuite/gcc.dg/ipa/ipa-pta-20.c
diff --git a/gcc/gimple-ssa-pta-constraints.cc
b/gcc/gimple-ssa-pta-constraints.cc
index dec3b2f6f14..a377b891d80 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 36640a4e0a1..d3cd45b5d55 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 cbd3c4958db..2773b29470a 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 00000000000..694a7c3b53a
--- /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" } } */
--
2.51.0