> 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
> 

Reply via email to