RFR: 8342662: C2: Add new phase for backend-specific lowering [v3]

Quan Anh Mai qamai at openjdk.org
Wed Dec 11 16:10:17 UTC 2024


On Wed, 11 Dec 2024 04:51:48 GMT, Jasmine Karthikeyan <jkarthikeyan at openjdk.org> wrote:

>> Hi @jaskarth ,
>> 
>> I was trying to lower LShiftVB/URShiftVB IR to LShiftVS/URShiftVS for the x86 backend. I intend to factor out through GVN upfront byte vector to short vector conversion for both input and shift vectors if these are shared across two operations since the x86 ISA does not support direct byte vector shifts.
>> 
>> To begin with, I made the following diff expecting status quo, but getting the following Fatal error at build time, can you kindly check?
>> 
>> 
>> diff --git a/src/hotspot/cpu/x86/c2_lowering_x86.cpp b/src/hotspot/cpu/x86/c2_lowering_x86.cpp
>> index cf4c014ffda..bc8df186396 100644
>> --- a/src/hotspot/cpu/x86/c2_lowering_x86.cpp
>> +++ b/src/hotspot/cpu/x86/c2_lowering_x86.cpp
>> @@ -32,6 +32,6 @@ Node* PhaseLowering::lower_node_platform(Node* n) {
>>  }
>> 
>>  bool PhaseLowering::should_lower() {
>> -  return false;
>> +  return true;
>>  }
>>  #endif // COMPILER2
>> ```  
>> 
>> 
>> ERROR: Build failed for target 'images' in configuration 'linux-x86_64-server-fastdebug' (exit code 2)
>> 
>> === Output from failing command(s) repeated here ===
>> * For target support_interim-image-jlink__jlink_interim_image_exec:
>> #
>> # A fatal error has been detected by the Java Runtime Environment:
>> #
>> #  Internal Error (/home/jatinbha/sandboxes/jdk-trunk/jdk/src/hotspot/share/opto/node.hpp:960), pid=1961256, tid=1961293
>> #  assert(is_MachReturn()) failed: invalid node class: Con
>> #
>> # JRE version: OpenJDK Runtime Environment (24.0) (fastdebug build 24-internal-adhoc.root.jdk)
>> # Java VM: OpenJDK 64-Bit Server VM (fastdebug 24-internal-adhoc.root.jdk, mixed mode, tiered, compressed oops, compressed class ptrs, g1 gc, linux-amd64)
>> # Problematic frame:
>> # V  [libjvm.so+0x140f939]  Matcher::Fixup_Save_On_Entry()+0x279
>> #
>> # Core dump will be written. Default location: Core dumps may be processed with "/usr/share/apport/apport %p %s %c %d %P %E" (or dumping to /home/jatinbha/sandboxes/jdk-trunk/jdk/make/core.1961256)
>> #
>> # An error report file with more information is saved as:
>> # /home/jatinbha/sandboxes/jdk-trunk/jdk/make/hs_err_pid1961256.log
>>    ... (rest of output omitted)
>> 
>> * All command lines available in /home/jatinbha/sandboxes/jdk-trunk/jdk/build/linux-x86_64-server-fastdebug/make-support/failure-logs.
>
> @jatin-bhateja Thanks for the bug report! I was able to reproduce it on my system as well. I apologize for the late response, I had been busy with my studies and only had a chance to look recently. It looks like this bug is caused because we run `Identity()` on all of the nodes, which finds new optimizations by replacing `LoadNode`s with a non-load identity. This causes an uncommon trap branch to be optimized out and the `HaltNode` replaced with a TOP `ConNode`. Usually these are removed by `RootNode::Ideal`, but since we don't do regular `Ideal` in lowering it ends up running into an assert later.
> 
> This is interesting because it suggests that there are potentially calls to `Identity()` that aren't run in earlier IGVN rounds. I didn't take a very in-depth look but it might be good to investigate separately. Because of that I'm not sure if we can rely on `Identity()` here, especially if there are identity transforms that rely on other `Ideal` calls. @merykitty do you have any thoughts on the best way to fix this?
> 
> @eme64 Ah, do you mean the recursive reduction op generation based on vector length? I think that could be handled here as well by splitting the reduction operation into multiple backend-specific nodes. It would still need to be implemented per-backend, but there could be benefits with optimizing more complex reductions, as you mention.

@jaskarth That's really interesting, it indeed seems like a missed transformation to me. I think adding an IGVN verification where we verify that no other transformation can take place after an IGVN transformation would catch this, what do you think @eme64 ?

For this PR, my optimalist side tells me that you can try repeatedly applying IGVN until there is no further progress. It may be cheap since there should be few to none transformations left. If that sounds inelegant a possible approach is to refactor the `Identity` call into an `apply_identity` similar to `apply_ideal` where you can override it with a method that always returns the current node until the missed transformation is fixed. IMO in principle, there should not be cases where we legitimately depend on `Ideal` to be invoked after `Identity` like this case.

-------------

PR Comment: https://git.openjdk.org/jdk/pull/21599#issuecomment-2536418534


More information about the hotspot-compiler-dev mailing list