aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Pinski <quic_apinski@quicinc.com>2025-03-08 22:43:54 -0800
committerAndrew Pinski <quic_apinski@quicinc.com>2025-03-09 11:28:32 -0700
commit7232c005afb5002cdfd0a2dbd0e8b8f2d80250ce (patch)
tree6e58a7affe19d62de94d16e0fa797bfda164742a
parent1b21da6abf22f164adb5d03cc91ef09472d035db (diff)
downloadgcc-7232c005afb5002cdfd0a2dbd0e8b8f2d80250ce.zip
gcc-7232c005afb5002cdfd0a2dbd0e8b8f2d80250ce.tar.gz
gcc-7232c005afb5002cdfd0a2dbd0e8b8f2d80250ce.tar.bz2
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_apinski@quicinc.com>
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr118922-1.c57
-rw-r--r--gcc/tree-ssa-phiopt.cc4
2 files changed, 61 insertions, 0 deletions
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 0000000..27e8c78
--- /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 f67f52d..7d2d169 100644
--- a/gcc/tree-ssa-phiopt.cc
+++ b/gcc/tree-ssa-phiopt.cc
@@ -1331,6 +1331,10 @@ value_replacement (basic_block cond_bb, basic_block middle_bb,
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;
+
/* We need to know which is the true edge and which is the false
edge so that we know if have abs or negative abs. */
extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);