With SuperWord AlignVector, we analyze the mem_ref's pointer (VPointer).
Since arrays are objects, they are 8-byte aligned (ObjectAlignmentInBytes), and so we can just ignore the base of the address (the address of the header of the array).
But if we do not take an array, but instead directly get an address to some allocated memory with Unsafe.allocateMemory, we can do any pointer arithmetic with this pointer, and pass it as an unaligned base. This breaks the assumption, and we can get unaligned vector memory accesses, even if not allowed by AlignVector.
Reproduce with JDK23, after JDK-8310190 (added runtime assert to verify that the address is aligned):
./java --add-modules java.base --add-exports java.base/jdk.internal.misc=ALL-UNNAMED -XX:CompileCommand=compileonly,Test::test* -XX:+TraceLoopOpts -XX:+TraceSuperWord -XX:+AlignVector -XX:+VerifyAlignVector Test.java
#
# A fatal error has been detected by the Java Runtime Environment:
#
# Internal Error (/oracle-work/jdk-fork0/open/src/hotspot/cpu/x86/macroAssembler_x86.cpp:831), pid=3090218, tid=3090219
# fatal error: DEBUG MESSAGE: verify_vector_alignment found a misaligned vector memory access
#
# JRE version: Java(TM) SE Runtime Environment (23.0) (fastdebug build 23-internal-2024-01-10-0740221.emanuel...)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (fastdebug 23-internal-2024-01-10-0740221.emanuel..., mixed mode, tiered, compressed oops, compressed class ptrs, g1 gc, linux-amd64)
# Problematic frame:
# V [libjvm.so+0x12eca65] MacroAssembler::debug64(char*, long, long*)+0x45
#
# Core dump will be written. Default location: Core dumps may be processed with "/usr/share/apport/apport -p%p -s%s -c%c -d%d -P%P -u%u -g%g -- %E" (or dumping to /oracle-work/jdk-fork0/build/linux-x64-debug/jdk/bin/core.3090218)
#
# An error report file with more information is saved as:
# /oracle-work/jdk-fork0/build/linux-x64-debug/jdk/bin/hs_err_pid3090218.log
#
# If you would like to submit a bug report, please visit:
# https://bugreport.java.com/bugreport/crash.jsp
#
Aborted (core dumped)
Older versions JDK20-JDK22:
/oracle-work/jdk-22/fastdebug/bin/java --add-modules java.base --add-exports java.base/jdk.internal.misc=ALL-UNNAMED -XX:CompileCommand=compileonly,Test::test* -XX:+TraceLoopOpts -XX:+TraceSuperWord -XX:+AlignVector Test.java
This seems to run ok, but produces misaligned alignment and performs misaligned vector memory access. We just don't fail on x64 since no strict alignment is actually required. In the log we find that the alignment/offset looks aligned, but that is because we assume the base to be aligned.
After find_adjacent_refs
packset
Pack: 0
align: 0 417 StoreI === 445 448 420 418 [[ 414 416 ]] @rawptr:BotPTR, idx=Raw; unaligned unsafe Memory: @rawptr:BotPTR, idx=Raw; !orig=343,291,248,123,262 !jvms: Test::test @ bci:38 (line 16)
align: 4 414 StoreI === 445 417 422 415 [[ 411 413 ]] @rawptr:BotPTR, idx=Raw; unaligned unsafe Memory: @rawptr:BotPTR, idx=Raw; !orig=340,288,123,262 !jvms: Test::test @ bci:38 (line 16)
I wonder if this has an impact on machines that do require AlignVector, such as ARM32? A first investigation with [~fgao] suggested that it does not reproduce, since it did not vectorize for some other reason. Maybe the reason is that Unaligned memory accesses are not intrinsified into simple loads / stores?
Versions with JDK19 or older do not vectorize this code anyway, so they are not affected.