From 46e6b26bf8c3124bf4e0c5d26c3eb04e220bd0cb Mon Sep 17 00:00:00 2001 From: Saranya Natarajan Date: Wed, 25 Mar 2026 12:47:41 +0000 Subject: [PATCH] 8372646: C2: Stress Counted Loop creation Reviewed-by: rcastanedalo, chagedorn, dfenacci --- src/hotspot/share/opto/c2_globals.hpp | 3 +++ src/hotspot/share/opto/compile.cpp | 12 +++++++++--- src/hotspot/share/opto/loopnode.cpp | 15 +++++++++++++-- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/hotspot/share/opto/c2_globals.hpp b/src/hotspot/share/opto/c2_globals.hpp index e0833afa29d..a4f6d04f6a3 100644 --- a/src/hotspot/share/opto/c2_globals.hpp +++ b/src/hotspot/share/opto/c2_globals.hpp @@ -907,6 +907,9 @@ \ develop(bool, StressLoopPeeling, false, \ "Randomize loop peeling decision") \ + \ + develop(bool, StressCountedLoop, false, \ + "Randomly delay conversion to counted loops") \ // end of C2_FLAGS diff --git a/src/hotspot/share/opto/compile.cpp b/src/hotspot/share/opto/compile.cpp index f1ea8231df9..f34c75656a4 100644 --- a/src/hotspot/share/opto/compile.cpp +++ b/src/hotspot/share/opto/compile.cpp @@ -741,7 +741,7 @@ Compile::Compile(ciEnv* ci_env, ciMethod* target, int osr_bci, if (StressLCM || StressGCM || StressIGVN || StressCCP || StressIncrementalInlining || StressMacroExpansion || StressMacroElimination || StressUnstableIfTraps || - StressBailout || StressLoopPeeling) { + StressBailout || StressLoopPeeling || StressCountedLoop) { initialize_stress_seed(directive); } @@ -2257,7 +2257,9 @@ bool Compile::optimize_loops(PhaseIterGVN& igvn, LoopOptsMode mode) { PhaseIdealLoop::optimize(igvn, mode); _loop_opts_cnt--; if (failing()) return false; - if (major_progress()) print_method(PHASE_PHASEIDEALLOOP_ITERATIONS, 2); + if (major_progress()) { + print_method(PHASE_PHASEIDEALLOOP_ITERATIONS, 2); + } } } return true; @@ -3798,7 +3800,11 @@ void Compile::final_graph_reshaping_main_switch(Node* n, Final_Reshape_Counts& f } break; case Op_Loop: - assert(!n->as_Loop()->is_loop_nest_inner_loop() || _loop_opts_cnt == 0, "should have been turned into a counted loop"); + // When StressCountedLoop is enabled, this loop may intentionally avoid a counted loop conversion. + // This is expected behavior for the stress mode, which exercises alternative compilation paths. + if (!StressCountedLoop) { + assert(!n->as_Loop()->is_loop_nest_inner_loop() || _loop_opts_cnt == 0, "should have been turned into a counted loop"); + } case Op_CountedLoop: case Op_LongCountedLoop: case Op_OuterStripMinedLoop: diff --git a/src/hotspot/share/opto/loopnode.cpp b/src/hotspot/share/opto/loopnode.cpp index b2eb0c47458..686a0a05f66 100644 --- a/src/hotspot/share/opto/loopnode.cpp +++ b/src/hotspot/share/opto/loopnode.cpp @@ -2137,7 +2137,6 @@ bool CountedLoopConverter::is_counted_loop() { } assert(_head->Opcode() == Op_Loop || _head->Opcode() == Op_LongCountedLoop, "regular loops only"); - _phase->C->print_method(PHASE_BEFORE_CLOOPS, 3, _head); // =================================================== // We can only convert this loop to a counted loop if we can guarantee that the iv phi will never overflow at runtime. @@ -2411,6 +2410,12 @@ bool CountedLoopConverter::is_counted_loop() { _checked_for_counted_loop = true; #endif +#ifndef PRODUCT + if (StressCountedLoop && (_phase->C->random() % 2 == 0)) { + return false; + } +#endif + return true; } @@ -2553,6 +2558,8 @@ IdealLoopTree* CountedLoopConverter::convert() { PhaseIterGVN* igvn = &_phase->igvn(); + _phase->C->print_method(PHASE_BEFORE_CLOOPS, 3, _head); + if (_should_insert_stride_overflow_limit_check) { insert_stride_overflow_limit_check(); } @@ -4734,7 +4741,11 @@ void IdealLoopTree::counted_loop( PhaseIdealLoop *phase ) { } else if (_head->is_LongCountedLoop() || phase->try_convert_to_counted_loop(_head, loop, T_LONG)) { remove_safepoints(phase, true); } else { - assert(!_head->is_Loop() || !_head->as_Loop()->is_loop_nest_inner_loop(), "transformation to counted loop should not fail"); + // When StressCountedLoop is enabled, this loop may intentionally avoid a counted loop conversion. + // This is expected behavior for the stress mode, which exercises alternative compilation paths. + if (!StressCountedLoop) { + assert(!_head->is_Loop() || !_head->as_Loop()->is_loop_nest_inner_loop(), "transformation to counted loop should not fail"); + } if (_parent != nullptr && !_irreducible) { // Not a counted loop. Keep one safepoint. bool keep_one_sfpt = true;