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]

Fix gcc.c-torture/execute/991202-3.c


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),

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