committed as revision 205448 to trunk.
committed as revision 205455 to wide-int branch.
On 11/27/2013 05:50 AM, Richard Biener wrote:
On Tue, Nov 26, 2013 at 5:33 PM, Kenneth Zadeck
<zad...@naturalbridge.com> wrote:
Richi,

patch ping
Ok.

Thanks,
Richard.

also two more pieces of information.    With further testing, this seems to
fix

Tests that now work, but didn't before:
===============
ext/random/hypergeometric_distribution/operators/values.cc (test for excess
errors)

New tests that PASS:

ext/random/hypergeometric_distribution/operators/values.cc execution test
================

also, the corresponding frag for fold-const.c on the wide-int branch will
look like
================
Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c    (revision 205224)
+++ gcc/fold-const.c    (working copy)
@@ -1030,51 +1030,51 @@ int_const_binop_1 (enum tree_code code,

      case TRUNC_DIV_EXPR:
      case EXACT_DIV_EXPR:
-      res = wi::div_trunc (arg1, arg2, sign, &overflow);
-      if (overflow)
+      if (arg2 == 0)
      return NULL_TREE;
+      res = wi::div_trunc (arg1, arg2, sign, &overflow);
        break;

      case FLOOR_DIV_EXPR:
-      res = wi::div_floor (arg1, arg2, sign, &overflow);
-      if (overflow)
+      if (arg2 == 0)
      return NULL_TREE;
+      res = wi::div_floor (arg1, arg2, sign, &overflow);
        break;

      case CEIL_DIV_EXPR:
-      res = wi::div_ceil (arg1, arg2, sign, &overflow);
-      if (overflow)
+      if (arg2 == 0)
      return NULL_TREE;
+      res = wi::div_ceil (arg1, arg2, sign, &overflow);
        break;

      case ROUND_DIV_EXPR:
-      res = wi::div_round (arg1, arg2, sign, &overflow);
-      if (overflow)
+      if (arg2 == 0)
      return NULL_TREE;
+      res = wi::div_round (arg1, arg2, sign, &overflow);
        break;

      case TRUNC_MOD_EXPR:
-      res = wi::mod_trunc (arg1, arg2, sign, &overflow);
-      if (overflow)
+      if (arg2 == 0)
      return NULL_TREE;
+      res = wi::mod_trunc (arg1, arg2, sign, &overflow);
        break;

      case FLOOR_MOD_EXPR:
-      res = wi::mod_floor (arg1, arg2, sign, &overflow);
-      if (overflow)
+      if (arg2 == 0)
      return NULL_TREE;
+      res = wi::mod_floor (arg1, arg2, sign, &overflow);
        break;

      case CEIL_MOD_EXPR:
-      res = wi::mod_ceil (arg1, arg2, sign, &overflow);
-      if (overflow)
+      if (arg2 == 0)
      return NULL_TREE;
+      res = wi::mod_ceil (arg1, arg2, sign, &overflow);
        break;

      case ROUND_MOD_EXPR:
-      res = wi::mod_round (arg1, arg2, sign, &overflow);
-      if (overflow)
+      if (arg2 == 0)
      return NULL_TREE;
+      res = wi::mod_round (arg1, arg2, sign, &overflow);
        break;

      case MIN_EXPR:

================

On 11/20/2013 06:31 PM, Kenneth Zadeck wrote:
On 11/13/2013 04:59 AM, Richard Biener wrote:
On Tue, Nov 12, 2013 at 5:43 PM, Kenneth Zadeck
<zad...@naturalbridge.com> wrote:
On 11/12/2013 11:27 AM, Joseph S. Myers wrote:
On Tue, 12 Nov 2013, Kenneth Zadeck wrote:

Richi,

i am having a little trouble putting this back the way that you want.
The
issue is rem.
what is supposed to happen for INT_MIN % -1?

I would assume because i am failing the last case of
gcc.dg/c90-const-expr-8.c
that INT_MIN %-1 should not overflow even if INT_MIN / -1 does.
however,
Given the conclusion in C11 that a%b should be considered undefined if
a/b
is not representable, I think it's reasonable to say INT_MIN % -1
*should*
be considered to overflow (for all C standard versions) (and bug 30484
is
only a bug for -fwrapv).

however, my local question is what do we want the api to be
int-const-binop-1?    The existing behavior seems to be that at least
for
common modes this function silently returns 0 and it is up to the front
ends
to put their own spin on it.
For wide-int you create 1:1 the behavior of current trunk (if a change of
behavior in TImode is not tested in the testsuite then you can ignore
that).
Whatever change you do to semantics of functions you do separately
from wide-int (preferably first on trunk, or at your choice after the
wide-int
merge).

For this case in question I'd say a % -1 should return 0, but for
INT_MIN % -1 that 0 should have TREE_OVERFLOW set (and
thus you need to adjust that c90-const-expr-8.c testcase).

Richard.

kenny
richi,
I have done this exactly as you suggested.   bootstrapped and regression
tested on x86-64.

2013-11-20  Kenneth Zadeck  <zad...@naturalbridge.com>

     * fold-const.c
     (int_const_binop_1): Make INT_MIN % -1 return 0 with the overflow
     bit set.


2013-11-20  Kenneth Zadeck  <zad...@naturalbridge.com>

     * gcc.dg/c90-const-expr-8.c: Look for overflow on INT_MIN % -1.
     * gcc.dg/c99-const-expr-8.c: Look for overflow on INT_MIN % -1.

ok to commit?

kenny


Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c	(revision 205447)
+++ gcc/fold-const.c	(working copy)
@@ -1110,7 +1110,22 @@ int_const_binop_1 (enum tree_code code,
     case ROUND_MOD_EXPR:
       if (op2.is_zero ())
 	return NULL_TREE;
-      tmp = op1.divmod_with_overflow (op2, uns, code, &res, &overflow);
+
+      /* Check for the case the case of INT_MIN % -1 and return
+       overflow and result = 0.  The TImode case is handled properly
+       in double-int.  */
+      if (TYPE_PRECISION (type) <= HOST_BITS_PER_WIDE_INT 
+	  && !uns
+          && op2.is_minus_one () 
+	  && op1.high == (HOST_WIDE_INT) -1
+	  && (HOST_WIDE_INT) op1.low 
+	  == (((HOST_WIDE_INT)-1) << (TYPE_PRECISION (type) - 1)))
+	{
+	  overflow = 1;
+	  res = double_int_zero;
+	}
+      else
+	tmp = op1.divmod_with_overflow (op2, uns, code, &res, &overflow);
       break;
 
     case MIN_EXPR:
Index: gcc/testsuite/gcc.dg/c90-const-expr-8.c
===================================================================
--- gcc/testsuite/gcc.dg/c90-const-expr-8.c	(revision 205447)
+++ gcc/testsuite/gcc.dg/c90-const-expr-8.c	(working copy)
@@ -23,5 +23,6 @@ enum e {
   /* { dg-error "3:overflow in constant expression" "constant" { target *-*-* } 22 } */
   E6 = 0 * !-INT_MIN, /* { dg-warning "13:integer overflow in expression" } */
   /* { dg-error "8:not an integer constant" "constant" { target *-*-* } 24 } */
-  E7 = INT_MIN % -1 /* Not an overflow.  */
+  E7 = INT_MIN % -1 /* { dg-warning "16:integer overflow in expression" } */
+  /* { dg-error "1:overflow in constant expression" "constant" { target *-*-* } 28 } */
 };
Index: gcc/testsuite/gcc.dg/c99-const-expr-8.c
===================================================================
--- gcc/testsuite/gcc.dg/c99-const-expr-8.c	(revision 205447)
+++ gcc/testsuite/gcc.dg/c99-const-expr-8.c	(working copy)
@@ -23,5 +23,6 @@ enum e {
   /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 22 } */
   E6 = 0 * !-INT_MIN, /* { dg-warning "integer overflow in expression" } */
   /* { dg-error "not an integer constant" "constant" { target *-*-* } 24 } */
-  E7 = INT_MIN % -1 /* Not an overflow.  */
+  E7 = INT_MIN % -1 /* { dg-warning "16:integer overflow in expression" } */
+  /* { dg-error "1:overflow in constant expression" "constant" { target *-*-* } 28 } */
 };

Reply via email to