address@hidden (Richard Kenner) writes:
 > Here's an example from the intprops module of gnulib.

 These are interesting case.

 Note that all the computations are constantfolded.

 And I think this points the fact that we can "have our cake and eat it too"
 in many cases. Everything we're seeing points to the fact that the cases
 where assuming undefined behavior for overflow will help optimizations are
 cases where few if any sane programmers would write the code depending on
 wrap semantics (e.g., loop variables). And nearly all the cases where wrap
 semantics are expected (e.g., the above) are such that there's no reasonable
 optimization benefit in assuming they're undefined.

 Take constant folding: if we were pendantic about it, we could say, "this
 folded expression overflows and so is undefined, so let's set its value to be
 whatever constant would yield the most efficient code in that case".

 Such behavior would be standardcompliant, but as unfriendly as possible
 because it wouldn't "optimize" any real code, just break common idioms.
 I doubt anybody would suggest not implementing wrapping semantics in
 constant folding.
As I'm looking into the VRP and CHREC codes to implement the
Wundefined warning, I came across this:
/* Wrapper around int_const_binop. If the operation overflows and we
are not using wrapping arithmetic, then adjust the result to be
INF or +INF depending on CODE, VAL1 and VAL2. */
static inline tree
vrp_int_const_binop (enum tree_code code, tree val1, tree val2)
{
/* ... */
else if (TREE_OVERFLOW (res)
&& !TREE_OVERFLOW (val1)
&& !TREE_OVERFLOW (val2))
{
/* If the operation overflowed but neither VAL1 nor VAL2 are
overflown, return INF or +INF depending on the operation
and the combination of signs of the operands. */
int sgn1 = tree_int_cst_sgn (val1);
int sgn2 = tree_int_cst_sgn (val2);
/* Notice that we only need to handle the restricted set of
operations handled by extract_range_from_binary_expr.
Among them, only multiplication, addition and subtraction
can yield overflow without overflown operands because we
are working with integral types only... except in the
case VAL1 = INF and VAL2 = 1 which overflows to +INF
for division too. */
/* For multiplication, the sign of the overflow is given
by the comparison of the signs of the operands. */
if ((code == MULT_EXPR && sgn1 == sgn2)
/* For addition, the operands must be of the same sign
to yield an overflow. Its sign is therefore that
of one of the operands, for example the first. */
 (code == PLUS_EXPR && sgn1 > 0)
/* For subtraction, the operands must be of different
signs to yield an overflow. Its sign is therefore
that of the first operand or the opposite of that
of the second operand. A first operand of 0 counts
as positive here, for the corner case 0  (INF),
which overflows, but must yield +INF. */
 (code == MINUS_EXPR && sgn1 >= 0)
/* For division, the only case is INF / 1 = +INF. */
 code == TRUNC_DIV_EXPR
 code == FLOOR_DIV_EXPR
 code == CEIL_DIV_EXPR
 code == EXACT_DIV_EXPR
 code == ROUND_DIV_EXPR)
return TYPE_MAX_VALUE (TREE_TYPE (res));
else
return TYPE_MIN_VALUE (TREE_TYPE (res));
}
/* ... */
}
What would you suggest this function to do, based on your comments?