llvm / llvm/llvm-project

[X86] Form PEXT for canonical v4i8 low-two-bit packing

Open
#215,085 2 comments 0 reactions 1 assignee Claimed by @RKSimon 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

## Summary

LLVM currently retains the following pattern after `default`:

```llvm
%shifted = shl <4 x i8> %x,
%masked = and <4 x i8> %shifted,
%packed = call i8 @llvm.vector.reduce.or.v4i8(<4 x i8> %masked)
```

On X86's little-endian layout, this is equivalent to:

```llvm
%bits = bitcast <4 x i8> %x to i32
%extracted = call i32 @llvm.pext.i32(i32 %bits, i32 50529027)
%packed = trunc i32 %extracted to i8
```

`50529027` is `0x03030303`. It selects bits `0..1` from each byte and packs
them into result bits `0..7`, producing:

```text
(x[0] & 3)
| ((x[1] & 3) << 2)
| ((x[2] & 3) << 4)
| ((x[3] & 3) << 6)
```

This looks suitable for an X86 target-aware combine when i32 PEXT is both legal
and profitable.

## Motivation

A complete optimized corpus contains 26 occurrences across five functions in
three ONNX Runtime x86-64-v4 modules. They all belong to the same `Int2x4`
packing lineage.

For the isolated x86-64-v4 case, the manually formed PEXT version lowers to:

```asm
vmovd %xmm0, %eax
movl $50529027, %ecx
pextl %ecx, %eax, %eax
retq
```

Local static measurements were:

| Metric | Current | PEXT |
| ------------------------------ | ------: | ---: |
| Executable instructions | 11 | 4 |
| `.text` bytes | 57 | 15 |
| Block reciprocal throughput | 3.2 | 1.0 |

These are code-generation and llvm-mca results, not application-level
benchmarks.

## Validation

The exact source and target relations were proven equivalent in both directions
with Alive2 for arbitrary `<4 x i8> %x`.

The current `default` pipeline retains the source form, while the explicit
`llvm.pext.i32` form selects native `pextl` for the tested x86-64-v4 target.

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.