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) --- gcc/testsuite/gcc.dg/torture/pr118922-1.c | 57 +++++++++++++++++++++++ gcc/tree-ssa-phiopt.cc | 3 ++ 2 files changed, 60 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/torture/pr118922-1.c 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 00000000000..27e8c78c0e4 --- /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 167b0b3be74..aec0350010b 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); -- 2.43.0