OSDN Git Service

2008-09-01 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 1 Sep 2008 13:39:42 +0000 (13:39 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 1 Sep 2008 13:39:42 +0000 (13:39 +0000)
PR tree-optimization/37305
* tree-ssa-ccp.c (ccp_fold): Do not set TREE_OVERFLOW on
the result of constant conversions.
(fold_gimple_assign): Likewise.

* gcc.c-torture/compile/pr37305.c: New testcase.

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

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/pr37305.c [new file with mode: 0644]
gcc/tree-ssa-ccp.c

index 078acdb..52c233c 100644 (file)
@@ -1,3 +1,10 @@
+2008-09-01  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/37305
+       * tree-ssa-ccp.c (ccp_fold): Do not set TREE_OVERFLOW on
+       the result of constant conversions.
+       (fold_gimple_assign): Likewise.
+
 2008-09-01  Andrey Belevantsev  <abel@ispras.ru>
 
        * sel-sched-ir.c (cmp_v_in_regset_pool): Surround with 
index f49a6ce..07830c8 100644 (file)
@@ -1,3 +1,8 @@
+2008-09-01  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/37305
+       * gcc.c-torture/compile/pr37305.c: New testcase.
+
 2008-09-01  Jakub Jelinek  <jakub@redhat.com>
 
        PR middle-end/36449
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr37305.c b/gcc/testsuite/gcc.c-torture/compile/pr37305.c
new file mode 100644 (file)
index 0000000..7c06736
--- /dev/null
@@ -0,0 +1,19 @@
+typedef int int32_t;
+typedef unsigned int uint32_t;
+static inline int
+safe_add_s_s (int si1, int si2)
+{
+  if ((si1 > 0) && (si2 > 0) && (si1 > (si2)) || (si1 < 0) && (si2 < 0)
+      && (si1 < ((-__INT_MAX__ - 1) - si2)))
+    return si1;
+}
+
+uint32_t g_8;
+uint32_t
+func_24 (int32_t p_25)
+{
+  uint32_t l_30 = -1L;
+  if ((safe_mod_u_u (1, 1)) | (safe_add_s_s (g_8, l_30)))
+    return 1;
+}
+
index 870a244..9fe0753 100644 (file)
@@ -941,6 +941,7 @@ ccp_fold (gimple stmt)
                  so this should almost always return a simplified RHS.  */
               tree lhs = gimple_assign_lhs (stmt);
               tree op0 = gimple_assign_rhs1 (stmt);
+             tree res;
 
               /* Simplify the operand down to a constant.  */
               if (TREE_CODE (op0) == SSA_NAME)
@@ -976,8 +977,21 @@ ccp_fold (gimple stmt)
                  return op0;
                }
 
-              return fold_unary (subcode, gimple_expr_type (stmt), op0);
-            }  
+              res = fold_unary (subcode, gimple_expr_type (stmt), op0);
+
+             /* If the operation was a conversion do _not_ mark a
+                resulting constant with TREE_OVERFLOW if the original
+                constant was not.  These conversions have implementation
+                defined behavior and retaining the TREE_OVERFLOW flag
+                here would confuse later passes such as VRP.  */
+             if (res
+                 && TREE_CODE (res) == INTEGER_CST
+                 && TREE_CODE (op0) == INTEGER_CST
+                 && CONVERT_EXPR_CODE_P (subcode))
+               TREE_OVERFLOW (res) = TREE_OVERFLOW (op0);
+
+             return res;
+            }
 
           case GIMPLE_BINARY_RHS:
             {
@@ -2644,26 +2658,37 @@ fold_gimple_assign (gimple_stmt_iterator *si)
       break;
 
     case GIMPLE_UNARY_RHS:
-      result = fold_unary (subcode,
-                           gimple_expr_type (stmt),
-                           gimple_assign_rhs1 (stmt));
+      {
+       tree rhs = gimple_assign_rhs1 (stmt);
 
-      if (result)
-        {
-          STRIP_USELESS_TYPE_CONVERSION (result);
-          if (valid_gimple_rhs_p (result))
-           return result;
-        }
-      else if (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt))
-              && POINTER_TYPE_P (gimple_expr_type (stmt))
-              && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (stmt))))
-       {
-         tree type = gimple_expr_type (stmt);
-         tree t = maybe_fold_offset_to_address (gimple_assign_rhs1 (stmt),
-                                                integer_zero_node, type);
-         if (t)
-           return t;
-       }
+       result = fold_unary (subcode, gimple_expr_type (stmt), rhs);
+       if (result)
+         {
+           /* If the operation was a conversion do _not_ mark a
+              resulting constant with TREE_OVERFLOW if the original
+              constant was not.  These conversions have implementation
+              defined behavior and retaining the TREE_OVERFLOW flag
+              here would confuse later passes such as VRP.  */
+           if (CONVERT_EXPR_CODE_P (subcode)
+               && TREE_CODE (result) == INTEGER_CST
+               && TREE_CODE (rhs) == INTEGER_CST)
+             TREE_OVERFLOW (result) = TREE_OVERFLOW (rhs);
+
+           STRIP_USELESS_TYPE_CONVERSION (result);
+           if (valid_gimple_rhs_p (result))
+             return result;
+         }
+       else if (CONVERT_EXPR_CODE_P (subcode)
+                && POINTER_TYPE_P (gimple_expr_type (stmt))
+                && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (stmt))))
+         {
+           tree type = gimple_expr_type (stmt);
+           tree t = maybe_fold_offset_to_address (gimple_assign_rhs1 (stmt),
+                                                  integer_zero_node, type);
+           if (t)
+             return t;
+         }
+      }
       break;
 
     case GIMPLE_BINARY_RHS: