[PATCH] Fix tree sharing in x86_64 va_arg gimplification (PR target/38123)

Jakub Jelinek jakub@redhat.com
Sat Nov 15 11:50:00 GMT 2008


Hi!

If va_arg's argument is a parameter and both integer and SSE registers are
needed the verifier reports invalid tree sharing of the INDIRECT_REF node
between ap->gp_offset = D.1623; and ap->fp_offset = D.1625;.
While most of the trees generated by ix86_gimplify_va_arg have
unshare_expr called on them by internal_get_tmp_var, that's not the case for
the LHSs.  Normally when va_list is a local variable,
build_va_arg_indirect_ref returns ARRAY_REF of the var and for that
tree_node_can_be_shared is true.  But if it is INDIRECT_REF of a variable or
PARM_DECL, it must not be shared.

The following patch fixes this by making sure the INDIRECT_REF isn't shared
between ap->gp_offset and ap->fp_offset.  I haven't done it for others, as
they are only used on the RHS side and therefore unshared ATM by the
gimplifier, to avoid creating too much garbage.  If the gimplifier is
changed to avoid the unshare_expr, of course this (and many other places)
would need to be changed.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2008-11-15  Jakub Jelinek  <jakub@redhat.com>

	PR target/38123
	* config/i386/i386.c (ix86_gimplify_va_arg): Don't share valist between
	gpr and other COMPONENT_REFs.

	* gcc.c-torture/compile/pr38123.c: New test.

--- gcc/config/i386/i386.c.jj	2008-11-05 11:21:12.000000000 +0100
+++ gcc/config/i386/i386.c	2008-11-15 11:02:26.000000000 +0100
@@ -6579,8 +6579,9 @@ ix86_gimplify_va_arg (tree valist, tree 
   f_ovf = TREE_CHAIN (f_fpr);
   f_sav = TREE_CHAIN (f_ovf);
 
+  gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr),
+		build_va_arg_indirect_ref (valist), f_gpr, NULL_TREE);
   valist = build_va_arg_indirect_ref (valist);
-  gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
   fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
   ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
   sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
--- gcc/testsuite/gcc.c-torture/compile/pr38123.c.jj	2008-11-15 11:05:55.000000000 +0100
+++ gcc/testsuite/gcc.c-torture/compile/pr38123.c	2008-11-15 11:05:38.000000000 +0100
@@ -0,0 +1,13 @@
+/* PR target/38123 */
+
+#include <stdarg.h>
+
+struct S { int i; double d; };
+
+struct S
+test (char *x, va_list ap)
+{
+  struct S s;
+  s = va_arg (ap, struct S);
+  return s;
+}

	Jakub



More information about the Gcc-patches mailing list