RFR: 8341976: C2: use_mem_state != load->find_exact_control(load->in(0)) assert failure [v2]
Damon Fenacci
dfenacci at openjdk.org
Tue Feb 18 13:47:12 UTC 2025
On Fri, 7 Feb 2025 08:45:34 GMT, Roland Westrelin <roland at openjdk.org> wrote:
>> The `arraycopy` writes to a non escaping array so its `ArrayCopy` node
>> is marked as having a narrow memory effect. One of the loads from the
>> destination after the copy is transformed into a load from the source
>> array (the rationale being that if there's no load from the
>> destination of the copy, the `arraycopy` is not needed). The load from
>> the source has the input memory state of the `ArrayCopy` as memory
>> input. That load is then sunk out of the loop and its control is
>> updated to be after the `ArrayCopy`. That's legal because the
>> `ArrayCopy` only has a narrow memory effect and can't modify the
>> source. The `ArrayCopy` can't be eliminated and is expanded. In the
>> process, a `MemBar` that has a wide memory effect is added. The load
>> from the source has control after the membar but memory state before
>> and because the membar has a wide memory effect, the load is anti
>> dependent on the membar: the graph is broken (the load can't be pinned
>> after the membar and anti dependent on it).
>>
>> In short, the problem is that the graph is transformed under the
>> assumption that the `ArrayCopy` has a narrow effect but the
>> `ArrayCopy` is expanded to a subgraph that has a wide memory
>> effect. The fix I propose is to not insert a membar with a wide memory
>> effect. We still need a membar when the destination is non escaping
>> because the expanded `ArrayCopy`, if it writes to a tighly allocated
>> array, writes to raw memory and not to the destination memory slice.
>
> Roland Westrelin has updated the pull request incrementally with one additional commit since the last revision:
>
> review
Thanks for the fix @rwestrel.
I noticed that the test `compiler/arraycopy/TestArrayCopyOverflowInBoundChecks.java` seems to be failing on linux x64 with the same `assert(use_mem_state != load->find_exact_control(load->in(0))) failed: dependence cycle found` error **after** your fix:
#
# A fatal error has been detected by the Java Runtime Environment:
#
# Internal Error (src/hotspot/share/opto/gcm.cpp:916), pid=1506939, tid=1506963
# assert(use_mem_state != load->find_exact_control(load->in(0))) failed: dependence cycle found
#
Current CompileTask:
C2:293 90 b 4 compiler.arraycopy.TestArrayCopyOverflowInBoundChecks::test (19 bytes)
Stack: [0x000076bd9f800000,0x000076bd9f900000], sp=0x000076bd9f8fb560, free space=1005k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V [libjvm.so+0xde84e9] PhaseCFG::insert_anti_dependences(Block*, Node*, bool)+0x1f69 (gcm.cpp:916)
V [libjvm.so+0xde8fa9] PhaseCFG::schedule_late(VectorSet&, Node_Stack&)+0x8c9 (gcm.cpp:1535)
V [libjvm.so+0xde9903] PhaseCFG::global_code_motion()+0x403 (gcm.cpp:1649)
V [libjvm.so+0xdea676] PhaseCFG::do_global_code_motion()+0x66 (gcm.cpp:1778)
V [libjvm.so+0xa55a00] Compile::Code_Gen()+0x3c0 (compile.cpp:2952)
V [libjvm.so+0xa5899f] Compile::Compile(ciEnv*, ciMethod*, int, Options, DirectiveSet*)+0x1c9f (compile.cpp:881)
V [libjvm.so+0x8a40b5] C2Compiler::compile_method(ciEnv*, ciMethod*, int, bool, DirectiveSet*)+0x1d5 (c2compiler.cpp:141)
V [libjvm.so+0xa65068] CompileBroker::invoke_compiler_on_method(CompileTask*)+0x928 (compileBroker.cpp:2317)
V [libjvm.so+0xa65da8] CompileBroker::compiler_thread_loop()+0x528 (compileBroker.cpp:1975)
V [libjvm.so+0xf2a1fe] JavaThread::thread_main_inner()+0xee (javaThread.cpp:776)
V [libjvm.so+0x187dbb6] Thread::call_run()+0xb6 (thread.cpp:231)
V [libjvm.so+0x1556338] thread_native_entry(Thread*)+0x128 (os_linux.cpp:877)
-------------
PR Comment: https://git.openjdk.org/jdk/pull/23465#issuecomment-2665761027
More information about the hotspot-compiler-dev
mailing list