[tree-ssa] Fix PR 14470

Diego Novillo dnovillo@redhat.com
Thu Apr 15 15:38:00 GMT 2004


On Wed, 2004-04-14 at 15:05, Jason Merrill wrote:

> Another way would be to force the array index to be a temporary, which
> seems more correct to me.
>
OK.  I tried that and it worked fine (patch1).  I also tried what you
suggested on IRC (patch2): force the LHS of a postfix expression to be a
minimal lvalue.  This works as well, but forces the gimplifier to turn
't[d]' into pointer arithmetic to obtain a valid lvalue (*T.3 below):

     1.   d = 0;
     2.   d.1 = (unsigned int)d;
     3.   T.2 = d.1 * 4;
     4.   T.3 = &t + T.2;
     5.   T.4 = *T.3;
     6.   d = T.4;
     7.   T.5 = T.4 + 1;
     8.   *T.3 = T.5;
     9.   T.6 = t[0];

The problem I see with this approach is that we end up emitting more
code in the gimplifier.  At -O0, none of that pointer arithmetic is
removed, I guess that's not a big issue with optimization enabled.

However, we end up not optimizing the program as much as before.  In 
particular, after all the usual constant propagation and folding, we get
to this situation:

     1.   d_4 = 0;
     2.   d.1_5 = 0;
     3.   T.2_6 = 0;
     4.   T.3_7 = &t[0];
     5.   #   VUSE <t_3>;
     6.   d_8 = t[0];
     7.   d_9 = d_8;
     8.   T.5_10 = d_8 + 1;
     9.   #   t_13 = VDEF <t_3>;
    10.   t[0] = T.5_10;
    11.   #   VUSE <t_13>;
    12.   T.6_11 = t[0];

Notice how we could not propagate T.5_10 in statement #10 to the RHS of
statement #12.  The reason we fail to propagate it is because 't[0]' in
#10 is "different" from 't[0]' in #12 because the two zeroes are of
different signs.  The one in #10 is 'unsigned int', the other is 'int'.

It all started when the gimplifier converted '&t[d]' into pointer
arithmetic.  We explicitly convert the index into sizetype.  I'm almost
inclined to say that we should make the gimplifier canonicalize array
indices into sizetype (in this test case, all the original ARRAY_REF
index operands where of type 'int').

Thoughts?


Diego.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: patch1
Type: text/x-patch
Size: 831 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20040415/c88fbd53/attachment.bin>
-------------- next part --------------
2004-04-14  Diego Novillo  <dnovillo@redhat.com>

	* gimplify.c (gimplify_self_mod_expr): Use is_gimple_min_lval
	when gimplifying postfix expressions.

Index: gimplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/gimplify.c,v
retrieving revision 1.1.2.148
diff -d -c -p -r1.1.2.148 gimplify.c
*** gimplify.c	8 Apr 2004 02:42:25 -0000	1.1.2.148
--- gimplify.c	14 Apr 2004 21:14:12 -0000
*************** gimplify_self_mod_expr (tree *expr_p, tr
*** 1821,1829 ****
    else
      arith_code = MINUS_EXPR;
  
!   /* Gimplify the LHS into a GIMPLE lvalue.  */
    lvalue = TREE_OPERAND (*expr_p, 0);
!   ret = gimplify_expr (&lvalue, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
    if (ret == GS_ERROR)
      return ret;
  
--- 1821,1836 ----
    else
      arith_code = MINUS_EXPR;
  
!   /* Gimplify the LHS into a GIMPLE lvalue.  For postfix
!      modifications, request a minimal lvalue so that any references
!      inside LHS are done before the modification.  This prevents the
!      problem exposed in gcc.c-torture/execute/20040313-1.c, where
!      'd = t[d]++' was gimplified such that the assignment to 'd' was
!      emitted before the reference to 't[d]'.  */
    lvalue = TREE_OPERAND (*expr_p, 0);
!   ret = gimplify_expr (&lvalue, pre_p, post_p,
! 		       (postfix) ? is_gimple_min_lval : is_gimple_lvalue,
! 		       fb_lvalue);
    if (ret == GS_ERROR)
      return ret;
  


More information about the Gcc-patches mailing list