On Mon, 3 Apr 2006, Roger Sayle wrote:

> 
> On Mon, 3 Apr 2006, Richard Guenther wrote:
> >
> >              || (TREE_CODE (type) == INTEGER_TYPE
> >              && (TREE_CODE (arg1) == INTEGER_CST
> >                  || TYPE_UNSIGNED (type)
> >                  || (flag_wrapv && !flag_trapv)))
> >
> > Does this sound reasonable?
> 
> Yes, this sounds reasonable.  It was not the negate_expr_p call
> that's causing your problems but the overly restrictive guard
> on this transformation.  Let me know the results of a bootstrap
> and regression test in case that points out something I've missed.

It didn't show up anything but some missed optimization that is because
a zero with overflow flag is not integer_zerop, but I see you are in
process of fixing this.  Other than that I'm a bit nervous if we both
introduce signed overflow because it is undefined and at the same time
pretend it doesn't happen because it is undefined.  Like given

   a - INT_MIN < a
-> a + INT_MIN < a
-> INT_MIN < 0

which is true, even for a == INT_MIN for which the original expression
didn't contain an overflow.  I.e. the following aborts

#include <limits.h>

extern void abort(void);

int foo(int a)
{
  return a - INT_MIN < a;
}

int main()
{
  if (foo(INT_MIN))
    abort ();
  return 0;
}

because we fold the comparison to 1.  In an intermediate folding we have

  return a + -080000000 < a;

with
 <integer_cst 0xb7e08ee8 type <integer_type 0xb7d86284 int> constant 
invariant public static overflow -2147483648>

and we continue folding via

      /* Transform comparisons of the form X +- C CMP X.  */
      if ((TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == 
MINUS_EXPR)
          && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0)
          && ((TREE_CODE (TREE_OPERAND (arg0, 1)) == REAL_CST
               && !HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0))))
              || (TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
                  && !TYPE_UNSIGNED (TREE_TYPE (arg1))
                  && !(flag_wrapv || flag_trapv))))
        {
...

which doesn't check for overflowed constants (you think the middle-end
shouldn't care for the overflow flag here, yes?) and folds the thing
to true.  Note that my proposed patch for folding of X +- CST CMP Y +- CST
_does_ check for overflow flag on CSTs (unnecessarily?).

So, I'm a bit confused as of the whole singed overflow undefined-ness.

Richard.

Reply via email to