[jdk20] RFR: JDK-8289748: C2 compiled code crashes with SIGFPE with -XX:+StressLCM and -XX:+StressGCM
Christian Hagedorn
chagedorn at openjdk.org
Fri Dec 9 15:37:49 UTC 2022
On Fri, 9 Dec 2022 11:12:35 GMT, Tobias Holenstein <tholenstein at openjdk.org> wrote:
> # Problem
>
> `203 CountedLoop` is the post loop of a strip-mined inner loop. In the loop we have `198 ModI` = 1 / tripcount, where tripcount can never be zero in this loop. The tripcount `204 Phi` is further pinned with a `224 CastII`.
>
> <img width="457" alt="before" src="https://user-images.githubusercontent.com/71546117/206709381-875a24f1-9d78-47d4-95d9-d844714edc09.png">
>
> `IdealLoopTree::do_remove_empty_loop(...)` now replaces the tripcounter `204 Phi` with the value that the loop will have on the last iteration: `80 Phi` (exact limit) - `Const 1` (stride). Here is where the mistake happens:
> `222 If` is the zero trip guard of the post loop and prevents that the post loop is executed when the divisor of `198 ModI` would be zero. BUT tripcounter `204 Phi` is removed without checking if it is pinned to the IF with a CastNode. Therefore the `198 ModI` now floats above the `222 if` where it now can be a modulo zero operation.
>
> <img width="267" alt="fail" src="https://user-images.githubusercontent.com/71546117/206709403-91480599-a310-4da0-b8ab-6e49527141db.png">
>
> # Solution
> The Solution is to check if the tripcount is pinned with a CastII that carries a dependency. If Yes, we create a new CastII to pin final_iv (exact_ limit - stride) :
> <img width="416" alt="fix" src="https://user-images.githubusercontent.com/71546117/206709431-60f0d104-1e4e-416a-8ee1-225435c82e7c.png">
Otherwise, the fix looks good to me!
src/hotspot/share/opto/loopTransform.cpp line 3694:
> 3692: if (castii->is_CastII() && castii->as_CastII()->carry_dependency()) {
> 3693: Node* cast = ConstraintCastNode::make(castii->in(0), exact_limit, phase->_igvn.type(exact_limit), ConstraintCastNode::UnconditionalDependency, T_INT);
> 3694: phase->_igvn.register_new_node_with_optimizer(cast);
We should use `register_new_node` here to also set ctrl.
Suggestion:
phase->register_new_node(cast, castii->in(0));
-------------
Changes requested by chagedorn (Reviewer).
PR: https://git.openjdk.org/jdk20/pull/8
More information about the hotspot-compiler-dev
mailing list