https://gcc.gnu.org/g:9d0c2f769553c65a39c12df3c2d0891c53fafd6a

commit r12-11050-g9d0c2f769553c65a39c12df3c2d0891c53fafd6a
Author: Andrew Pinski <quic_apin...@quicinc.com>
Date:   Sat Mar 8 22:43:54 2025 -0800

    phiopt: Fix value_replacement for middle bb having phi nodes [PR118922]
    
    After r12-5300-gf98f373dd822b3, value_replacement would be able to look at 
the
    following cfg structure:
    ```
      <bb 5> [local count: 1014686024]:
      if (h_6 != 0)
        goto <bb 7>; [94.50%]
      else
        goto <bb 6>; [5.50%]
    
      <bb 6> [local count: 114863530]:
      # h_6 = PHI <0(4), 1(5)>
    
      <bb 7> [local count: 1073741824]:
      # f_8 = PHI <0(5), h_6(6)>
      _9 = f_8 ^ 1;
      a.0_10 = a;
      _11 = _9 + a.0_10;
      if (_11 != -117)
        goto <bb 5>; [94.50%]
      else
        goto <bb 8>; [5.50%]
    ```
    
    value_replacement would incorrectly think the middle bb (6) was empty and 
so it decides
    to remove condition in bb5 and replacing it with 0 as the function thought 
it was `h_6 ? 0 : h_6`.
    But since the there is an incoming phi node to bb6 defining h_6 that is 
incorrect.
    
    The fix is to check if there is phi nodes in the middle bb and set 
empty_or_with_defined_p to false.
    This was not needed before r12-5300-gf98f373dd822b3 because the phi would 
have been dead otherwise due to
    other checks.
    
    Bootstrapped and tested on x86_64-linux-gnu.
    
            PR tree-optimization/118922
    
    gcc/ChangeLog:
    
            * tree-ssa-phiopt.cc (value_replacement): Set 
empty_or_with_defined_p
            to false when there is phi nodes for the middle bb.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.dg/torture/pr118922-1.c: New test.
    
    Signed-off-by: Andrew Pinski <quic_apin...@quicinc.com>
    (cherry picked from commit 7232c005afb5002cdfd0a2dbd0e8b8f2d80250ce)

Diff:
---
 gcc/testsuite/gcc.dg/torture/pr118922-1.c | 57 +++++++++++++++++++++++++++++++
 gcc/tree-ssa-phiopt.cc                    |  3 ++
 2 files changed, 60 insertions(+)

diff --git a/gcc/testsuite/gcc.dg/torture/pr118922-1.c 
b/gcc/testsuite/gcc.dg/torture/pr118922-1.c
new file mode 100644
index 000000000000..27e8c78c0e4e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr118922-1.c
@@ -0,0 +1,57 @@
+/* { dg-do run } */
+/* PR tree-optimization/118922 */
+
+/* Phi-opt would convert:
+  <bb 5> [local count: 1014686024]:
+  if (h_6 != 0)
+    goto <bb 7>; [94.50%]
+  else
+    goto <bb 6>; [5.50%]
+
+  <bb 6> [local count: 114863530]:
+  # h_6 = PHI <0(4), 1(5)>
+
+  <bb 7> [local count: 1073741824]:
+  # f_8 = PHI <0(5), h_6(6)>
+  _9 = f_8 ^ 1;
+  a.0_10 = a;
+  _11 = _9 + a.0_10;
+  if (_11 != -117)
+    goto <bb 5>; [94.50%]
+  else
+    goto <bb 8>; [5.50%]
+
+into:
+
+  <bb 4> [local count: 59055799]:
+  c = d_3;
+
+  <bb 5> [local count: 1073741824]:
+  # f_8 = PHI <0(5), 0(4)>
+  _9 = f_8 ^ 1;
+  a.0_10 = a;
+  _11 = _9 + a.0_10;
+  if (_11 != -117)
+    goto <bb 5>; [94.50%]
+  else
+    goto <bb 6>; [5.50%]
+
+as it thought the middle bb was empty as there was only a phi node there. */
+
+
+int a = -117, b, c, e;
+void g(int h) {
+  int f = 0;
+  while (!f + a - -117) {
+    f = h == 0;
+    if (h == 0)
+      h = 1;
+  }
+}
+int main() {
+  int d = 8;
+  for (; e;)
+    d = 0;
+  c = d;
+  g(0);
+}
diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc
index 167b0b3be741..aec0350010b5 100644
--- a/gcc/tree-ssa-phiopt.cc
+++ b/gcc/tree-ssa-phiopt.cc
@@ -1322,6 +1322,9 @@ value_replacement (basic_block cond_bb, basic_block 
middle_bb,
                && jump_function_from_stmt (&arg1, stmt)))
        empty_or_with_defined_p = false;
     }
+  /* The middle bb is not empty if there are any phi nodes. */
+  if (phi_nodes (middle_bb))
+    empty_or_with_defined_p = false;
 
   cond = last_stmt (cond_bb);
   code = gimple_cond_code (cond);

Reply via email to