aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYury Gribov <tetra2005@gmail.com>2018-10-12 20:35:20 +0000
committerYury Gribov <ygribov@gcc.gnu.org>2018-10-12 20:35:20 +0000
commite41ec71bd97a1a8eaef40695c7ae9b7f4b1fc819 (patch)
treed9f2071404e3120d9043af8e3800ed5d14c14b8c
parent67aeaded2f8dabe16b4879261c6b6ddda6b53cd2 (diff)
downloadgcc-e41ec71bd97a1a8eaef40695c7ae9b7f4b1fc819.zip
gcc-e41ec71bd97a1a8eaef40695c7ae9b7f4b1fc819.tar.gz
gcc-e41ec71bd97a1a8eaef40695c7ae9b7f4b1fc819.tar.bz2
Add pattern to remove useless float casts in comparisons.
PR middle-end/81376 gcc/ * real.c (format_helper::can_represent_integral_type_p): New function * real.h (format_helper::can_represent_integral_type_p): Ditto. * match.pd: New pattern. gcc/testsuite/ * c-c++-common/pr81376.c: New test. * gcc.target/i386/387-ficom-2.c: Update test. * gcc.target/i386/387-ficom-2.c: Ditto. From-SVN: r265131
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/match.pd35
-rw-r--r--gcc/real.c13
-rw-r--r--gcc/real.h1
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/c-c++-common/pr81376.c48
-rw-r--r--gcc/testsuite/gcc.target/i386/387-ficom-1.c5
-rw-r--r--gcc/testsuite/gcc.target/i386/387-ficom-2.c5
8 files changed, 110 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1cc85d8..465de40 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2018-10-12 Yury Gribov <tetra2005@gmail.com>
+
+ PR middle-end/81376
+ * real.c (format_helper::can_represent_integral_type_p): New function
+ * real.h (format_helper::can_represent_integral_type_p): Ditto.
+ * match.pd: New pattern.
+
2018-10-12 Alexandre Oliva <oliva@adacore.com>
* configure.ac: Introduce --enable-large-address-aware
diff --git a/gcc/match.pd b/gcc/match.pd
index 94fbab8..b36d7cc 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -3400,6 +3400,32 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(if (! HONOR_NANS (@0))
(cmp @0 @1))))))
+/* Optimize various special cases of (FTYPE) N CMP (FTYPE) M. */
+(for cmp (tcc_comparison)
+ (simplify
+ (cmp (float@0 @1) (float @2))
+ (if (SCALAR_FLOAT_TYPE_P (TREE_TYPE (@0))
+ && ! DECIMAL_FLOAT_TYPE_P (TREE_TYPE (@0)))
+ (with
+ {
+ format_helper fmt (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (@0))));
+ tree type1 = TREE_TYPE (@1);
+ bool type1_signed_p = TYPE_SIGN (type1) == SIGNED;
+ tree type2 = TREE_TYPE (@2);
+ bool type2_signed_p = TYPE_SIGN (type2) == SIGNED;
+ }
+ (if (fmt.can_represent_integral_type_p (type1)
+ && fmt.can_represent_integral_type_p (type2))
+ (if (TYPE_PRECISION (type1) > TYPE_PRECISION (type2)
+ && type1_signed_p >= type2_signed_p)
+ (cmp @1 (convert @2))
+ (if (TYPE_PRECISION (type1) < TYPE_PRECISION (type2)
+ && type1_signed_p <= type2_signed_p)
+ (cmp (convert:type2 @1) @2)
+ (if (TYPE_PRECISION (type1) == TYPE_PRECISION (type2)
+ && type1_signed_p == type2_signed_p)
+ (cmp @1 @2)))))))))
+
/* Optimize various special cases of (FTYPE) N CMP CST. */
(for cmp (lt le eq ne ge gt)
icmp (le le eq ne ge ge)
@@ -3410,7 +3436,6 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(with
{
tree itype = TREE_TYPE (@0);
- signop isign = TYPE_SIGN (itype);
format_helper fmt (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (@1))));
const REAL_VALUE_TYPE *cst = TREE_REAL_CST_PTR (@1);
/* Be careful to preserve any potential exceptions due to
@@ -3420,17 +3445,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
bool exception_p
= real_isnan (cst) && (cst->signalling
|| (cmp != EQ_EXPR && cmp != NE_EXPR));
- /* INT?_MIN is power-of-two so it takes
- only one mantissa bit. */
- bool signed_p = isign == SIGNED;
- bool itype_fits_ftype_p
- = TYPE_PRECISION (itype) - signed_p <= significand_size (fmt);
}
/* TODO: allow non-fitting itype and SNaNs when
-fno-trapping-math. */
- (if (itype_fits_ftype_p && ! exception_p)
+ (if (fmt.can_represent_integral_type_p (itype) && ! exception_p)
(with
{
+ signop isign = TYPE_SIGN (itype);
REAL_VALUE_TYPE imin, imax;
real_from_integer (&imin, fmt, wi::min_value (itype), isign);
real_from_integer (&imax, fmt, wi::max_value (itype), isign);
diff --git a/gcc/real.c b/gcc/real.c
index 51f8fd5..0e2da25 100644
--- a/gcc/real.c
+++ b/gcc/real.c
@@ -5176,6 +5176,19 @@ get_max_float (const struct real_format *fmt, char *buf, size_t len)
gcc_assert (strlen (buf) < len);
}
+/* True if all values of integral type can be represented
+ by this floating-point type exactly. */
+
+bool format_helper::can_represent_integral_type_p (tree type) const
+{
+ gcc_assert (! decimal_p () && INTEGRAL_TYPE_P (type));
+
+ /* INT?_MIN is power-of-two so it takes
+ only one mantissa bit. */
+ bool signed_p = TYPE_SIGN (type) == SIGNED;
+ return TYPE_PRECISION (type) - signed_p <= significand_size (*this);
+}
+
/* True if mode M has a NaN representation and
the treatment of NaN operands is important. */
diff --git a/gcc/real.h b/gcc/real.h
index 561d0fd..cd557b3 100644
--- a/gcc/real.h
+++ b/gcc/real.h
@@ -216,6 +216,7 @@ public:
operator const real_format *() const { return m_format; }
bool decimal_p () const { return m_format && m_format->b == 10; }
+ bool can_represent_integral_type_p (tree type) const;
private:
const real_format *m_format;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 3604fe6..d5bdf78 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2018-10-12 Yury Gribov <tetra2005@gmail.com>
+
+ PR middle-end/81376
+ * c-c++-common/pr81376.c: New test.
+ * gcc.target/i386/387-ficom-2.c: Update test.
+ * gcc.target/i386/387-ficom-2.c: Ditto.
+
2018-10-12 Tobias Burnus <burnus@net-b.de>
PR fortran/87597
diff --git a/gcc/testsuite/c-c++-common/pr81376.c b/gcc/testsuite/c-c++-common/pr81376.c
new file mode 100644
index 0000000..e67f41e
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr81376.c
@@ -0,0 +1,48 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-original" } */
+
+typedef double c_t;
+typedef int a_t;
+int f(a_t a1, a_t a2) {
+ return (c_t) a1 < (c_t) a2;
+ /* { dg-final { scan-tree-dump "return (<retval> = )?a1 < a2" "original" } } */
+}
+
+void f1(short a, short b)
+{
+ volatile int s_s;
+ s_s = (float) a < (float) b;
+ /* { dg-final { scan-tree-dump "s_s = a < b" "original" } } */
+}
+
+void f2(unsigned short a, unsigned short b)
+{
+ volatile int us_us;
+ us_us = (float) a < (float) b;
+ /* { dg-final { scan-tree-dump "us_us = a < b" "original" } } */
+}
+
+/* We don't optimize here because neither of integral types is
+ subset of the other. */
+void f3(unsigned short a, short b)
+{
+ volatile int us_s;
+ us_s = (float) a < (float) b;
+ /* { dg-final { scan-tree-dump "us_s = \\(float\\) a < \\(float\\) b" "original" } } */
+}
+
+void f4(unsigned short a, int b)
+{
+ volatile int us_i;
+ us_i = (double) a < (double) b;
+ /* { dg-final { scan-tree-dump "us_i = \\(int\\) a < b" "original" } } */
+}
+
+/* We don't optimize here because neither of integral types is
+ subset of the other. */
+void f5(short a, unsigned int b)
+{
+ volatile int s_ui;
+ s_ui = (double) a < (double) b;
+ /* { dg-final { scan-tree-dump "s_ui = \\(double\\) a < \\(double\\) b" "original" } } */
+}
diff --git a/gcc/testsuite/gcc.target/i386/387-ficom-1.c b/gcc/testsuite/gcc.target/i386/387-ficom-1.c
index 3256988..8cef82d 100644
--- a/gcc/testsuite/gcc.target/i386/387-ficom-1.c
+++ b/gcc/testsuite/gcc.target/i386/387-ficom-1.c
@@ -37,5 +37,6 @@ int test_ld_i (int x)
return (long double)i != x;
}
-/* { dg-final { scan-assembler-times "ficomp\[s\t\]" 3 } } */
-/* { dg-final { scan-assembler-times "ficompl" 3 } } */
+/* { dg-final { scan-assembler-times "cmpw\[s\t\]" 3 } } */
+/* { dg-final { scan-assembler-times "ficompl" 1 } } */
+/* { dg-final { scan-assembler-times "cmpl" 2 } } */
diff --git a/gcc/testsuite/gcc.target/i386/387-ficom-2.c b/gcc/testsuite/gcc.target/i386/387-ficom-2.c
index d528368..46c4b55 100644
--- a/gcc/testsuite/gcc.target/i386/387-ficom-2.c
+++ b/gcc/testsuite/gcc.target/i386/387-ficom-2.c
@@ -5,5 +5,6 @@
#include "387-ficom-1.c"
-/* { dg-final { scan-assembler-times "ficomp\[s\t\]" 3 } } */
-/* { dg-final { scan-assembler-times "ficompl" 3 } } */
+/* { dg-final { scan-assembler-times "cmpw\[s\t\]" 3 } } */
+/* { dg-final { scan-assembler-times "ficompl" 1 } } */
+/* { dg-final { scan-assembler-times "cmpl" 2 } } */