On Mon, 3 Apr 2006, Roger Sayle wrote:

> 
> On Mon, 3 Apr 2006, Richard Guenther wrote:
> > negate_expr_p currently contains
> > ...
> > where it looks bogus to simply return true for signed types but
> > unset flag_trapv.
> > ...
> > which is bogus as it should read || (!flag_trapv && flag_wrapv) - no?
> > I hit this with a patch to fold A +- CST to A -+ CST for negative CST,
> > which tells me it is ok to negate -INT_MAX.
> 
> I suspect the problem is in the use of negate_expr_p.  This predicate
> is designed for integer constants to check whether it is reasonable to
> evaluate NEG_EXPR at compile-time.
> 
> Hence, fold will/can convert:
> 
> int foo()
> {
>   return -INT_MIN;
> }
> 
> into "return INT_MIN;" during tree-ssa, provided that we don't rely
> on trapping math.  i.e. we take advantage of the undefined behaviour
> of signed types, with or without flag_wrapv.

Hmm, but then, we would be allowed to transform A - -INT_MIN to
A + INT_MIN, correct?

Now, I'm trying to teach fold_binary to transform i - -1 to i + 1 by
adjusting

      /* A - B -> A + (-B) if B is easily negatable.  */
      if (negate_expr_p (arg1)
          && ((FLOAT_TYPE_P (type)
               /* Avoid this transformation if B is a positive REAL_CST.  
*/
               && (TREE_CODE (arg1) != REAL_CST
                   ||  REAL_VALUE_NEGATIVE (TREE_REAL_CST (arg1))))
              || (INTEGRAL_TYPE_P (type) && flag_wrapv && !flag_trapv)))
        return fold_build2 (PLUS_EXPR, type,
                            fold_convert (type, arg0),
                            fold_convert (type, negate_expr (arg1)));

which at the moment does not do that if flag_wrapv is not set.  If your
reasoning is correct, we can simply replace the last line in the condition
with

             || (TREE_CODE (type) == INTEGER_TYPE
                 && (TREE_CODE (arg1) == INTEGER_CST
                     || TYPE_UNSIGNED (type)
                     || (flag_wrapv && !flag_trapv)))

(only do it for INTEGER_TYPE to avoid negating pointer constants)
Now for constants this is always valid due to your reasoning, for unsigned
types anyway and else if flag_wrapv and no trapping v is in effect.

Does this sound reasonable?

Thanks,
Richard.

Reply via email to