8193935: RFR(S): Illegal countedLoops transformation
nils.eliasson at oracle.com
Mon Mar 19 09:17:28 UTC 2018
This bug was found in mpegaudio hiding behind the loop predication. The
Counted loop transformation may loose a significant truncation which
changes the behaviour of the program.
CountedLoopNode::match_incr_with_optional_truncation finds the
truncation Op_AndI(0x7fff) and sets trunc_t = TypeInt::CHAR. However the
program does not use it for a char truncation, but a accessing an array
as a circular buffer. (Any other mask would have hidden this problem
since char truncation is the only one matched).
A loop is succesfully matched as a countedloop, and when the trip
counter is cloned it drops the truncation. In the intended char-case
that is ok. In this case the truncation prevents the program from
hitting an AIOOB.
In the general case, if a truncated loop counter is compared to an array
length (or any variable) it must be provable that the array length is
less than the truncation, and then the truncation can be omitted. If the
array length can be longer, the exit may never be taken - the loop may
never terminate, and a counted loop transform can not be performed.
One additional topic of discussion is if we really want to do counted
loop transformations with a RangeCheck as exit point. Especially if the
profiling shows that the RangeCheck never fails. In the loop that fails
there are multiple exits, many which are RangeChecks.
For additional optimization opportunities we could consider rotating the
loop until a normal compare is the loop exit condition.
Image of significant parts of node graph (the entire loop with its
multiple exits, is omitted):
More information about the hotspot-compiler-dev