]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
phiopt: Reject instead of assert that the 2 vuse of the loads are the same [PR125923]
authorAndrew Pinski <andrew.pinski@oss.qualcomm.com>
Sun, 21 Jun 2026 23:10:15 +0000 (16:10 -0700)
committerAndrew Pinski <andrew.pinski@oss.qualcomm.com>
Mon, 22 Jun 2026 17:35:35 +0000 (10:35 -0700)
So it turns out I thought we would always get a virtual phi when there was a store
in front of the load. This is correct for all normal code except if heading into
an infinite loop where there are no stores/loads. Since this is leading to
an infinite loop, rejecting this case does not change performance at all.

Bootstrapped and tested on x86_64-linux-gnu.

PR tree-optimization/125923

gcc/ChangeLog:

* tree-ssa-phiopt.cc (factor_out_conditional_load): Change
assert of the vuse being the same to rejecting if they are
different without a virtual phi.

gcc/testsuite/ChangeLog:

* gcc.dg/torture/pr125923-1.c: New test.

Signed-off-by: Andrew Pinski <andrew.pinski@oss.qualcomm.com>
gcc/testsuite/gcc.dg/torture/pr125923-1.c [new file with mode: 0644]
gcc/tree-ssa-phiopt.cc

diff --git a/gcc/testsuite/gcc.dg/torture/pr125923-1.c b/gcc/testsuite/gcc.dg/torture/pr125923-1.c
new file mode 100644 (file)
index 0000000..1edce7d
--- /dev/null
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fno-tree-dce" } */
+/* PR tree-optimization/125923 */
+
+int a, b, c, d;
+void e() {
+  d = a && d;
+  if (b)
+    b = 0;
+  while (!a || b)
+    c ^= 1;
+}
index c73a81c41668ca73d5cc2f60ddd1116bbaee5e15..7a623fc4c0c2b7d3cb77e4687a029d32a34b9be3 100644 (file)
@@ -3713,8 +3713,11 @@ factor_out_conditional_load (edge e0, edge e1, basic_block merge, gphi *phi,
          || gimple_vuse (load1) != gimple_phi_arg_def (vphi, e1->dest_idx))
        return false;
     }
-  else
-    gcc_assert (gimple_vuse (load0) == gimple_vuse (load1));
+  /* Sometimes due to not removing dead statements,
+     a virtual phi does not show up going into an infinite loop
+     so just reject that case.  */
+  else if (gimple_vuse (load0) != gimple_vuse (load1))
+    return false;
 
   tree ref0 = gimple_assign_rhs1 (load0);
   tree ref1 = gimple_assign_rhs1 (load1);