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.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 </body> </html> On an AWS Graviton3 (Neoverse-V1) machine with 256-bit SVE1: <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 | 35793.9 | 6.5 | 64358.5 | 42.6 | 1.80 LogicOperationsBenchmark.intNotAnd | 1024 | ops/ms | 5892.5 | 1.8 | 14042.4 | 1.5 | 2.38 LogicOperationsBenchmark.longNotAnd | 1024 | ops/ms | 2722.2 | 0.4 | 5889.9 | 1.1 | 2.16 LogicOperationsBenchmark.shortNotAnd | 1024 | ops/ms | 14096.6 | 6.8 | 30413.2 | 17.7 | 2.16 MaskLogicOperationsBenchmark.byteMaskNotAnd | 256 | ops/ms | 53505.2 | 83.4 | 72209.9 | 493.7 | 1.35 MaskLogicOperationsBenchmark.byteMaskNotAnd | 512 | ops/ms | 28833.3 | 129.2 | 37787.6 | 29.0 | 1.31 MaskLogicOperationsBenchmark.byteMaskNotAnd | 1024 | ops/ms | 15157.6 | 23.0 | 19666.3 | 22.7 | 1.30 MaskLogicOperationsBenchmark.intMaskNotAnd | 256 | ops/ms | 14977.2 | 65.2 | 19980.3 | 33.6 | 1.33 MaskLogicOperationsBenchmark.intMaskNotAnd | 512 | ops/ms | 7737.0 | 3.8 | 10200.4 | 15.7 | 1.32 MaskLogicOperationsBenchmark.intMaskNotAnd | 1024 | ops/ms | 3921.8 | 1.6 | 5195.8 | 11.2 | 1.32 MaskLogicOperationsBenchmark.longMaskNotAnd | 256 | ops/ms | 7796.8 | 15.0 | 10178.0 | 11.2 | 1.31 MaskLogicOperationsBenchmark.longMaskNotAnd | 512 | ops/ms | 3884.9 | 0.4 | 5174.7 | 3.7 | 1.33 MaskLogicOperationsBenchmark.longMaskNotAnd | 1024 | ops/ms | 1865.3 | 2.7 | 2556.7 | 8.3 | 1.37 MaskLogicOperationsBenchmark.shortMaskNotAnd | 256 | ops/ms | 28326.7 | 37.3 | 37997.8 | 406.9 | 1.34 MaskLogicOperationsBenchmark.shortMaskNotAnd | 512 | ops/ms | 14864.5 | 29.7 | 20060.8 | 76.7 | 1.35 MaskLogicOperationsBenchmark.shortMaskNotAnd | 1024 | ops/ms | 7600.4 | 9.8 | 10281.7 | 21.5 | 1.35 </body> </html> On a Nvidia Grace (Neoverse-V2) machine with NEON: <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 | 20835.0 | 118.2 | 52623.3 | 926.7 | 2.53 LogicOperationsBenchmark.intNotAnd | 1024 | ops/ms | 3557.0 | 2.4 | 7942.8 | 6.6 | 2.23 LogicOperationsBenchmark.longNotAnd | 1024 | ops/ms | 1691.3 | 1.8 | 3561.8 | 3.7 | 2.11 LogicOperationsBenchmark.shortNotAnd | 1024 | ops/ms | 7953.2 | 8.5 | 20472.2 | 16.5 | 2.57 MaskLogicOperationsBenchmark.byteMaskNotAnd | 256 | ops/ms | 132524.5 | 612.7 | 139916.1 | 6617.6 | 1.06 MaskLogicOperationsBenchmark.byteMaskNotAnd | 512 | ops/ms | 69445.0 | 35.0 | 78484.9 | 402.9 | 1.13 MaskLogicOperationsBenchmark.byteMaskNotAnd | 1024 | ops/ms | 35659.9 | 181.1 | 38741.8 | 235.2 | 1.09 MaskLogicOperationsBenchmark.intMaskNotAnd | 256 | ops/ms | 16553.8 | 16.1 | 18701.7 | 82.4 | 1.13 MaskLogicOperationsBenchmark.intMaskNotAnd | 512 | ops/ms | 8312.9 | 5.3 | 9371.1 | 23.7 | 1.13 MaskLogicOperationsBenchmark.intMaskNotAnd | 1024 | ops/ms | 4174.3 | 1.0 | 4639.7 | 17.3 | 1.11 MaskLogicOperationsBenchmark.longMaskNotAnd | 256 | ops/ms | 6442.5 | 8.6 | 6768.9 | 3.6 | 1.05 MaskLogicOperationsBenchmark.longMaskNotAnd | 512 | ops/ms | 3239.7 | 3.9 | 3390.9 | 1.2 | 1.05 MaskLogicOperationsBenchmark.longMaskNotAnd | 1024 | ops/ms | 1620.9 | 1.7 | 1690.5 | 2.0 | 1.04 MaskLogicOperationsBenchmark.shortMaskNotAnd | 256 | ops/ms | 46164.5 | 236.9 | 56235.9 | 212.7 | 1.22 MaskLogicOperationsBenchmark.shortMaskNotAnd | 512 | ops/ms | 23326.0 | 57.0 | 28611.9 | 31.3 | 1.23 MaskLogicOperationsBenchmark.shortMaskNotAnd | 1024 | ops/ms | 11711.3 | 9.9 | 14438.7 | 13.5 | 1.23 </body> </html> The PR was tested on AArch64 (with SVE2, SVE1 and NEON) and X86 (AVX3, AVX2) platforms, all tests (tier1, tier2 and tier3) passed. --------- - [x] I confirm that I make this contribution in accordance with the [OpenJDK Interim AI Policy](https://openjdk.org/legal/ai). ------------- Commit messages: - 8388918: AArch64: Optimize vector and vector mask (A & B) ^ B to BIC instruction Changes: https://git.openjdk.org/jdk/pull/32095/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=32095&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8388918 Stats: 638 lines in 7 files changed: 628 ins; 7 del; 3 mod Patch: https://git.openjdk.org/jdk/pull/32095.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/32095/head:pull/32095 PR: https://git.openjdk.org/jdk/pull/32095
