diff mbox

Simplify (double)i != 0

Message ID alpine.DEB.2.02.1305251820190.12614@stedding.saclay.inria.fr
State New
Headers show

Commit Message

Marc Glisse May 25, 2013, 5:11 p.m. UTC
Hello,

this patch only handles the simple case where the constant is 0, I'll keep 
the PR open for the more general case. Note that if we split 
flag_trapping_math into no|weak|strict, the test here would be !=strict, 
since we only remove trapping operations.

Passes bootstrap+testsuite on x86_64-linux-gnu.

2013-05-27  Marc Glisse  <marc.glisse@inria.fr>

 	PR tree-optimization/57371
gcc/
 	* fold-const.c (fold_comparison): Fold comparison of a FLOAT_EXPR
 	with 0.

gcc/testsuite/
 	* gcc.dg/pr57371-1.c: New testcase.
 	* gcc.dg/pr57371-2.c: Likewise.
 	* gcc.dg/pr57371-3.c: Likewise.
diff mbox

Patch

Index: fold-const.c
===================================================================
--- fold-const.c	(revision 199323)
+++ fold-const.c	(working copy)
@@ -9362,20 +9362,38 @@  fold_comparison (location_t loc, enum tr
 	    }
 
 	  /* Fold comparisons against infinity.  */
 	  if (REAL_VALUE_ISINF (cst)
 	      && MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg1))))
 	    {
 	      tem = fold_inf_compare (loc, code, type, arg0, arg1);
 	      if (tem != NULL_TREE)
 		return tem;
 	    }
+
+	  /* (double)i CMP 0 is just i CMP 0.  See PR 57371 for how this
+	     can be extended to non-zero constants.  */
+	  if (TREE_CODE (arg0) == FLOAT_EXPR && real_zerop (arg1))
+	    {
+	      tree inner = TREE_OPERAND (arg0, 0);
+	      tree itype = TREE_TYPE (inner);
+	      tree ftype = TREE_TYPE (arg0);
+	      /* If ftype cannot represent exactly all values of itype,
+		 we may have an inexact exception.  If the conversion from
+		 itype to ftype may overflow (unsigned __int128 to float),
+		 we may have an overflow exception.  */
+	      if (!flag_trapping_math
+		  || (unsigned) significand_size (TYPE_MODE (ftype))
+		     >= element_precision (itype) - !TYPE_UNSIGNED (itype))
+		return fold_build2_loc (loc, code, type, inner,
+					build_zero_cst (itype));
+	    }
 	}
 
       /* If this is a comparison of a real constant with a PLUS_EXPR
 	 or a MINUS_EXPR of a real constant, we can convert it into a
 	 comparison with a revised real constant as long as no overflow
 	 occurs when unsafe_math_optimizations are enabled.  */
       if (flag_unsafe_math_optimizations
 	  && TREE_CODE (arg1) == REAL_CST
 	  && (TREE_CODE (arg0) == PLUS_EXPR
 	      || TREE_CODE (arg0) == MINUS_EXPR)
Index: testsuite/gcc.dg/pr57371-3.c
===================================================================
--- testsuite/gcc.dg/pr57371-3.c	(revision 0)
+++ testsuite/gcc.dg/pr57371-3.c	(revision 0)
@@ -0,0 +1,11 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-optimized -ftrapping-math" } */
+
+int f (unsigned long long x)
+{
+  float y = x;
+  return y <= 0;
+}
+
+/* { dg-final { scan-tree-dump "float" "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */

Property changes on: testsuite/gcc.dg/pr57371-3.c
___________________________________________________________________
Added: svn:keywords
   + Author Date Id Revision URL
Added: svn:eol-style
   + native

Index: testsuite/gcc.dg/pr57371-1.c
===================================================================
--- testsuite/gcc.dg/pr57371-1.c	(revision 0)
+++ testsuite/gcc.dg/pr57371-1.c	(revision 0)
@@ -0,0 +1,11 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-optimized -ftrapping-math" } */
+
+int f (char x)
+{
+  long double y = x;
+  return y <= 0;
+}
+
+/* { dg-final { scan-tree-dump-not "double" "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */

Property changes on: testsuite/gcc.dg/pr57371-1.c
___________________________________________________________________
Added: svn:keywords
   + Author Date Id Revision URL
Added: svn:eol-style
   + native

Index: testsuite/gcc.dg/pr57371-2.c
===================================================================
--- testsuite/gcc.dg/pr57371-2.c	(revision 0)
+++ testsuite/gcc.dg/pr57371-2.c	(revision 0)
@@ -0,0 +1,11 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-optimized -fno-trapping-math" } */
+
+int f (unsigned long long x)
+{
+  float y = x;
+  return y <= 0;
+}
+
+/* { dg-final { scan-tree-dump-not "float" "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */