[TCWG CI] Regression caused by gcc: tree-optimization/102880 - make PHI-OPT 
recognize more CFGs:
commit f98f373dd822b35c52356b753d528924e9f89678
Author: Richard Biener <rguent...@suse.de>

    tree-optimization/102880 - make PHI-OPT recognize more CFGs

Results regressed to
# reset_artifacts:
-10
# build_abe binutils:
-9
# build_abe stage1:
-5
# build_abe qemu:
-2
# linux_n_obj:
21059
# First few build errors in logs:
# 00:20:13 drivers/net/wireless/realtek/rtlwifi/rtl8192se/hw.c:2521:1: error: 
definition in block 22 does not dominate use in block 21
# 00:20:13 drivers/net/wireless/realtek/rtlwifi/rtl8192se/hw.c:2521:1: internal 
compiler error: verify_ssa failed
# 00:20:13 make[6]: *** [scripts/Makefile.build:280: 
drivers/net/wireless/realtek/rtlwifi/rtl8192se/hw.o] Error 1
# 00:20:20 make[5]: *** [scripts/Makefile.build:497: 
drivers/net/wireless/realtek/rtlwifi/rtl8192se] Error 2
# 00:24:02 make[4]: *** [scripts/Makefile.build:497: 
drivers/net/wireless/realtek/rtlwifi] Error 2
# 00:24:02 make[3]: *** [scripts/Makefile.build:497: 
drivers/net/wireless/realtek] Error 2
# 00:24:02 make[2]: *** [scripts/Makefile.build:497: drivers/net/wireless] 
Error 2
# 00:25:21 drivers/staging/comedi/drivers/addi_apci_3120.c:1117:1: error: 
definition in block 10 does not dominate use in block 11
# 00:25:21 drivers/staging/comedi/drivers/addi_apci_3120.c:1117:1: internal 
compiler error: verify_ssa failed
# 00:25:22 make[4]: *** [scripts/Makefile.build:280: 
drivers/staging/comedi/drivers/addi_apci_3120.o] Error 1

from
# reset_artifacts:
-10
# build_abe binutils:
-9
# build_abe stage1:
-5
# build_abe qemu:
-2
# linux_n_obj:
28893
# linux build successful:
all

THIS IS THE END OF INTERESTING STUFF.  BELOW ARE LINKS TO BUILDS, REPRODUCTION 
INSTRUCTIONS, AND THE RAW COMMIT.

This commit has regressed these CI configurations:
 - tcwg_kernel/gnu-master-arm-lts-allmodconfig

First_bad build: 
https://ci.linaro.org/job/tcwg_kernel-gnu-bisect-gnu-master-arm-lts-allmodconfig/15/artifact/artifacts/build-f98f373dd822b35c52356b753d528924e9f89678/
Last_good build: 
https://ci.linaro.org/job/tcwg_kernel-gnu-bisect-gnu-master-arm-lts-allmodconfig/15/artifact/artifacts/build-d699f03720fce57b319276226ac4a463a8538e9f/
Baseline build: 
https://ci.linaro.org/job/tcwg_kernel-gnu-bisect-gnu-master-arm-lts-allmodconfig/15/artifact/artifacts/build-baseline/
Even more details: 
https://ci.linaro.org/job/tcwg_kernel-gnu-bisect-gnu-master-arm-lts-allmodconfig/15/artifact/artifacts/

Reproduce builds:
<cut>
mkdir investigate-gcc-f98f373dd822b35c52356b753d528924e9f89678
cd investigate-gcc-f98f373dd822b35c52356b753d528924e9f89678

# Fetch scripts
git clone https://git.linaro.org/toolchain/jenkins-scripts

# Fetch manifests and test.sh script
mkdir -p artifacts/manifests
curl -o artifacts/manifests/build-baseline.sh 
https://ci.linaro.org/job/tcwg_kernel-gnu-bisect-gnu-master-arm-lts-allmodconfig/15/artifact/artifacts/manifests/build-baseline.sh
 --fail
curl -o artifacts/manifests/build-parameters.sh 
https://ci.linaro.org/job/tcwg_kernel-gnu-bisect-gnu-master-arm-lts-allmodconfig/15/artifact/artifacts/manifests/build-parameters.sh
 --fail
curl -o artifacts/test.sh 
https://ci.linaro.org/job/tcwg_kernel-gnu-bisect-gnu-master-arm-lts-allmodconfig/15/artifact/artifacts/test.sh
 --fail
chmod +x artifacts/test.sh

# Reproduce the baseline build (build all pre-requisites)
./jenkins-scripts/tcwg_kernel-build.sh @@ artifacts/manifests/build-baseline.sh

# Save baseline build state (which is then restored in artifacts/test.sh)
mkdir -p ./bisect
rsync -a --del --delete-excluded --exclude /bisect/ --exclude /artifacts/ 
--exclude /gcc/ ./ ./bisect/baseline/

cd gcc

# Reproduce first_bad build
git checkout --detach f98f373dd822b35c52356b753d528924e9f89678
../artifacts/test.sh

# Reproduce last_good build
git checkout --detach d699f03720fce57b319276226ac4a463a8538e9f
../artifacts/test.sh

