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

Reply via email to