On Tue, 30 Jun 2026 16:36:50 GMT, Galder Zamarreño <[email protected]> wrote:

>> This PR introduces the basic Ideal/Identity transformations for 
>> `VectorBlendNode`.
>> 
>> The semantic of `VectorBlend(X, Y, M)` is: `M ? Y : X`.
>> 
>> **Identity**:
>> 
>>   (VectorBlend X Y (Replicate -1)) => Y
>>   (VectorBlend X Y (MaskAll   -1)) => Y
>>   (VectorBlend X Y (Replicate  0)) => X
>>   (VectorBlend X Y (MaskAll    0)) => X
>> 
>> 
>> **Ideal**:
>> 
>>   (VectorBlend (VectorBlend X A M) B M)  => (VectorBlend X B M)
>>   (VectorBlend A (VectorBlend B X M) M)  => (VectorBlend A X M)
>>   (VectorBlend A B (XorV/XorVMask M -1)) => (VectorBlend B A M)
>> 
>> 
>> Also corrects the VectorBlendNode header comment: across all backends (X86 
>> SSE/AVX, AArch64 NEON/SVE, RISC-V V) the active mask lane selects `vec2` 
>> (in(2)), and the inactive lane selects `vec1` (in(1)).
>> 
>> JTReg and JMH tests are also added for each optimization pattern. All tests 
>> (tier1, tier2, and tier3) passed on AArch64 and X86 platforms.
>> 
>> JMH benchmark test results:
>> 
>> On a Nvidia Grace (Neoverse-V2) machine with 128-bit SVE2:
>> 
>> Benchmark                    Unit    Before  Error   After           Error   
>> Uplift
>> blendNegatedMaskInt      ops/ms      7990.6  2.8         10215.2             
>> 11.0    1.3
>> identityAllOnesInt       ops/ms      3574.8  2.6         7967.1              
>> 0.3         2.2
>> identityAllZerosLong ops/ms  3575.6  1.0         7966.0              3.6     
>>     2.2
>> nestedBlendInnerLong ops/ms  3533.8  2.8         478573.0    3178.5  135.4
>> nestedBlendOuterInt      ops/ms      3537.6  3.4         472242.2    3034.2  
>> 133.5
>> 
>> 
>> On an AWS Graviton3 (Neoverse-V1) machine with 256-bit SVE1:
>> 
>> Benchmark                    Unit    Before  Error   After           Error   
>> Uplift
>> blendNegatedMaskInt      ops/ms      5171.9  5.2         8129.0              
>> 17.3    1.6
>> identityAllOnesInt       ops/ms      2722.0  0.1         5891.3              
>> 0.1         2.2
>> identityAllZerosLong ops/ms  2722.4  0.1         5891.1              0.3     
>>     2.2
>> nestedBlendInnerLong ops/ms  2697.6  0.0         312148.7    2366.4  115.7
>> nestedBlendOuterInt      ops/ms      2702.7  0.1         308686.0    2709.8  
>> 114.2
>> 
>> 
>> On a Nvidia Grace (Neoverse-V2) machine with `-XX:UseSVE=0`:
>> 
>> Benchmark                    Unit    Before  Error   After           Error   
>> Uplift
>> blendNegatedMaskInt      ops/ms      7718.1  1.9         9515.9              
>> 54.0    1.2
>> identityAllOnesInt       ops/ms      3581.9  0.6         8062.5              
>> 0.5         2.3
>> identityAllZerosLong ops/ms  3582.7  0.6         8058.5              11.9    
>> 2.2
>> nestedBlendInnerLong ops/ms  3529.6  1.4         476029.8    5190.2  134.9
>> nestedBlendOuterInt      ops/ms      3536.9  2.1         486060.0    3442.1  
>> 137.4
>> 
>> 
>> On an AMD EPYC 9124 16-Core Processor with option `-XX:UseAVX=3`:
>> 
>> Benchmark                    Unit    Before  Error   After           Error   
>> Uplift
>> blendNegatedMaskInt      ops/ms...
>
> Ah, I see that the types tested are extended in #31379 to cover float and 
> double, but no byte/short/float16?

@galderz Thanks for the review! Yes the test doesn't cover all types, because 
these optimizations apply to all types, I only wrote one test for each 
optimization pattern, instead of a test for each pattern across all types. I 
can extend these tests to all types if you feel it's necessary.

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

PR Comment: https://git.openjdk.org/jdk/pull/31333#issuecomment-4849544038

Reply via email to