RFR: 8359235: C1 compilation fails with "assert(is_single_stack() && !is_virtual()) failed: type check" [v4]
Tobias Hartmann
thartmann at openjdk.org
Fri Aug 8 22:29:13 UTC 2025
On Wed, 30 Jul 2025 22:58:50 GMT, Guanqiang Han <ghan at openjdk.org> wrote:
>> I'm able to consistently reproduce the problem using the following command line and test program :
>>
>> java -Xcomp -XX:TieredStopAtLevel=1 -XX:C1MaxInlineSize=200 Test.java
>>
>> import java.util.Arrays;
>> public class Test{
>> public static void main(String[] args) {
>> System.out.println("begin");
>> byte[] arr1 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
>> byte[] arr2 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
>> System.out.println(Arrays.equals(arr1, arr2));
>> System.out.println("end");
>> }
>> }
>>
>> From my analysis, the root cause appears to be a mismatch in operand handling between T_ADDRESS and T_LONG in LIR_Assembler::stack2reg, especially when the source is marked as double stack (e.g., T_LONG) and the destination as single CPU register (e.g., T_ADDRESS), leading to assertion failures like assert(is_single_stack())(because T_LONG is double_size).
>>
>> In the test program above , the call chain is: Arrays.equals → ArraysSupport.vectorizedMismatch → LIRGenerator::do_vectorizedMismatch
>> Within the do_vectorizedMismatch() method, a move instruction constructs an LIR_Op1. During LIR to machine code generation, LIR_Assembler::stack2reg was called.
>>
>> In this case, the src operand has type T_LONG and the dst operand has type T_ADDRESS. This combination triggers an assert in stack2reg, due to a mismatch between the stack slot type and register type handling.
>>
>> Importantly, this path ( LIR_Assembler::stack2reg was called ) is only taken when src is forced onto the stack. To reliably trigger this condition, the test is run with the -Xcomp option to force compilation and increase register pressure.
>>
>> A reference to the relevant code paths is provided below :
>> <img width="1260" height="720" alt="image1" src="https://github.com/user-attachments/assets/d0d6a8e2-4316-4475-86a6-58f5f274682c" />
>> <img width="598" height="206" alt="image2" src="https://github.com/user-attachments/assets/90d1bcdd-c9fa-4598-b8a6-101101caad9c" />
>>
>> On 64-bit platforms, although T_ADDRESS is classified as single_size, it is in fact 64 bits wide ,represent a single 64-bit general-purpose register and it can hold a T_LONG value, which is also 64 bits.
>>
>> However, T_LONG is defined as double_size, requiring two local variable slots or a pair of registers in the JVM's abstract model. This mismatch stems from the fact that T_ADDRESS is platform-dependent: it's 32 bits on 32-bit platforms, and 64 bits on 64-bit platforms — yet its size class...
>
> Guanqiang Han has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains six additional commits since the last revision:
>
> - change T_LONG to T_ADDRESS in some intrinsic functions
> - Merge remote-tracking branch 'upstream/master' into 8359235
> - Increase sleep time to ensure the method gets compiled
> - add regression test
> - Merge remote-tracking branch 'upstream/master' into 8359235
> - 8359235: C1 compilation fails with "assert(is_single_stack() && !is_virtual()) failed: type check"
test/hotspot/jtreg/compiler/intrinsics/TestStack2RegSlotMismatch.java line 29:
> 27: * @summary Test C1 stack2reg after fixing incorrect use of T_LONG in intrinsic
> 28: * @requires vm.debug == true & vm.compiler1.enabled
> 29: * @run main/othervm -XX:TieredStopAtLevel=1 -XX:C1MaxInlineSize=200 -XX:CompileThreshold=10 compiler.intrinsics.TestStack2RegSlotMismatch
I'm still wondering if this test can be reduced. Right now `-XX:C1MaxInlineSize=200 -XX:CompileThreshold=10` will lead to a lot of methods being compiled with C1 but I assume there is only one method that actually triggers the issue, right? Can we restrict compilation to that one?
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/26462#discussion_r2264078800
More information about the hotspot-compiler-dev
mailing list