This is the mail archive of the gcc@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]

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
--


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