While working on JDK-8323101, I've noticed that the test case triggers with DivI/ModI cases but not with DivL/ModL cases even though the graph looks exactly the same (apart from using *L instead of *I nodes).
I had a closer look and found that the DivL/ModL nodes have a different late control compared to the DivI/ModI in the same test. In fact, early and late control are exactly the same for the DivL/ModL nodes while they are different for the DivI/ModI nodes The reason is that DivL/ModL nodes are not treated as unpinned in PhaseIdeal::build_loop_late_post_work() while DivI/ModI nodes are.
I think we just miss DivL/ModL nodes in this switch statement where we treat nodes as unpinned:
https://github.com/openjdk/jdk/blob/82a63a03c0155288e8e43b9f766c8be70be50b6a/src/hotspot/share/opto/loopnode.cpp#L6091-L6125
I dug deeper and found that DivL/ModL nodes were added later after the switch statement was already there. We probably just forgot back there to adjust the switch statement to also special case them.
We should try to add an IR test which shows that it is beneficial to treat them unpinned in PhaseIdeal::build_loop_late_post_work(). This can most likely be done by utilizing the Split If optimization.