On 08/18/2015 09:10 AM, Richard Sandiford wrote:
simplify_unary_operation_1 has:

       /*  (float_truncate (float x)) is (float x)  */
       if ((GET_CODE (op) == FLOAT || GET_CODE (op) == UNSIGNED_FLOAT)
         && (flag_unsafe_math_optimizations
             || (SCALAR_FLOAT_MODE_P (GET_MODE (op))
                 && ((unsigned)significand_size (GET_MODE (op))
                     >= (GET_MODE_PRECISION (GET_MODE (XEXP (op, 0)))
                         - num_sign_bit_copies (XEXP (op, 0),
                                                GET_MODE (XEXP (op, 0))))))))
        return simplify_gen_unary (GET_CODE (op), mode,
                                  XEXP (op, 0),
                                  GET_MODE (XEXP (op, 0)));

where the !flag_unsafe_math_optimizations alternative is trying to check
that the int->float conversion is exact.  Using num_sign_bit_copies is
only correct for signed inputs though; for UNSIGNED_FLOAT we need to
check whether the upper bits are zero.

Also, for both cases we can discount known trailing zeros.  It might not
be a particularly exciting thing to check on its own, but since we're
calling nonzero_bits for UNSIGNED_FLOAT anyway...  It does mean calling
nonzero_bits as well as num_sign_bit_copies for FLOAT, but this is very
rarely executed code.

I noticed this while trying to generalise some of the simplify-rtx.c
patterns so that they applied to vectors as well as scalars.  (Dave's
recent GET_MODE_INNER changes make this easier and cheaper to do.)
The patch does that here too for completeness.  I think any code
in simplify-rtx.c that handles GET_MODE_PRECISION for scalars only
is suspect.

Tested on x86_64-linux-gnu and aarch64-linux-gnu.  OK to install?

This is a gcc 6 regression so no backport is needed.

Thanks,
Richard


gcc/
        PR rtl-optimization/67218
        * simplify-rtx.c (exact_int_to_float_conversion_p): New function.
        (simplify_unary_operation_1): Use it.

gcc/testsuite/
        PR rtl-optimization/67218
        * gcc.c-torture/execute/ieee/pr67218.c,
        gcc.target/aarch64/fcvt_int_float_double1.c,
        gcc.target/aarch64/fcvt_int_float_double2.c,
        gcc.target/aarch64/fcvt_int_float_double3.c,
        gcc.target/aarch64/fcvt_int_float_double4.c,
        gcc.target/aarch64/fcvt_uint_float_double1.c,
        gcc.target/aarch64/fcvt_uint_float_double2.c,
        gcc.target/aarch64/fcvt_uint_float_double3.c,
        gcc.target/aarch64/fcvt_uint_float_double4.c: New tests.
OK.  Thanks!

Jeff

Reply via email to