re PR tree-optimization/80054 (ICE in verify_ssa with -O3 -march=broadwell/skylake...
authorBill Schmidt <wschmidt@linux.vnet.ibm.com>
Mon, 20 Mar 2017 20:04:25 +0000 (20:04 +0000)
committerWilliam Schmidt <wschmidt@gcc.gnu.org>
Mon, 20 Mar 2017 20:04:25 +0000 (20:04 +0000)
[gcc]

2017-03-20  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>

PR tree-optimization/80054
* gimple-ssa-strength-reduction.c (all_phi_incrs_profitable): Fail
the optimization if a PHI or any of its arguments is not dominated
by the candidate's basis.  Use gphi* rather than gimple* as
appropriate.
(replace_profitable_candidates): Clean up a gimple* variable that
should be a gphi* variable.

[gcc/testsuite]

2017-03-20  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>

PR tree-optimization/80054
* g++.dg/torture/pr80054.C: New file.

From-SVN: r246290

gcc/ChangeLog
gcc/gimple-ssa-strength-reduction.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/pr80054.C [new file with mode: 0644]

index 188a561963b5aa7a5febd98deef4ceac37fd780c..07fc63898d3c699557ae6164736d5f20e46a67f9 100644 (file)
@@ -1,3 +1,13 @@
+2017-03-20  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
+
+       PR tree-optimization/80054
+       * gimple-ssa-strength-reduction.c (all_phi_incrs_profitable): Fail
+       the optimization if a PHI or any of its arguments is not dominated
+       by the candidate's basis.  Use gphi* rather than gimple* as
+       appropriate.
+       (replace_profitable_candidates): Clean up a gimple* variable that
+       should be a gphi* variable.
+
 2017-03-20  Martin Sebor  <msebor@redhat.com>
 
        PR c++/52477
index 9ebe1989bd2f755e8ffbe43110204dcab2415a1a..ca154c51bfcd7c133d4762bb3322a1438f40f1c6 100644 (file)
@@ -3279,17 +3279,34 @@ insert_initializers (slsr_cand_t c)
 }
 
 /* Return TRUE iff all required increments for candidates feeding PHI
-   are profitable to replace on behalf of candidate C.  */
+   are profitable (and legal!) to replace on behalf of candidate C.  */
 
 static bool
-all_phi_incrs_profitable (slsr_cand_t c, gimple *phi)
+all_phi_incrs_profitable (slsr_cand_t c, gphi *phi)
 {
   unsigned i;
   slsr_cand_t basis = lookup_cand (c->basis);
   slsr_cand_t phi_cand = *stmt_cand_map->get (phi);
 
+  /* If the basis doesn't dominate the PHI (including when the PHI is
+     in the same block as the basis), we won't be able to create a PHI
+     using the basis here.  */
+  basic_block basis_bb = gimple_bb (basis->cand_stmt);
+  basic_block phi_bb = gimple_bb (phi);
+
+  if (phi_bb == basis_bb
+      || !dominated_by_p (CDI_DOMINATORS, phi_bb, basis_bb))
+    return false;
+
   for (i = 0; i < gimple_phi_num_args (phi); i++)
     {
+      /* If the PHI arg resides in a block not dominated by the basis,
+        we won't be able to create a PHI using the basis here.  */
+      basic_block pred_bb = gimple_phi_arg_edge (phi, i)->src;
+
+      if (!dominated_by_p (CDI_DOMINATORS, pred_bb, basis_bb))
+       return false;
+
       tree arg = gimple_phi_arg_def (phi, i);
 
       if (!operand_equal_p (arg, phi_cand->base_expr, 0))
@@ -3298,7 +3315,7 @@ all_phi_incrs_profitable (slsr_cand_t c, gimple *phi)
 
          if (gimple_code (arg_def) == GIMPLE_PHI)
            {
-             if (!all_phi_incrs_profitable (c, arg_def))
+             if (!all_phi_incrs_profitable (c, as_a <gphi *> (arg_def)))
                return false;
            }
          else
@@ -3565,7 +3582,7 @@ replace_profitable_candidates (slsr_cand_t c)
        {
          if (phi_dependent_cand_p (c))
            {
-             gimple *phi = lookup_cand (c->def_phi)->cand_stmt;
+             gphi *phi = as_a <gphi *> (lookup_cand (c->def_phi)->cand_stmt);
 
              if (all_phi_incrs_profitable (c, phi))
                {
index 2b6d7c6286c15a8876eab30569f7960dd2245405..121c3dc7c316ba73f0c459856d8d636394fb5d40 100644 (file)
@@ -1,3 +1,8 @@
+2017-03-20  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
+
+       PR tree-optimization/80054
+       * g++.dg/torture/pr80054.C: New file.
+
 2017-03-20  Kelvin Nilsen  <kelvin@gcc.gnu.org>
 
        PR target/79963
diff --git a/gcc/testsuite/g++.dg/torture/pr80054.C b/gcc/testsuite/g++.dg/torture/pr80054.C
new file mode 100644 (file)
index 0000000..50de24a
--- /dev/null
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+
+/* Used to fail in SLSR because of a dominance violation.  PR80054.  */
+
+extern short var_2;
+extern short var_4;
+extern const bool var_32;
+extern short var_36;
+extern const bool var_37;
+extern bool var_46;
+extern unsigned int var_47;
+extern short var_49;
+extern unsigned int var_56;
+extern unsigned int var_62;
+extern unsigned int var_65;
+extern bool var_831;
+extern unsigned int var_843;
+extern short var_846;
+extern short var_889;
+
+void foo() {
+  if (var_36 * var_37)
+    var_831 = var_56 = 0;
+  else
+    var_65 = 0;
+
+  if (var_46)
+    var_843 = 0;
+
+  var_846 = 0;
+
+  if ((var_4 == 0) >> (var_32 | -(var_37 < var_46 || var_36)) + 8)
+    var_49 = 2032651381 * bool(var_2 * var_37);
+  else {
+    var_62 = 0;
+    var_47 = (var_46 || var_36) * (var_2 * var_37);
+  }
+
+  var_889 = bool(var_2 * var_37);
+}