]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-ssa-sccvn.c (cond_stmts_equal_p): Compare two GIMPLE cond stmts, enhanced and...
authorRichard Biener <rguenther@suse.de>
Wed, 21 Oct 2015 08:12:15 +0000 (08:12 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 21 Oct 2015 08:12:15 +0000 (08:12 +0000)
2015-10-21  Richard Biener  <rguenther@suse.de>

* tree-ssa-sccvn.c (cond_stmts_equal_p): Compare two GIMPLE
cond stmts, enhanced and split out from ...
(vn_phi_eq): ... here.

From-SVN: r229119

gcc/ChangeLog
gcc/tree-ssa-sccvn.c

index 89b7c441f2e2da510f1c28c0e6fa7302649db01e..6e30cdb3d933b6c10e3bbd266112ad82620ed785 100644 (file)
@@ -1,3 +1,9 @@
+2015-10-21  Richard Biener  <rguenther@suse.de>
+
+       * tree-ssa-sccvn.c (cond_stmts_equal_p): Compare two GIMPLE
+       cond stmts, enhanced and split out from ...
+       (vn_phi_eq): ... here.
+
 2015-10-21  Richard Biener  <rguenther@suse.de>
 
        PR middle-end/68031
index c57fb259f033f3e63bbf6b1cdffdffd6beeb7a22..ac21f75cea48838c77e69b57c7f35aed332697aa 100644 (file)
@@ -2687,6 +2687,43 @@ vn_phi_compute_hash (vn_phi_t vp1)
 }
 
 
+/* Return true if COND1 and COND2 represent the same condition, set
+   *INVERTED_P if one needs to be inverted to make it the same as
+   the other.  */
+
+static bool
+cond_stmts_equal_p (gcond *cond1, gcond *cond2, bool *inverted_p)
+{
+  enum tree_code code1 = gimple_cond_code (cond1);
+  enum tree_code code2 = gimple_cond_code (cond2);
+  tree lhs1 = gimple_cond_lhs (cond1);
+  tree lhs2 = gimple_cond_lhs (cond2);
+  tree rhs1 = gimple_cond_rhs (cond1);
+  tree rhs2 = gimple_cond_rhs (cond2);
+
+  *inverted_p = false;
+  if (code1 == code2)
+    ;
+  else if (code1 == swap_tree_comparison (code2))
+    std::swap (lhs2, rhs2);
+  else if (code1 == invert_tree_comparison (code2, HONOR_NANS (lhs2)))
+    *inverted_p = true;
+  else if (code1 == invert_tree_comparison
+                     (swap_tree_comparison (code2), HONOR_NANS (lhs2)))
+    {
+      std::swap (lhs2, rhs2);
+      *inverted_p = true;
+    }
+  else
+    return false;
+
+  if (! expressions_equal_p (vn_valueize (lhs1), vn_valueize (lhs2))
+      || ! expressions_equal_p (vn_valueize (rhs1), vn_valueize (rhs2)))
+    return false;
+
+  return true;
+}
+
 /* Compare two phi entries for equality, ignoring VN_TOP arguments.  */
 
 static int
@@ -2735,13 +2772,9 @@ vn_phi_eq (const_vn_phi_t const vp1, const_vn_phi_t const vp2)
            if (gimple_code (last1) != GIMPLE_COND
                || gimple_code (last2) != GIMPLE_COND)
              return false;
-           gcond *cond1 = as_a <gcond *> (last1);
-           gcond *cond2 = as_a <gcond *> (last2);
-           if (gimple_cond_code (cond1) != gimple_cond_code (cond2)
-               || ! expressions_equal_p (gimple_cond_lhs (cond1),
-                                      gimple_cond_lhs (cond2))
-               || ! expressions_equal_p (gimple_cond_rhs (cond1),
-                                         gimple_cond_rhs (cond2)))
+           bool inverted_p;
+           if (! cond_stmts_equal_p (as_a <gcond *> (last1),
+                                     as_a <gcond *> (last2), &inverted_p))
              return false;
 
            /* Get at true/false controlled edges into the PHI.  */
@@ -2752,6 +2785,11 @@ vn_phi_eq (const_vn_phi_t const vp1, const_vn_phi_t const vp2)
                                                          &te2, &fe2))
              return false;
 
+           /* Swap edges if the second condition is the inverted of the
+              first.  */
+           if (inverted_p)
+             std::swap (te2, fe2);
+
            /* ???  Handle VN_TOP specially.  */
            if (! expressions_equal_p (vp1->phiargs[te1->dest_idx],
                                       vp2->phiargs[te2->dest_idx])