> Am 09.03.2025 um 18:11 schrieb Andrew Pinski <quic_apin...@quicinc.com>:
>
> 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.
Ok
Thanks,
Richard
> 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>
> ---
> gcc/testsuite/gcc.dg/torture/pr118922-1.c | 57 +++++++++++++++++++++++
> gcc/tree-ssa-phiopt.cc | 4 ++
> 2 files changed, 61 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 fb918f8825d..371a7c7bd98 100644
> --- a/gcc/tree-ssa-phiopt.cc
> +++ b/gcc/tree-ssa-phiopt.cc
> @@ -1366,6 +1366,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);
> --
> 2.43.0
>