2012-04-27 Marc Glisse <marc.glisse@inria.fr>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 27 Apr 2012 10:34:13 +0000 (10:34 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 27 Apr 2012 10:34:13 +0000 (10:34 +0000)
PR middle-end/27139
* tree-ssa-forwprop.c (combine_conversions): Handle INT->FP->INT.

* gcc.dg/tree-ssa/forwprop-18.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@186898 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/forwprop-18.c [new file with mode: 0644]
gcc/tree-ssa-forwprop.c

index 5ed7c47..76578cb 100644 (file)
@@ -1,3 +1,8 @@
+2012-04-27  Marc Glisse  <marc.glisse@inria.fr>
+
+       PR middle-end/27139
+       * tree-ssa-forwprop.c (combine_conversions): Handle INT->FP->INT.
+
 2012-04-25  Manuel López-Ibáñez  <manu@gcc.gnu.org>
 
        PR c/53130
index 7643b5a..2109f5d 100644 (file)
@@ -1,3 +1,8 @@
+2012-04-27  Marc Glisse  <marc.glisse@inria.fr>
+
+       PR middle-end/27139
+       * gcc.dg/tree-ssa/forwprop-18.c: New test.
+
 2012-04-27  Tom de Vries  <tom@codesourcery.com>
 
        PR tree-optimization/51879
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-18.c b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-18.c
new file mode 100644 (file)
index 0000000..2c4d120
--- /dev/null
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-forwprop1" } */
+
+signed char f1(signed char n)
+{
+  return (long double)n;
+}
+unsigned long long f2(signed char n)
+{
+  return (long double)n;
+}
+
+unsigned long long g1(unsigned long long n)
+{
+  return (float)n;
+}
+signed char g2(unsigned long long n)
+{
+  return (float)n;
+}
+
+/* { dg-final { scan-tree-dump-times "\\\(float\\\)" 2 "forwprop1" } } */
+/* { dg-final { scan-tree-dump-not "\\\(long double\\\)" "forwprop1" } } */
+/* { dg-final { cleanup-tree-dump "forwprop1" } } */
index 3f00b1d..4739de1 100644 (file)
@@ -2405,6 +2405,7 @@ combine_conversions (gimple_stmt_iterator *gsi)
   gimple def_stmt;
   tree op0, lhs;
   enum tree_code code = gimple_assign_rhs_code (stmt);
+  enum tree_code code2;
 
   gcc_checking_assert (CONVERT_EXPR_CODE_P (code)
                       || code == FLOAT_EXPR
@@ -2425,7 +2426,9 @@ combine_conversions (gimple_stmt_iterator *gsi)
   if (!is_gimple_assign (def_stmt))
     return 0;
 
-  if (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt)))
+  code2 = gimple_assign_rhs_code (def_stmt);
+
+  if (CONVERT_EXPR_CODE_P (code2) || code2 == FLOAT_EXPR)
     {
       tree defop0 = gimple_assign_rhs1 (def_stmt);
       tree type = TREE_TYPE (lhs);
@@ -2553,6 +2556,29 @@ combine_conversions (gimple_stmt_iterator *gsi)
          update_stmt (gsi_stmt (*gsi));
          return 1;
        }
+
+      /* If we are converting an integer to a floating-point that can
+        represent it exactly and back to an integer, we can skip the
+        floating-point conversion.  */
+      if (inside_int && inter_float && final_int &&
+          (unsigned) significand_size (TYPE_MODE (inter_type))
+          >= inside_prec - !inside_unsignedp)
+        {
+         if (useless_type_conversion_p (type, inside_type))
+           {
+             gimple_assign_set_rhs1 (stmt, unshare_expr (defop0));
+             gimple_assign_set_rhs_code (stmt, TREE_CODE (defop0));
+             update_stmt (stmt);
+             return remove_prop_source_from_use (op0) ? 2 : 1;
+           }
+         else
+           {
+             gimple_assign_set_rhs1 (stmt, defop0);
+             gimple_assign_set_rhs_code (stmt, CONVERT_EXPR);
+             update_stmt (stmt);
+             return remove_prop_source_from_use (op0) ? 2 : 1;
+           }
+       }
     }
 
   return 0;