]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR tree-optimization/37542 (PRE doesn't simplify during phi-translation)
authorRichard Guenther <rguenther@suse.de>
Sun, 2 Nov 2008 15:26:04 +0000 (15:26 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Sun, 2 Nov 2008 15:26:04 +0000 (15:26 +0000)
2008-11-02  Richard Guenther  <rguenther@suse.de>

PR tree-optimization/37542
* tree-ssa-pre.c (fully_constant_expression): Handle more cases.
* tree-ssa-sccvn.c (vn_get_expr_for): Fix typo.
(vn_nary_op_lookup_stmt): Adjust for unary reference trees.
(vn_nary_op_insert_stmt): Likewise.
(visit_use): Likewise.

* gcc.dg/tree-ssa/ssa-pre-22.c: New testcase.
* gcc.c-torture/compile/20081101-1.c: Likewise.

From-SVN: r141534

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/20081101-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-22.c [new file with mode: 0644]
gcc/tree-ssa-pre.c
gcc/tree-ssa-sccvn.c

index b01b48337dbca2a4d4bcfcddc681333ec0295577..90c40cac6659bd2660fc4440c9a5bbd10466d2e2 100644 (file)
@@ -1,3 +1,12 @@
+2008-11-02  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/37542
+       * tree-ssa-pre.c (fully_constant_expression): Handle more cases.
+       * tree-ssa-sccvn.c (vn_get_expr_for): Fix typo.
+       (vn_nary_op_lookup_stmt): Adjust for unary reference trees.
+       (vn_nary_op_insert_stmt): Likewise.
+       (visit_use): Likewise.
+
 2008-11-02  Anatoly Sokolov  <aesok@post.ru>
 
        * config/avr/avr.md (UNSPEC_SWAP): Remove constants.
index 90e0db5fb721393749cdbfbcee74d0e354035091..e7c346467c455a03b582c7e3f34d48ed487f11d9 100644 (file)
@@ -1,3 +1,9 @@
+2008-11-02  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/37542
+       * gcc.dg/tree-ssa/ssa-pre-22.c: New testcase.
+       * gcc.c-torture/compile/20081101-1.c: Likewise.
+
 2008-11-02  Richard Guenther  <rguenther@suse.de>
 
        PR tree-optimization/37991
diff --git a/gcc/testsuite/gcc.c-torture/compile/20081101-1.c b/gcc/testsuite/gcc.c-torture/compile/20081101-1.c
new file mode 100644 (file)
index 0000000..0e484d0
--- /dev/null
@@ -0,0 +1,12 @@
+int foo (int i, int b)
+{
+  int mask;
+  int result;
+  if (b)
+    mask = -1;
+  else
+    mask = 0;
+  result = i + 1;
+  result = result & mask;
+  return result;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-22.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-22.c
new file mode 100644 (file)
index 0000000..3a1697e
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-pre-stats" } */
+
+int foo (int i, int b)
+{
+  int j = 1;
+  if (b)
+    j = i;
+  return j - i;
+}
+
+/* { dg-final { scan-tree-dump "Eliminated: 1" "pre" } } */
+/* { dg-final { cleanup-tree-dump "pre" } } */
index dc576c5a3d7d615605b89ef9c37507bc063762a5..d881bf3961c2f47a30c067cb45b4c05f719f07b2 100644 (file)
@@ -1088,47 +1088,59 @@ fully_constant_expression (pre_expr e)
        vn_nary_op_t nary = PRE_EXPR_NARY (e);
        switch (TREE_CODE_CLASS (nary->opcode))
          {
+         case tcc_expression:
+           if (nary->opcode == TRUTH_NOT_EXPR)
+             goto do_unary;
+           if (nary->opcode != TRUTH_AND_EXPR
+               && nary->opcode != TRUTH_OR_EXPR
+               && nary->opcode != TRUTH_XOR_EXPR)
+             return e;
+           /* Fallthrough.  */
          case tcc_binary:
+         case tcc_comparison:
            {
              /* We have to go from trees to pre exprs to value ids to
                 constants.  */
              tree naryop0 = nary->op[0];
              tree naryop1 = nary->op[1];
-             tree const0, const1, result;
-             if (is_gimple_min_invariant (naryop0))
-               const0 = naryop0;
-             else
+             tree result;
+             if (!is_gimple_min_invariant (naryop0))
                {
                  pre_expr rep0 = get_or_alloc_expr_for (naryop0);
                  unsigned int vrep0 = get_expr_value_id (rep0);
-                 const0 = get_constant_for_value_id (vrep0);
+                 tree const0 = get_constant_for_value_id (vrep0);
+                 if (const0)
+                   naryop0 = fold_convert (TREE_TYPE (naryop0), const0);
                }
-             if (is_gimple_min_invariant (naryop1))
-               const1 = naryop1;
-             else
+             if (!is_gimple_min_invariant (naryop1))
                {
                  pre_expr rep1 = get_or_alloc_expr_for (naryop1);
                  unsigned int vrep1 = get_expr_value_id (rep1);
-                 const1 = get_constant_for_value_id (vrep1);
-               }
-             result = NULL;
-             if (const0 && const1)
-               {
-                 tree type1 = TREE_TYPE (nary->op[0]);
-                 tree type2 = TREE_TYPE (nary->op[1]);
-                 const0 = fold_convert (type1, const0);
-                 const1 = fold_convert (type2, const1);
-                 result = fold_binary (nary->opcode, nary->type, const0,
-                                       const1);
+                 tree const1 = get_constant_for_value_id (vrep1);
+                 if (const1)
+                   naryop1 = fold_convert (TREE_TYPE (naryop1), const1);
                }
+             result = fold_binary (nary->opcode, nary->type,
+                                   naryop0, naryop1);
              if (result && is_gimple_min_invariant (result))
                return get_or_alloc_expr_for_constant (result);
+             /* We might have simplified the expression to a
+                SSA_NAME for example from x_1 * 1.  But we cannot
+                insert a PHI for x_1 unconditionally as x_1 might
+                not be available readily.  */
              return e;
            }
+         case tcc_reference:
+           if (nary->opcode != REALPART_EXPR
+               && nary->opcode != IMAGPART_EXPR 
+               && nary->opcode != VIEW_CONVERT_EXPR)
+             return e;
+           /* Fallthrough.  */
          case tcc_unary:
+do_unary:
            {
-           /* We have to go from trees to pre exprs to value ids to
-              constants.  */
+             /* We have to go from trees to pre exprs to value ids to
+                constants.  */
              tree naryop0 = nary->op[0];
              tree const0, result;
              if (is_gimple_min_invariant (naryop0))
@@ -1146,7 +1158,6 @@ fully_constant_expression (pre_expr e)
                  const0 = fold_convert (type1, const0);
                  result = fold_unary (nary->opcode, nary->type, const0);
                }
-             
              if (result && is_gimple_min_invariant (result))
                return get_or_alloc_expr_for_constant (result);
              return e;
index e255411fe6a8458efe7ee57302042bb4439a41a7..80f7a92c3dcef625546c1a43885f518f395353bc 100644 (file)
@@ -258,8 +258,8 @@ vn_get_expr_for (tree name)
     {
     case tcc_reference:
       if (gimple_assign_rhs_code (def_stmt) == VIEW_CONVERT_EXPR
-         && gimple_assign_rhs_code (def_stmt) == REALPART_EXPR
-         && gimple_assign_rhs_code (def_stmt) == IMAGPART_EXPR)
+         || gimple_assign_rhs_code (def_stmt) == REALPART_EXPR
+         || gimple_assign_rhs_code (def_stmt) == IMAGPART_EXPR)
        expr = fold_build1 (gimple_assign_rhs_code (def_stmt),
                            gimple_expr_type (def_stmt),
                            TREE_OPERAND (gimple_assign_rhs1 (def_stmt), 0));
@@ -1281,6 +1281,10 @@ vn_nary_op_lookup_stmt (gimple stmt, vn_nary_op_t *vnresult)
   vno1.type = TREE_TYPE (gimple_assign_lhs (stmt));
   for (i = 0; i < vno1.length; ++i)
     vno1.op[i] = gimple_op (stmt, i + 1);
+  if (vno1.opcode == REALPART_EXPR
+      || vno1.opcode == IMAGPART_EXPR
+      || vno1.opcode == VIEW_CONVERT_EXPR)
+    vno1.op[0] = TREE_OPERAND (vno1.op[0], 0);
   vno1.hashcode = vn_nary_op_compute_hash (&vno1);
   slot = htab_find_slot_with_hash (current_info->nary, &vno1, vno1.hashcode,
                                   NO_INSERT);
@@ -1385,6 +1389,10 @@ vn_nary_op_insert_stmt (gimple stmt, tree result)
   vno1->type = TREE_TYPE (gimple_assign_lhs (stmt));
   for (i = 0; i < vno1->length; ++i)
     vno1->op[i] = gimple_op (stmt, i + 1);
+  if (vno1->opcode == REALPART_EXPR
+      || vno1->opcode == IMAGPART_EXPR
+      || vno1->opcode == VIEW_CONVERT_EXPR)
+    vno1->op[0] = TREE_OPERAND (vno1->op[0], 0);
   vno1->result = result;
   vno1->hashcode = vn_nary_op_compute_hash (vno1);
   slot = htab_find_slot_with_hash (current_info->nary, vno1, vno1->hashcode,
@@ -2380,8 +2388,18 @@ visit_use (tree use)
                    case GIMPLE_SINGLE_RHS:
                      switch (TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)))
                        {
-                       case tcc_declaration:
                        case tcc_reference:
+                         /* VOP-less references can go through unary case.  */
+                         if ((gimple_assign_rhs_code (stmt) == REALPART_EXPR
+                              || gimple_assign_rhs_code (stmt) == IMAGPART_EXPR
+                              || gimple_assign_rhs_code (stmt) == VIEW_CONVERT_EXPR )
+                             && TREE_CODE (TREE_OPERAND (gimple_assign_rhs1 (stmt), 0)) == SSA_NAME)
+                           {
+                             changed = visit_unary_op (lhs, stmt);
+                             break;
+                           }
+                         /* Fallthrough.  */
+                       case tcc_declaration:
                          changed = visit_reference_op_load
                              (lhs, gimple_assign_rhs1 (stmt), stmt);
                          break;