> 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 | ...
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 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 ``` On a Nvidia Grace (Neoverse-V2) machine with NEON: ``` 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 132525 612.7 139916 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 ``` The PR was tested on AArch64 (with SVE2, SVE1 and NEON) and X86 (AVX3, AVX2) platforms, all tests (tier1, tier2 and tier3) passed. ------------- Changes: - all: https://git.openjdk.org/jdk/pull/32095/files - new: https://git.openjdk.org/jdk/pull/32095/files/b7d755c8..c40310f1 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=32095&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=32095&range=00-01 Stats: 225501 lines in 2208 files changed: 207614 ins; 5988 del; 11899 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