cd ..
</cut>

Full commit (up to 1000 lines):
<cut>
commit f98f373dd822b35c52356b753d528924e9f89678
Author: Richard Biener <rguent...@suse.de>
Date:   Mon Nov 15 15:19:36 2021 +0100

    tree-optimization/102880 - make PHI-OPT recognize more CFGs
    
    This allows extra edges into the middle BB for the PHI-OPT
    transforms using replace_phi_edge_with_variable that do not
    end up moving stmts from that middle BB.  This avoids regressing
    gcc.dg/tree-ssa/ssa-hoist-4.c with the actual fix for PR102880
    where CFG cleanup has the choice to remove two forwarders and
    picks "the wrong" leading to
    
       if (a > b) /
           /\    /
          /  <BB>
         /    |
      # PHI <a, b>
    
    rather than
    
       if (a > b)  |
           /\      |
        <BB> \     |
         /    \    |
      # PHI <a, b, b>
    
    but it's relatively straight-forward to support extra edges
    into the middle-BB in paths ending in replace_phi_edge_with_variable
    and that do not require moving stmts.  That's because we really
    only want to remove the edge from the condition to the middle BB.
    Of course actually doing that means updating dominators in non-trival
    ways which is why I kept the original code for the single edge
    case and simply defer to CFG cleanup by adjusting the condition for
    the complicated case.
    
    The testcase needs to be a GIMPLE one since it's quite unreliable
    to produce the desired CFG.
    
    2021-11-15  Richard Biener  <rguent...@suse.de>
    
            PR tree-optimization/102880
            * tree-ssa-phiopt.c (tree_ssa_phiopt_worker): Push
            single_pred (bb1) condition to places that really need it.
            (match_simplify_replacement): Likewise.
            (value_replacement): Likewise.
            (replace_phi_edge_with_variable): Deal with extra edges
            into the middle BB.
    
            * gcc.dg/tree-ssa/phi-opt-26.c: New testcase.
---
 gcc/testsuite/gcc.dg/tree-ssa/phi-opt-26.c | 31 +++++++++++++
 gcc/tree-ssa-phiopt.c                      | 71 +++++++++++++++++-------------
 2 files changed, 72 insertions(+), 30 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-26.c 
b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-26.c
new file mode 100644
index 00000000000..21aa66e38b8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-26.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fgimple -fdump-tree-phiopt1" } */
+
+int __GIMPLE (ssa,startwith("phiopt"))
+foo (int a, int b, int flag)
+{
+  int res;
+
+  __BB(2):
+  if (flag_2(D) != 0)
+    goto __BB6;
+  else
+    goto __BB4;
+
+  __BB(4):
+  if (a_3(D) > b_4(D))
+    goto __BB7;
+  else
+    goto __BB6;
+
+  __BB(6):
+  goto __BB7;
+
+  __BB(7):
+  res_1 = __PHI (__BB4: a_3(D), __BB6: b_4(D));
+  return res_1;
+}
+
+/* We should be able to detect MAX despite the extra edge into
+   the middle BB.  */
+/* { dg-final { scan-tree-dump "MAX" "phiopt1" } } */
diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c
index 173ac835ca6..6b22f6bedd4 100644
--- a/gcc/tree-ssa-phiopt.c
+++ b/gcc/tree-ssa-phiopt.c
@@ -220,7 +220,6 @@ tree_ssa_phiopt_worker (bool do_store_elim, bool 
do_hoist_loads, bool early_p)
 
       /* If either bb1's succ or bb2 or bb2's succ is non NULL.  */
       if (EDGE_COUNT (bb1->succs) == 0
-          || bb2 == NULL
          || EDGE_COUNT (bb2->succs) == 0)
         continue;
 
@@ -276,14 +275,14 @@ tree_ssa_phiopt_worker (bool do_store_elim, bool 
do_hoist_loads, bool early_p)
          || (e1->flags & EDGE_FALLTHRU) == 0)
         continue;
 
