On 07/02/2017 11:03 AM, Yuri Gribov wrote:
Hi all,
This is initial patch for
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57371 . Per Joseph's
suggestion it optimizes
(float)lhs CMP rhs
(double)lhs CMP rhs
to
lhs CMP (typeof(x))rhs
whenever typeof(x) can be precisely represented by floating-point type
(e.g. short by float or int by double) and rhs can be precisely
represented by typeof(x).
Bootstrapped/regtested on x64. Ok for trunk?
I'd like to extend this further in follow-up patches:
1) fold always-false/always-true comparisons e.g.
short x;
(float)x > INT16_MAX; // Always false
2) get rid of cast in comparisons with zero regardless of typeof(lhs)
when -fno-trapping-math:
(float_or_double)lhs CMP 0
-Y
pr57371-1.patch
2017-07-02 Yury Gribov <tetra2005@gmail.com>
PR tree-optimization/57371
* match.pd: New pattern.
* testsuite/gcc.dg/pr57371-1.c: New test.
* testsuite/gcc.dg/pr57371-2.c: New test.
diff -rupN gcc/gcc/match.pd gcc-57371/gcc/match.pd
--- gcc/gcc/match.pd 2017-06-29 21:14:57.000000000 +0200
+++ gcc-57371/gcc/match.pd 2017-07-01 09:08:04.000000000 +0200
@@ -2802,7 +2802,35 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(simplify
(cmp (sq @0) (sq @1))
(if (! HONOR_NANS (@0))
- (cmp @0 @1))))))
+ (cmp @0 @1)))))
+
+ /* Get rid of float cast in
+ (float_type)N CMP M
+ if N and M are within the range explicitly representable
+ by float type.
+
+ TODO: fold always true/false comparisons if M is outside valid range. */
+ (simplify
+ (cmp (float @0) REAL_CST@1)
+ (if (SCALAR_FLOAT_TYPE_P (TREE_TYPE (@1)))
+ (with
+ {
+ tree itype = TREE_TYPE (@0);
+
+ const real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (@1)));
+
+ const REAL_VALUE_TYPE *rhs = TREE_REAL_CST_PTR (@1);
+ bool not_rhs_int_p = false;
+ wide_int rhs_int = real_to_integer (rhs, ¬_rhs_int_p, TYPE_PRECISION (itype));
+ }
+ (if (!not_rhs_int_p
+ && !(TYPE_UNSIGNED (itype) && real_isneg (rhs))
+ && wi::ge_p (rhs_int, wi::min_value (itype), TYPE_SIGN (itype))
+ && wi::le_p (rhs_int, wi::max_value (itype), TYPE_SIGN (itype))
+ && TYPE_PRECISION (itype) <= significand_size (fmt))
+ (cmp @0 { wide_int_to_tree (itype, rhs_int); })
+ ))))
+)
Seems like a nit, but instead of "not_rhs_int_p" use "fail" or something
like that. That makes it easier to mentally parse the conditional which
uses the result.
What happens if @0 is a floating point type? Based on the variable name
"itype" and passing TYPE_PRECISION (itype) to real_to_integer, it seems
like you're expecting @0 to be an integer. If so, you should verify
that it really is an integer type. Seems like a good thing to verify
with tests as well.