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

--- Comment #9 from Richard Biener <rguenth at gcc dot gnu.org> ---
There's nothing wrong with the unswitching I think.  The exit test is optimized
out in VRP2 where the preceeding DOM pass ended up putting some more SSA ranges
in, specifically those derived from the unreachable().  Disabling DOM3 avoids
the miscompile.

After DOM3 we have

  <bb 2> [local count: 118111600]:
  goto <bb 4>; [100.00%]

  <bb 4> [local count: 228582456]:
  # ivtmp.22_40 = PHI <0(2), ivtmp.22_42(3)>
  # RANGE [-32768, 2]
  it$z_43 = (short int) ivtmp.22_40;
  # RANGE [1, 1]
  _32 = it$z_43 <= 2;

  <bb 5> [local count: 443025880]:
  # ivtmp.14_3 = PHI <0(4), ivtmp.14_19(9)>
  # RANGE [-32768, 2]
  it$y_2 = (short int) ivtmp.14_3;
  # RANGE [1, 1]
  _10 = it$y_2 <= 2;
  # RANGE [1, 1]
  _29 = _10 & _32;
  if (ivtmp.22_40 != 3)
    goto <bb 7>; [89.00%]
  else
    goto <bb 6>; [11.00%]

note how it$z_43, derived from ivtmp.22_40 has a [-32768, 2] range and the
exit test is ivtmp.22_40 != 3.

Now, if ranger would come along and we'd ask it for the _43 def with
the global range [-32768, 2] how that constrains _40 it would compute
a range for that that doesn't hold at this point.  SO what we're likely
seeing is bad effects of our handling of globalizing ranges for a
derived from if (a) __builtin_unreachable ();

There have been issues with that in the past.  GCC 10 vs 11 we have the
extra g:c76b3f9e83353a4cd437ca137c1fb835c9b5c21f which likely fixed this.

Reply via email to