[X86] Constant-fold `vcvtps2ph` when the observed lane is compile-time constant
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
## Summary
LLVM IR currently retains an exact constant F16C conversion followed by a
direct lane-zero extraction:
```llvm
%packed = call <8 x i16> @llvm.x86.vcvtps2ph.128(
<4 x float> , i32 0)
%lane0 = extractelement <8 x i16> %packed, i64 0
ret i16 %lane0
```
For this fixed input and immediate, the observed lane is the binary16 bit
pattern for `1.0`, `0x3c00` (`i16 15360`). The expected result is:
```llvm
ret i16 15360
```
The current `default` planning replay leaves the intrinsic and extract in
place.
## Corpus evidence
An ONNX Runtime x86-64-v4 optimized module contains:
- 32 exact `vcvtps2ph.128` calls with the constant vector
`<1.0, 0.0, 0.0, 0.0>` and immediate zero.
- 8 direct lane-zero `i16` consumers matching this issue's narrow relation.
- The representative current-O3 form retains both the intrinsic and
`extractelement`.
The packet deliberately excludes full-vector/bitcast consumers, other
constants, other lanes, other immediates, masked forms, dynamic inputs, and
constrained-FP cases.
## Relevant prior work
[LLVM PR #162295](https://github.com/llvm/llvm-project/pull/162295),
`[X86][Clang] Allow constexpr evaluation of F16C CVTPS2PH intrinsics`, adds
constexpr handling for the 128-bit and 256-bit Clang F16C builtins. The change
is useful precedent but is not an LLVM IR optimization patch.
The PR's implementation establishes the relevant semantic shape:
- the builtin is marked `Constexpr`;
- the interpreter converts each source element with `APFloat::convert`;
- immediate bits 0-1 select nearest, toward-negative, toward-positive, or
toward-zero rounding;
- immediate bit 2 selects MXCSR rounding behavior;
- constrained floating-point evaluation with MXCSR rounding is accepted only
when the conversion is exact;
- wider destination vectors are zero-filled in the remaining lanes;
- Clang tests cover constant vector results and rounding cases.
This suggests that an IR-level constant folder or target-intrinsic simplifier
could use an equivalent, well-defined semantic path for fully constant inputs,
subject to the same immediate and constrained-FP restrictions.
## Performance impact
The exact minimized source/target pair passes the x86-64-v4 CostGate:
| Metric | Source | Proposed | Change |
|---|---:|---:|---:|
| body instructions per iteration | 7 | 5 | -2 |
| LLVM-MCA uOps / 100 iterations | 1300 | 1000 | -300 |
| LLVM-MCA cycles / 100 iterations | 263 | 209 | -54 |
| block reciprocal throughput | 2.2 | 1.7 | -0.5 |
| `.text` bytes | 24 | 10 | -14 |
| read-only constant bytes | 4 | 0 | -4 |
| total counted object-section bytes | 28 | 10 | -18 |
The source emits a constant-pool load, `vcvtps2ph`, and a vector-to-GPR
transfer. The proposed form is one immediate `movw`.
These are static x86-64-v4 code-generation and llvm-mca results, not an
application-level benchmark.
Contributor guide
Assessment
This issue has not been assessed yet.