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