On Thu, 30 Jul 2026 02:19:09 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.2 | > 3400.5 | 1.7 | 1.71 > MaskLogicOperationsBenchmark.shortMaskNotAnd | 256 | ... Wouldn't canonicalizing this form earlier in C2 be a better fix? ------------- PR Comment: https://git.openjdk.org/jdk/pull/32095#issuecomment-5141060245
