This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: [RFH] negate_expr_p bug?
- From: Roger Sayle <roger at eyesopen dot com>
- To: Richard Guenther <rguenther at suse dot de>
- Cc: gcc at gcc dot gnu dot org
- Date: Mon, 3 Apr 2006 08:47:32 -0600 (MDT)
- Subject: Re: [RFH] negate_expr_p bug?
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.
The real question is whether your new transformation is using
negate_expr_p correctly. It sounds as though you may be introducing
an overflow that wasn't there before, in which case you need to be
testing flag_wrapv && !flag_trapv in the calling clause.
negate_expr_p (t) is simply an efficient version of
temp = fold_build1 (NEGATE_EXPR, type, t);
return TREE_CODE (temp) != NEGATE_EXPR;
and its logic precisely mirrors the equivalent code in negate_expr.
Perhaps some of the logic in fold_negate_const is more appropriate:
temp = fold_negate_const (arg0, type);
return !TREE_OVERFLOW (temp);
I hope this helps.
Roger
--