https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115494

--- Comment #8 from Richard Biener <rguenth at gcc dot gnu.org> ---
ANTIC_IN[6] := { _5 (0005), _16 (0014), {bit_not_expr,_16} (0016),
{bit_ior_expr,_5,_19} (0017) }
ANTIC_IN[8] := { _5 (0005), _16 (0014), {bit_not_expr,_16} (0016),
{bit_ior_expr,_5,_17} (0017) }
ANTIC_IN[11] := { _5 (0005), _16 (0014), {bit_not_expr,_16} (0016),
{bit_ior_expr,_5,_24} (0017) }

merge 8 + 11:
ANTIC_IN[7] := { b.0_1 (0001), _5 (0005), _16 (0014), {bit_not_expr,_16}
(0016), {bit_ior_expr,_5,_17} (0017), {bit_ior_expr,_5,_24} (0017) }

merge 7 + 6:
ANTIC_IN[5] := { b.0_1 (0001), iftmp.2_9 (0008), {nop_expr,iftmp.2_9} (0005),
{bit_not_expr,_5} (0006), {nop_expr,b.0_1} (0014), {bit_not_expr,_16} (0016),
{bit_ior_expr,_5,_19} (0017), {bit_ior_expr,_5,_17} (0017),
{bit_ior_expr,_5,_24} (0017) 

that's all OK.  Note all exprs have the same value (0017) here.  Then
we PHI-translate to where _5 == 0:
ANTIC_IN[14] := { b.0_1 (0001), {nop_expr,b.0_1} (0014), {bit_not_expr,_16}
(0016) }
which is OK, 0 | .. gets simplified to ~16

Then we PHI-translate to where _5 == 1:
ANTIC_IN[4] := { b.0_1 (0001), {nop_expr,b.0_1} (0014), {bit_not_expr,_16}
(0016), {bit_ior_expr,_17,1} (0027), {bit_ior_expr,_24,1} (0028) }
even that's OK, you see that we simplified just _5 | _19 to 1 (constants
are not tracked in the set, the translated _17 | _5 and _24 | _5 got
different value numbers).

But then:

Found partial redundancy for expression {bit_ior_expr,_5,_19} (0017)
...
Created phi prephitmp_29 = PHI <1(4), _28(14)>
 in block 5 (0017)

see how we figured the redundancy for value 0017 (because _5 | _19
simplified to 1) and we use the same value for the PHI as for all of
the expressions.

That we now keep all PRE exprs didn't save us here.  _19 _is_ the leader
for the expression as we translate it.  The problem is the other
expressions for the same value do not translate the same.

This is probably a longer latent issue since we scrapped resetting
ranges which likely means since RPO VN.  It's always a bit of luck
but I guess since we now track all expressions we have for a value
this got more robust in triggering.  It of course also needs a suitable
simplification to manifest.

I have to think about this.  Simplifying to sth like

  if (flag)
    a = 1;
  if (b & 1 == b) // b [0,1]
    x = a | b;
  else
    x = a | b;
  return x;

should be possible.

Reply via email to