mirror of
https://gcc.gnu.org/git/gcc.git
synced 2026-02-22 03:46:53 -05:00
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>
This commit is contained in:
57
gcc/testsuite/gcc.dg/torture/pr118922-1.c
Normal file
57
gcc/testsuite/gcc.dg/torture/pr118922-1.c
Normal file
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user