RFR: JDK-8289748: C2 compiled code crashes with SIGFPE with -XX:+StressLCM and -XX:+StressGCM

Vladimir Kozlov kvn at openjdk.org
Mon Jan 16 23:48:12 UTC 2023


On Fri, 13 Jan 2023 15:15:43 GMT, Tobias Holenstein <tholenstein at openjdk.org> wrote:

> # Problem 
> 
> We have an outer strip-mined loop `207`/`205` with inner strip-mined loop `283`/`203`. `262` is the zero-trip guard and `157 ModI` has the trip count `284 Phi` in the divisor. The corresponding zero guard of `157 ModI` was removed because the divisor is guaranteed to always be non-zero.
> 
> `PhaseIdealLoop::cast_incr_before_loop(..)` inserts a CastII to pin `284 Phi` to `262 if` but the following `igvn` phase removes the CastII again because it becomes a constant. Therefore, `284 Phi` loses its pin to `262 if`.
> ![fail before](https://user-images.githubusercontent.com/71546117/212355062-feaa78a9-b1f4-4bf6-b70b-03a134b2de9d.png)
> 
> `IdealLoopTree::do_remove_empty_loop(..)` removes the loop `283`/`203` and replaces `284 Phi` with the final value of the last iteration. The problem is that the computation of final value (exact_limit - stride) floats above `262 if` - so now `157 ModI` is not guarded by `262 if` anymore: in our attached test case we get an `SIGFPE` because the modulo divides by zero at runtime. 
> 
> ![fail after](https://user-images.githubusercontent.com/71546117/212355115-e8015569-0d1a-450e-bd09-40e1f8999bdd.png)
> 
> # Solution
> The solution is to insert a `CastII` in `IdealLoopTree::do_remove_empty_loop(..)` to prevent final_iv (exact_limit - stride) to float above the zero trip guard. 
> 
> ![fix after](https://user-images.githubusercontent.com/71546117/212355168-a0a86420-dbcc-48c7-9466-a6bf2db8b13b.png)

src/hotspot/share/opto/loopTransform.cpp line 3702:

> 3700:   Node* cast_ii = ConstraintCastNode::make(cl->in(LoopNode::EntryControl), exact_limit, phase->_igvn.type(exact_limit), ConstraintCastNode::UnconditionalDependency, T_INT);
> 3701:   phase->register_new_node(cast_ii, cl->in(LoopNode::EntryControl));
> 3702:   phase->_igvn.replace_input_of(final_iv, 1, cast_ii);

Why replace input here instead of using it as input when `final_iv` is created?

-------------

PR: https://git.openjdk.org/jdk/pull/11990


More information about the hotspot-compiler-dev mailing list