llvm / llvm/llvm-project

[X86] Implement `vgf2p8mulb(x, splat(C))` using `vgf2p8affineqb` to allow for more optimization opportunities

Open
#196,878 1 comment 0 reactions 0 assignees View on GitHub
backend:X86 llvm:SelectionDAG missed-optimization
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

Although they have the same performance characteristics, `vgf2p8affineqb` has the ability to perform arbitrary XOR permutations allowing it to be folded with many other operations (see #178795, #179607, #178785, #190502). This would benefit AES-style pipelines that mix `vgf2p8affineqb` and `vgf2p8mulb` or when used with common cryptographic primitives (rotates, bit reversals, and general bitwise operations).

```asm
gfMulNot_src:
gf2p8mulb xmm0, xmmword ptr [rip + .LCPI0_0]
pcmpeqd xmm1, xmm1
pxor xmm0, xmm1
ret
```

```asm
gfMulNot_tgt:
gf2p8affineqb xmm0, xmmword ptr [rip + .LCPI1_0], 255
ret
```

https://godbolt.org/z/8fvPoGGvv

The affine matrix for such multiply can be calculated using the following logic. This was derived from its pseudocode code and verified on hardware using every 8-bit pair:

```
u64 getMatrixForGF2P8Mul(u8 term) {
const u64 BASIS_MATRIX[] = [
0x0102040810204080,
0x8081028488102040,
0x40c08142c4881020,
0x2060c0a162c48810,
0x103060d0b162c488,
0x889830e858b162c4,
0xc44c98f42c58b162,
0x62a64cfa962c58b1
]

u64 matrix = 0
for i FROM 0...7 {
matrix ^= term.bit[i]? BASIS_MATRIX[i] : 0
}

return matrix
}
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.