This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]