-      /* Also make sure that bb1 only have one predecessor and that it
-        is bb.  */
-      if (!single_pred_p (bb1)
-          || single_pred (bb1) != bb)
-       continue;
-
       if (do_store_elim)
        {
+         /* Also make sure that bb1 only have one predecessor and that it
+            is bb.  */
+         if (!single_pred_p (bb1)
+             || single_pred (bb1) != bb)
+           continue;
+
          /* bb1 is the middle block, bb2 the join block, bb the split block,
             e1 the fallthrough edge from bb1 to bb2.  We can't do the
             optimization if the join block has more than two predecessors.  */
@@ -328,10 +327,11 @@ tree_ssa_phiopt_worker (bool do_store_elim, bool 
do_hoist_loads, bool early_p)
             node.  */
          gcc_assert (arg0 != NULL_TREE && arg1 != NULL_TREE);
 
-         gphi *newphi = factor_out_conditional_conversion (e1, e2, phi,
-                                                           arg0, arg1,
-                                                           cond_stmt);
-         if (newphi != NULL)
+         gphi *newphi;
+         if (single_pred_p (bb1)
+             && (newphi = factor_out_conditional_conversion (e1, e2, phi,
+                                                             arg0, arg1,
+                                                             cond_stmt)))
            {
              phi = newphi;
              /* factor_out_conditional_conversion may create a new PHI in
@@ -350,12 +350,14 @@ tree_ssa_phiopt_worker (bool do_store_elim, bool 
do_hoist_loads, bool early_p)
                                               early_p))
            cfgchanged = true;
          else if (!early_p
+                  && single_pred_p (bb1)
                   && cond_removal_in_builtin_zero_pattern (bb, bb1, e1, e2,
                                                            phi, arg0, arg1))
            cfgchanged = true;
          else if (minmax_replacement (bb, bb1, e1, e2, phi, arg0, arg1))
            cfgchanged = true;
-         else if (spaceship_replacement (bb, bb1, e1, e2, phi, arg0, arg1))
+         else if (single_pred_p (bb1)
+                  && spaceship_replacement (bb, bb1, e1, e2, phi, arg0, arg1))
            cfgchanged = true;
        }
     }
@@ -386,7 +388,6 @@ replace_phi_edge_with_variable (basic_block cond_block,
                                edge e, gphi *phi, tree new_tree)
 {
   basic_block bb = gimple_bb (phi);
-  basic_block block_to_remove;
   gimple_stmt_iterator gsi;
   tree phi_result = PHI_RESULT (phi);
 
@@ -422,28 +423,33 @@ replace_phi_edge_with_variable (basic_block cond_block,
   SET_USE (PHI_ARG_DEF_PTR (phi, e->dest_idx), new_tree);
 
   /* Remove the empty basic block.  */
+  edge edge_to_remove;
   if (EDGE_SUCC (cond_block, 0)->dest == bb)
+    edge_to_remove = EDGE_SUCC (cond_block, 1);
+  else
+    edge_to_remove = EDGE_SUCC (cond_block, 0);
+  if (EDGE_COUNT (edge_to_remove->dest->preds) == 1)
     {
-      EDGE_SUCC (cond_block, 0)->flags |= EDGE_FALLTHRU;
-      EDGE_SUCC (cond_block, 0)->flags &= ~(EDGE_TRUE_VALUE | 
EDGE_FALSE_VALUE);
-      EDGE_SUCC (cond_block, 0)->probability = profile_probability::always ();
+      e->flags |= EDGE_FALLTHRU;
+      e->flags &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);
+      e->probability = profile_probability::always ();
+      delete_basic_block (edge_to_remove->dest);
 
-      block_to_remove = EDGE_SUCC (cond_block, 1)->dest;
+      /* Eliminate the COND_EXPR at the end of COND_BLOCK.  */
+      gsi = gsi_last_bb (cond_block);
+      gsi_remove (&gsi, true);
     }
   else
     {
-      EDGE_SUCC (cond_block, 1)->flags |= EDGE_FALLTHRU;
-      EDGE_SUCC (cond_block, 1)->flags
-       &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);
-      EDGE_SUCC (cond_block, 1)->probability = profile_probability::always ();
-
-      block_to_remove = EDGE_SUCC (cond_block, 0)->dest;
+      /* If there are other edges into the middle block make
+        CFG cleanup deal with the edge removal to avoid
+        updating dominators here in a non-trivial way.  */
+      gcond *cond = as_a <gcond *> (last_stmt (cond_block));
+      if (edge_to_remove->flags & EDGE_TRUE_VALUE)
+       gimple_cond_make_false (cond);
+      else
+       gimple_cond_make_true (cond);
     }
-  delete_basic_block (block_to_remove);
-
-  /* Eliminate the COND_EXPR at the end of COND_BLOCK.  */
-  gsi = gsi_last_bb (cond_block);
-  gsi_remove (&gsi, true);
 
   statistics_counter_event (cfun, "Replace PHI with variable", 1);
 
@@ -959,6 +965,9 @@ match_simplify_replacement (basic_block cond_bb, 
basic_block middle_bb,
      allow it and move it once the transformation is done. */
   if (!empty_block_p (middle_bb))
     {
+      if (!single_pred_p (middle_bb))
+       return false;
+
       stmt_to_move = last_and_only_stmt (middle_bb);
       if (!stmt_to_move)
        return false;
@@ -1351,7 +1360,10 @@ value_replacement (basic_block cond_bb, basic_block 
middle_bb,
        }
       else
        {
-         statistics_counter_event (cfun, "Replace PHI with 
variable/value_replacement", 1);
+         if (!single_pred_p (middle_bb))
+           return 0;
+         statistics_counter_event (cfun, "Replace PHI with "
+                                   "variable/value_replacement", 1);
 
          /* Replace the PHI arguments with arg. */
          SET_PHI_ARG_DEF (phi, e0->dest_idx, arg);
@@ -1367,7 +1379,6 @@ value_replacement (basic_block cond_bb, basic_block 
middle_bb,
             }
           return 1;
        }
-
     }
 
   /* Now optimize (x != 0) ? x + y : y to just x + y.  */
</cut>
_______________________________________________
linaro-toolchain mailing list
linaro-toolchain@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/linaro-toolchain

Reply via email to