On Thu, 2 Nov 2017, Richard Biener wrote:
On Wed, Nov 1, 2017 at 12:47 PM, Marc Glisse <marc.gli...@inria.fr> wrote:
Hello,
just a little tweak to that transformation. There is some overlap between
the 2 versions, but it seemed easier to handle the NOP case (including the
case without convert and the vector case) separately from the narrowing /
sign-extending scalar integer case.
At some point it would be good to have fold_negate_expr call
generic_simplify so we could remove some transformations from fold-const.c.
Bootstrap+regtest on powerpc64le-unknown-linux-gnu.
+ (negate (convert (negate @1)))
+ (if (INTEGRAL_TYPE_P (type)
+ && (TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (@1))
+ || (!TYPE_UNSIGNED (TREE_TYPE (@1))
+ && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@1))))
+ && !TYPE_OVERFLOW_SANITIZED (type)
+ && !TYPE_OVERFLOW_SANITIZED (TREE_TYPE (@1)))
so I don't understand this fully -- a widening conversion is ok only for
signed types with undefined overflow? How does overflow come into play
here at all?
Sign-extension is ok, as long as negate does what one expects. For
INT_MIN, that's not the case.
Consider -(long)(-INT_MIN). -INT_MIN is INT_MIN, cast to long it remains
negative, and the final value is positive (assuming long is larger than
int), while (long)INT_MIN is negative.
Undefined overflow allows us to assume that X is not INT_MIN. I could
instead query VRP (and teach VRP that NEGATE_EXPR of VARYING has range
[-INT_MAX,INT_MAX] with undefined overflow), but that seems a bit
overkill.
The testcase doesn't tell ...
Probably I should add a second testcase with cases that must not be
simplified. Maybe even a runtime test for INT_MIN...
For floats eliding any conversion should be ok if not flag_rounding_math
and flag_unsafe_math_optimizations (we remove a rounding step)?
I was leaving that for another time (currently this is handled differently
in fold-const.c), but ok.
For true floats (not fixed point), any extension seems fine, and narrowing
indeed requires !HONOR_SIGN_DEPENDENT_ROUNDING (on the smaller type). It
isn't clear to me that we need flag_unsafe_math_optimizations, with
round-to-nearest -(float)(-dbl) does look equivalent to (float)dbl.
I'll post a new patch with floats and more testcases when I get the time.
--
Marc Glisse