This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Fix gcc.c-torture/execute/991202-3.c
- To: gcc-patches at gcc dot gnu dot org
- Subject: Fix gcc.c-torture/execute/991202-3.c
- From: Richard Henderson <rth at cygnus dot com>
- Date: Sun, 19 Mar 2000 03:41:07 -0800
Pretty self-explanitory when youy look at the test case.
We weren't respecting overflow on (x * 65536) / 8 for
type `unsigned int'.
Bootstrapped alphaev56-dec-linux-gnu.
r~
* fold-const.c (extract_muldiv): Apply type check for defined
overflow to multiply as well as divide.
Index: fold-const.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/fold-const.c,v
retrieving revision 1.109
diff -c -p -d -r1.109 fold-const.c
*** fold-const.c 2000/03/16 23:45:28 1.109
--- fold-const.c 2000/03/19 11:26:39
*************** optimize_minmax_comparison (t)
*** 4333,4341 ****
should be used for the computation if wider than our type.
For example, if we are dividing (X * 8) + (Y + 16) by 4, we can return
! (X * 2) + (Y + 4). We also canonicalize (X + 7) * 4 into X * 4 + 28
! in the hope that either the machine has a multiply-accumulate insn
! or that this is part of an addressing calculation.
If we return a non-null expression, it is an equivalent form of the
original computation, but need not be in the original type. */
--- 4333,4345 ----
should be used for the computation if wider than our type.
For example, if we are dividing (X * 8) + (Y + 16) by 4, we can return
! (X * 2) + (Y + 4). We must, however, be assured that either the original
! expression would not overflow or that overflow is undefined for the type
! in the language in question.
!
! We also canonicalize (X + 7) * 4 into X * 4 + 28 in the hope that either
! the machine has a multiply-accumulate insn or that this is part of an
! addressing calculation.
If we return a non-null expression, it is an equivalent form of the
original computation, but need not be in the original type. */
*************** extract_muldiv (t, c, code, wide_type)
*** 4358,4364 ****
/* Don't deal with constants of zero here; they confuse the code below. */
if (integer_zerop (c))
! return 0;
if (TREE_CODE_CLASS (tcode) == '1')
op0 = TREE_OPERAND (t, 0);
--- 4362,4368 ----
/* Don't deal with constants of zero here; they confuse the code below. */
if (integer_zerop (c))
! return NULL_TREE;
if (TREE_CODE_CLASS (tcode) == '1')
op0 = TREE_OPERAND (t, 0);
*************** extract_muldiv (t, c, code, wide_type)
*** 4379,4385 ****
break;
case CONVERT_EXPR: case NON_LVALUE_EXPR: case NOP_EXPR:
-
/* Pass the constant down and see if we can make a simplification. If
we can, replace this expression with the inner simplification for
possible later conversion to our or some other type. */
--- 4383,4388 ----
*************** extract_muldiv (t, c, code, wide_type)
*** 4534,4549 ****
/* If these operations "cancel" each other, we have the main
optimizations of this pass, which occur when either constant is a
multiple of the other, in which case we replace this with either an
! operation or CODE or TCODE. If we have an unsigned type that is
! not a sizetype, we canot do this for division since it will change
! the result if the original computation overflowed. */
! if ((code == MULT_EXPR && tcode == EXACT_DIV_EXPR
! && (! TREE_UNSIGNED (ctype)
! || (TREE_CODE (ctype) == INTEGER_TYPE
! && TYPE_IS_SIZETYPE (ctype))))
! || (tcode == MULT_EXPR
! && code != TRUNC_MOD_EXPR && code != CEIL_MOD_EXPR
! && code != FLOOR_MOD_EXPR && code != ROUND_MOD_EXPR))
{
if (integer_zerop (const_binop (TRUNC_MOD_EXPR, op1, c, 0)))
return fold (build (tcode, ctype, convert (ctype, op0),
--- 4537,4554 ----
/* If these operations "cancel" each other, we have the main
optimizations of this pass, which occur when either constant is a
multiple of the other, in which case we replace this with either an
! operation or CODE or TCODE.
!
! If we have an unsigned type that is not a sizetype, we canot do
! this since it will change the result if the original computation
! overflowed. */
! if ((! TREE_UNSIGNED (ctype)
! || (TREE_CODE (ctype) == INTEGER_TYPE
! && TYPE_IS_SIZETYPE (ctype)))
! && ((code == MULT_EXPR && tcode == EXACT_DIV_EXPR)
! || (tcode == MULT_EXPR
! && code != TRUNC_MOD_EXPR && code != CEIL_MOD_EXPR
! && code != FLOOR_MOD_EXPR && code != ROUND_MOD_EXPR)))
{
if (integer_zerop (const_binop (TRUNC_MOD_EXPR, op1, c, 0)))
return fold (build (tcode, ctype, convert (ctype, op0),