llvm / llvm/llvm-project

[AMDGPU][GFX12] llvm.amdgcn.cvt.pk.f32.fp8 selects an e32 form rejected by llvm-mc

Open
#224,032 1 comment 0 reactions 0 assignees View on GitHub
backend:AMDGPU
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

## Summary

When targeting GFX12 (`gfx1200`/`gfx1201`), lowering `llvm.amdgcn.cvt.pk.f32.fp8` with `word_sel=false` selects the e32 form:

```asm
v_cvt_pk_f32_fp8_e32 v[0:1], v0
```

However, the generated instruction is rejected by `llvm-mc` for the same target:

```text
v_cvt_pk_f32_fp8_e32 v[0:1], v0
^ operands are not valid for this GPU or mode
```

Using `word_sel=true` selects the accepted e64 form with `op_sel:[1,0]`.

## Reduced reproducer

```llvm
target triple = "amdgcn-amd-amdhsa"

declare <2 x float> @llvm.amdgcn.cvt.pk.f32.fp8(i32, i1 immarg)

define amdgpu_kernel void @repro(
ptr addrspace(1) %out,
ptr addrspace(1) %in) {
entry:
%src = load i32, ptr addrspace(1) %in, align 4
%result = call <2 x float>
@llvm.amdgcn.cvt.pk.f32.fp8(i32 %src, i1 false)
store <2 x float> %result, ptr addrspace(1) %out, align 8
ret void
}
```

Run:

```shell
llc -O0 -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1200 \
-filetype=asm repro.ll -o repro.s

llvm-mc -triple=amdgcn-amd-amdhsa -mcpu=gfx1200 \
-filetype=obj repro.s -o repro.o
```

The same behavior is observed with `-mcpu=gfx1201`.

## Actual behavior

`llc` selects `v_cvt_pk_f32_fp8_e32` when `word_sel=false`, but the emitted instruction cannot be assembled by `llvm-mc` for GFX12.

## Expected behavior

Assembly emitted by `llc` should be accepted by `llvm-mc` for the same target while preserving the `word_sel=false` semantics.

The selector and assembler should agree on whether the e32 form is valid for GFX12. If it is not valid, LLVM should select an appropriate e64 encoding.

## Impact

This blocks the straightforward use of the hardware OCP E4M3FN upcast path in Triton on RDNA4.

Triton currently needs a workaround that shifts the packed low word into the high half and invokes the conversion with `word_sel=true`, forcing LLVM to select the e64 form. This adds one shift per four FP8 inputs.

## Related issues and PRs

- Triton PR: https://github.com/triton-lang/triton/pull/11809
- Original Triton issue: https://github.com/triton-lang/triton/issues/11497
- Earlier GFX12 FP8 support: https://github.com/llvm/llvm-project/issues/78414

Contributor guide

Open the contributing guide

Research direction

Start by running the reduced reproducer through llc and then llvm-mc for gfx1200 and gfx1201, comparing the emitted e32 and accepted e64 forms. Trace the selector and assembler handling for llvm.amdgcn.cvt.pk.f32.fp8 and ensure the emitted assembly is accepted while preserving word_sel=false semantics.

Written by the indexing model from the issue text.

Assessment

Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
50/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.