On Fri, 7 Aug 2026 03:16:56 GMT, Eric Fang <[email protected]> wrote:

>> The expression `(A & B) ^ B` is algebraically equivalent to `~A & B`, which 
>> maps directly to the AArch64 `BIC` (bit clear) instruction.
>> 
>> Now the expression is lowered as two operations `AndV` and `XorV`, this 
>> patch adds C2 match rules to fold this pattern into a single `BIC` for both 
>> integral vectors and vector masks on AArch64 (NEON and SVE). JMH 
>> micro-benchmarks demonstrate a significant performance improvement.
>> 
>> On a Nvidia Grace (Neoverse-V2) machine with 128-bit SVE2:
>> <html xmlns:v="urn:schemas-microsoft-com:vml"
>> xmlns:o="urn:schemas-microsoft-com:office:office"
>> xmlns:x="urn:schemas-microsoft-com:office:excel"
>> xmlns="http://www.w3.org/TR/REC-html40";>
>> 
>> <head>
>> 
>> <meta name=ProgId content=Excel.Sheet>
>> <meta name=Generator content="Microsoft Excel 15">
>> <link id=Main-File rel=Main-File
>> href="file:////Users/erfang/Library/Group%20Containers/UBF8T346G9.Office/TemporaryItems/msohtmlclip/clip.htm">
>> <link rel=File-List
>> href="file:////Users/erfang/Library/Group%20Containers/UBF8T346G9.Office/TemporaryItems/msohtmlclip/clip_filelist.xml">
>> 
>> </head>
>> 
>> <body link="#467886" vlink="#96607D">
>> 
>> 
>> Benchmark | size | Unit | Before | Error | After | Error | Uplift
>> -- | -- | -- | -- | -- | -- | -- | --
>> LogicOperationsBenchmark.byteNotAnd | 1024 | ops/ms | 20769.0 | 49.6 | 
>> 52065.1 | 684.0 | 2.51
>> LogicOperationsBenchmark.intNotAnd | 1024 | ops/ms | 3576.6 | 0.4 | 7980.8 | 
>> 4.0 | 2.23
>> LogicOperationsBenchmark.longNotAnd | 1024 | ops/ms | 1699.1 | 0.6 | 3575.1 
>> | 0.6 | 2.10
>> LogicOperationsBenchmark.shortNotAnd | 1024 | ops/ms | 7986.0 | 3.4 | 
>> 20523.8 | 13.6 | 2.57
>> MaskLogicOperationsBenchmark.byteMaskNotAnd | 256 | ops/ms | 82165.6 | 70.1 
>> | 108802.4 | 169.4 | 1.32
>> MaskLogicOperationsBenchmark.byteMaskNotAnd | 512 | ops/ms | 42859.7 | 27.1 
>> | 59531.1 | 65.5 | 1.39
>> MaskLogicOperationsBenchmark.byteMaskNotAnd | 1024 | ops/ms | 21703.1 | 9.3 
>> | 31475.2 | 5.5 | 1.45
>> MaskLogicOperationsBenchmark.intMaskNotAnd | 256 | ops/ms | 15467.4 | 50.9 | 
>> 27138.2 | 76.1 | 1.75
>> MaskLogicOperationsBenchmark.intMaskNotAnd | 512 | ops/ms | 7951.4 | 14.9 | 
>> 13962.2 | 4.9 | 1.76
>> MaskLogicOperationsBenchmark.intMaskNotAnd | 1024 | ops/ms | 3988.2 | 4.1 | 
>> 6876.1 | 2.1 | 1.72
>> MaskLogicOperationsBenchmark.longMaskNotAnd | 256 | ops/ms | 7933.8 | 6.4 | 
>> 13933.2 | 6.6 | 1.76
>> MaskLogicOperationsBenchmark.longMaskNotAnd | 512 | ops/ms | 3977.9 | 4.0 | 
>> 6865.8 | 4.2 | 1.73
>> MaskLogicOperationsBenchmark.longMaskNotAnd | 1024 | ops/ms | 1992.7 | 1...
>
> Eric Fang 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 three additional commits since 
> the last revision:
> 
>  - Canonicalize "(A & B) ^ B" to "~A & B" in midend
>  - Merge branch 'master' into JDK-8388918-not-and-opt
>  - 8388918: AArch64: Optimize vector and vector mask (A & B) ^ B to BIC 
> instruction
>    
>    The expression `(A & B) ^ B` is algebraically equivalent to `~A & B`,
>    which maps directly to the AArch64 `BIC` (bit clear) instruction.
>    
>    Now the expression is lowered as two operations `AndV` and `XorV`, this
>    patch adds C2 match rules to fold this pattern into a single `BIC` for
>    both integral vectors and vector masks on AArch64 (NEON and SVE). JMH
>    micro-benchmarks demonstrate a significant performance improvement.
>    
>    On a Nvidia Grace (Neoverse-V2) machine with 128-bit SVE2:
>    ```
>    Benchmark                                  size    Unit    Before  Error   
> After   Error   Uplift
>    LogicOperationsBenchmark.byteNotAnd                1024    ops/ms  20769.0 
> 49.6    52065.1 684.0   2.51
>    LogicOperationsBenchmark.intNotAnd         1024    ops/ms  3576.6  0.4     
> 7980.8  4.0     2.23
>    LogicOperationsBenchmark.longNotAnd                1024    ops/ms  1699.1  
> 0.6     3575.1  0.6     2.10
>    LogicOperationsBenchmark.shortNotAnd               1024    ops/ms  7986.0  
> 3.4     20523.8 13.6    2.57
>    MaskLogicOperationsBenchmark.byteMaskNotAnd        256     ops/ms  82165.6 
> 70.1    108802  169.4   1.32
>    MaskLogicOperationsBenchmark.byteMaskNotAnd        512     ops/ms  42859.7 
> 27.1    59531.1 65.5    1.39
>    MaskLogicOperationsBenchmark.byteMaskNotAnd        1024    ops/ms  21703.1 
> 9.3     31475.2 5.5     1.45
>    MaskLogicOperationsBenchmark.intMaskNotAnd 256     ops/ms  15467.4 50.9    
> 27138.2 76.1    1.75
>    MaskLogicOperationsBenchmark.intMaskNotAnd 512     ops/ms  7951.4  14.9    
> 13962.2 4.9     1.76
>    MaskLogicOperationsBenchmark.intMaskNotAnd 1024    ops/ms  3988.2  4.1     
> 6876.1  2.1     1.72
>    MaskLogicOperationsBenchmark.longMaskNotAnd        256     ops/ms  7933.8  
> 6.4     13933.2 6.6     1.76
>    MaskLogicOperationsBenchmark.longMaskNotAnd        512     ops/ms  3977.9  
> 4.0     6865.8  4.2     1.73
>    MaskLogicOperationsBenchmark.longMaskNotAnd        1024    ops/ms  1992.7  
> 1.2     3400.5  1.7     1.71
>    MaskLogicOperationsBenchmark.shortMaskNotAnd       256     ops/ms  30460.9 
> 35.2    52855.5 30.4    1.74
>    MaskLogicOperationsBenchmark.shortMaskNotAnd       512     ops/ms  15430.4 
> 37.9    26508.9 33.5    1.72
>    MaskLogicOperationsBenchmark.shortMaskNotAnd       1024    ops/ms  8064.8  
> 14.7    13846.5 4.9     1.72
>    ```
>    
>    On an AWS Graviton3 (Neoverse-V1) machine with 256-bit SVE1:
>    ```
>    Benchmark                                  size    Unit...

Hi @dean-long @theRealAph I changed the implementation into midend, in this way 
we don't need to add any new backend rules, would you mind taking another look, 
thanks~

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

PR Comment: https://git.openjdk.org/jdk/pull/32095#issuecomment-5211856964

Reply via email to