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 PR28230, wrong code with VRP and -fwrapv


This fixes PR28230, VRP was interestingly thinking that -frwapv is
somehow special for combining value ranges in general.  But of course just
"ignoring" overflow in [0, 65000] + [0, +Inf] is not yielding any
useful value range.

The fix for this is to move the flag_wrapv handling to the unsigned
case.

Bootstrapped and tested on x86_64-unknown-linux-gnu.

Ok for mainline?

Thanks,
Richard.

:ADDPATCH middle-end:

2006-10-10  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/28230
	* tree-vrp.c (vrp_int_const_binop): Move flag_wrapv handling
	to the correct place.

	* gcc.dg/torture/pr28230.c: New testcase.


Index: tree-vrp.c
===================================================================
*** tree-vrp.c	(revision 117629)
--- tree-vrp.c	(working copy)
*************** vrp_int_const_binop (enum tree_code code
*** 1235,1248 ****
  {
    tree res;
  
!   if (flag_wrapv)
!     return int_const_binop (code, val1, val2, 0);
  
    /* If we are not using wrapping arithmetic, operate symbolically
       on -INF and +INF.  */
!   res = int_const_binop (code, val1, val2, 0);
! 
!   if (TYPE_UNSIGNED (TREE_TYPE (val1)))
      {
        int checkz = compare_values (res, val1);
        bool overflow = false;
--- 1235,1246 ----
  {
    tree res;
  
!   res = int_const_binop (code, val1, val2, 0);
  
    /* If we are not using wrapping arithmetic, operate symbolically
       on -INF and +INF.  */
!   if (TYPE_UNSIGNED (TREE_TYPE (val1))
!       || flag_wrapv)
      {
        int checkz = compare_values (res, val1);
        bool overflow = false;

/* { dg-do run } */
/* { dg-options "-fwrapv" } */

void foo( unsigned long long bb, unsigned short tn, unsigned e, unsigned* w );
void foo( unsigned long long bb, unsigned short tn, unsigned e, unsigned* w )
{
        unsigned n = tn + bb;
        do {
                e = (e > n) ? e : *w;
                n -= (e > n) ? n : e;
                if (*w)
                        *w = 0;
        } while ( n );
}
int main()
{
        unsigned w = 0;
        foo( 0, 0, 0, &w );
        return 0;
}


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