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

--- Comment #2 from Jeffrey A. Law <law at redhat dot com> ---
Ha!  Got it.

On the path noted in the earlier comment we have the following:

<bb 444>:
pred_x ={v} {CLOBBER};
pred_y ={v} {CLOBBER};
_423 = s_46(D)->rd_total;
_424 = score[best_374];
_425 = (long int) _424;
_426 = _423 + _425;
s_46(D)->rd_total = _426;
if (best_374 != 2)
  goto <bb 445>;
else
  goto <bb 449>;



I'd looked at that block a few times and even traced where that test came from,
the propagation of best_374 into that test and determined that while
suboptimal, it was correct (the test originally used a different variable, one
which had the range [0..2].  The path by which the "2" appears in that range
eventually gets proved unexecutable and removed.  Once that happens the
original object becomes equivalent to best_374 and the copy propagation occurs
in copyprop (which AFAICT doesn't try to use range information to simplify
things).

Anyway, all that is irrelevant to the problem.  ssa_name_has_boolean_range does
something like this

edge_info->rhs = (integer_zerop (op1) ? true_val : false_val);

When it only had to deal with booleans, that was fine because op1 in this
context would always be the constant 0 or 1 (it's the RHS of the conditional).

But once we start handling integers with a narrow range, that test is wrong.

Fixing is trivial.  It'll probably take longer to boil down a suitable testcase
-- it's late.  I'll poke at this further over the weekend.

Reply via email to