If there are two adjacent guards with different conditions, we can
remove one of them and include its condition into the condition of
another one. This patch allows InstCombine to merge them by the
following pattern:
guard(a); guard(b) -> guard(a & b).
There's a subtle problem here -- we can transform
to
but not to
since the deopt state of the second guard (represented as "Y" here
for simplicity) may have been optimized under the assumption that a
is true.
For instance, say we started with
which first got optimized to
and then due to this change is optimized to
Now if a is false at runtime then the expected behavior was to
deoptimize with the deopt state (a) == (false), but in the
optimized program we will deoptimize with the deopt state (true).
The right transform here is to widen the first guard, not the second
one.