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] PR middle-end/11968: Remove confusing comment


The following patch is my proposed resolution to PR middle-end/11968,
which is targeted for version 3.4.  The PR is caused by a misleading
comment in expr.c.  As far as I can tell (HJ hasn't responded to my
e-mails), the bug is hypothetical, there's no known failure, which is
why there isn't an example piece of code attached to the PR that produces
incorrect results, or even a host or target system specified in the PR.

Particularly, confusing is that the problematic comment in expand_expr
discusses when it is reasonable/possible to apply distributivity to
turn (X+C1)*C2 into X*C2 + C1*C2.  The confusion is that expand_expr
isn't responsible for these transformations, they get handled by
either fold-const.c or simplify-rtx.c.  expand_expr simply converts
the tree its given into RTL.  The comment appears in the part of the
code that decides to always generate an explicit MULT rtx for potential
addressing modes, rather than decompose the multiplication into a
sequence of shifts and adds.

Then whilst investigating the case-study expression given in the PR,
"array[x - 0x70000000]", I discovered that GCC doesn't actually apply
the discussed/proposed distributivity optimization when the new constant
expression overflows.

Hence on x86 mainline GCC currently generates:
        subl    $1879048192, %eax
        movl    array(,%eax,4), %eax

whilst, for example, Microsoft's Visual C/C++ compiler generates:
        movl    array+1073741824(,%eax,4), %eax


The secret is that its reasonable to allow the constant calculation
to overflow, when the compilation model specifies wrap-around overflow.
In GCC, this is supported via the -fwrapv command line option, and the
tweak to fold-const.c below, allows us to generate this more efficient
form when that option is specified.


The following patch has been tested on i686-pc-linux-gnu with a complete
"make bootstrap", all languages except treelang, and regression tested
with a top-level "make -k check" with no new failures.  GCC's java
front-end specifies -fwrapv by default, but to test the patch further
I also bootstrapped and regression tested mainline+patch with flag_wrapv
defaulting to true, again without problems or any new failures.

Ok for mainline?


2003-10-31  Roger Sayle  <roger@eyesopen.com>

	PR middle-end/11968
	* expr.c (expand_expr <MULT_EXPR>): Remove inappropriate and
	confusing comment; distributivity isn't handled in expand_expr.
	* fold_const.c (extract_muldiv_1 <PLUS_EXPR>):  Allow overflow
	in distributivity, if wrap-around semantics are specified with
	-fwrapv.


Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.c,v
retrieving revision 1.597
diff -c -3 -p -r1.597 expr.c
*** expr.c	22 Oct 2003 00:18:11 -0000	1.597
--- expr.c	28 Oct 2003 13:53:06 -0000
*************** expand_expr (tree exp, rtx target, enum
*** 7854,7869 ****
  	  op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode,
  			     EXPAND_SUM);

- 	  /* If we knew for certain that this is arithmetic for an array
- 	     reference, and we knew the bounds of the array, then we could
- 	     apply the distributive law across (PLUS X C) for constant C.
- 	     Without such knowledge, we risk overflowing the computation
- 	     when both X and C are large, but X+C isn't.  */
- 	  /* ??? Could perhaps special-case EXP being unsigned and C being
- 	     positive.  In that case we are certain that X+C is no smaller
- 	     than X and so the transformed expression will overflow iff the
- 	     original would have.  */
-
  	  if (GET_CODE (op0) != REG)
  	    op0 = force_operand (op0, NULL_RTX);
  	  if (GET_CODE (op0) != REG)
--- 7854,7859 ----
Index: fold-const.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fold-const.c,v
retrieving revision 1.314
diff -c -3 -p -r1.314 fold-const.c
*** fold-const.c	15 Oct 2003 22:32:27 -0000	1.314
--- fold-const.c	27 Oct 2003 01:20:40 -0000
*************** extract_muldiv_1 (tree t, tree c, enum t
*** 4433,4440 ****
        if (code == MULT_EXPR
  	  || integer_zerop (const_binop (TRUNC_MOD_EXPR, op1, c, 0)))
  	{
! 	  op1 = const_binop (code, convert (ctype, op1), convert (ctype, c), 0);
! 	  if (op1 == 0 || TREE_OVERFLOW (op1))
  	    break;
  	}
        else
--- 4433,4443 ----
        if (code == MULT_EXPR
  	  || integer_zerop (const_binop (TRUNC_MOD_EXPR, op1, c, 0)))
  	{
! 	  op1 = const_binop (code, convert (ctype, op1),
! 			     convert (ctype, c), 0);
! 	  /* We allow the constant to overflow with wrapping semantics.  */
! 	  if (op1 == 0
! 	      || (TREE_OVERFLOW (op1) && ! flag_wrapv))
  	    break;
  	}
        else

Roger
--
Roger Sayle,                         E-mail: roger@eyesopen.com
OpenEye Scientific Software,         WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road,     Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507.         Fax: (+1) 505-473-0833


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