[llvm] [AMDGPU] Fall back for FP8-to-half conversions without native support (PR #225528)
Chinmay Deshpande via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 22 14:57:59 PDT 2026
https://github.com/chinmaydd updated https://github.com/llvm/llvm-project/pull/225528
>From e0151307066dbfdc94a679e81ae214922c2bb00f Mon Sep 17 00:00:00 2001
From: Chinmay Deshpande <chdeshpa at amd.com>
Date: Tue, 22 Sep 2026 14:56:00 -0700
Subject: [PATCH] [AMDGPU] Fall back for FP8-to-half conversions without native
support
The custom v2i8 source action also handles half results on gfx950, which
has native OCP FP8-to-f32 conversions but lacks FP8-to-f16 instructions.
Converting FP8 vectors to half therefore reached lowerFromFP8 and asserted
that FP8F16ConversionInsts was available.
Use generic legalization for half results when the subtarget lacks the
required instructions. Preserve native f32 conversions and native f16
conversions on targets that support them.
Add a gfx950 run line to the existing FP8-to-f16 test, which already covers
both OCP encodings for scalars and for vectors that widen or split into
pairs.
---
llvm/lib/Target/AMDGPU/SIISelLowering.cpp | 6 +
.../arbitrary-fp-from-float-fp8-f16-hw.ll | 575 ++++++++++++++++++
2 files changed, 581 insertions(+)
diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
index f9a4ba4c1bd1d..b6c15fd76e9e5 100644
--- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
@@ -11144,6 +11144,12 @@ SITargetLowering::LowerCONVERT_FROM_ARBITRARY_FP(SDValue Op,
return SDValue();
EVT DstVT = Op.getValueType();
+ // The custom action for a v2i8 source also reaches half conversions on
+ // targets which only have FP8-to-f32 instructions.
+ if (DstVT.getScalarType() == MVT::f16 &&
+ !Subtarget->hasFP8F16ConversionInsts())
+ return SDValue();
+
if (IsE5M3) {
if (DstVT.getScalarType() != MVT::f32)
return SDValue();
diff --git a/llvm/test/CodeGen/AMDGPU/arbitrary-fp-from-float-fp8-f16-hw.ll b/llvm/test/CodeGen/AMDGPU/arbitrary-fp-from-float-fp8-f16-hw.ll
index f03c9195edbfa..3dc17f783858d 100644
--- a/llvm/test/CodeGen/AMDGPU/arbitrary-fp-from-float-fp8-f16-hw.ll
+++ b/llvm/test/CodeGen/AMDGPU/arbitrary-fp-from-float-fp8-f16-hw.ll
@@ -1,9 +1,12 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
; RUN: llc < %s -mtriple=amdgpu12.50-amd-amdhsa -mattr=+real-true16 | FileCheck -check-prefixes=GFX1250,GFX1250-TRUE16 %s
; RUN: llc < %s -mtriple=amdgpu12.50-amd-amdhsa -mattr=-real-true16 | FileCheck -check-prefixes=GFX1250,GFX1250-FAKE16 %s
+; RUN: llc < %s -mtriple=amdgpu9.50-amd-amdhsa | FileCheck -check-prefix=GFX950 %s
; llvm.convert.from.arbitrary.fp from FP8/BF8 producing f16 result types,
; lowered via the gfx1250+ unscaled v_cvt_{pk_}f16_{fp8,bf8} instructions.
+; gfx950 has native FP8-to-f32 conversions but no FP8-to-f16 ones, so it must
+; fall back to the generic expansion instead of selecting them.
; Scalar Float8E4M3FN
define half @from_fp8_f16_s(i8 %x) {
@@ -20,6 +23,43 @@ define half @from_fp8_f16_s(i8 %x) {
; GFX1250-FAKE16-NEXT: s_wait_kmcnt 0x0
; GFX1250-FAKE16-NEXT: v_cvt_f16_fp8_e32 v0, v0
; GFX1250-FAKE16-NEXT: s_set_pc_i64 s[30:31]
+;
+; GFX950-LABEL: from_fp8_f16_s:
+; GFX950: ; %bb.0:
+; GFX950-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX950-NEXT: v_lshrrev_b16_e32 v4, 3, v0
+; GFX950-NEXT: v_lshlrev_b16_e32 v1, 8, v0
+; GFX950-NEXT: v_and_b32_e32 v2, 7, v0
+; GFX950-NEXT: v_and_b32_e32 v5, 15, v4
+; GFX950-NEXT: v_and_b32_e32 v1, 0xffff8000, v1
+; GFX950-NEXT: v_lshlrev_b16_e32 v3, 7, v2
+; GFX950-NEXT: v_lshlrev_b16_e32 v6, 10, v5
+; GFX950-NEXT: v_bitop3_b16 v3, v6, v3, v1 bitop3:0xfe
+; GFX950-NEXT: v_lshlrev_b32_e32 v6, 16, v2
+; GFX950-NEXT: v_ffbh_u32_e32 v6, v6
+; GFX950-NEXT: v_sub_u16_e32 v7, 15, v6
+; GFX950-NEXT: v_lshlrev_b16_e64 v7, v7, 1
+; GFX950-NEXT: v_bitop3_b16 v0, v0, v7, 7 bitop3:0x6c
+; GFX950-NEXT: v_add_u16_e32 v7, -5, v6
+; GFX950-NEXT: v_sub_u16_e32 v6, 21, v6
+; GFX950-NEXT: v_lshlrev_b16_e32 v0, v7, v0
+; GFX950-NEXT: v_lshlrev_b16_e32 v6, 10, v6
+; GFX950-NEXT: v_cmp_ne_u16_e32 vcc, 0, v2
+; GFX950-NEXT: v_cmp_eq_u16_e64 s[0:1], 0, v5
+; GFX950-NEXT: v_add_u16_e32 v3, 0x2000, v3
+; GFX950-NEXT: v_bitop3_b16 v0, v1, v0, v6 bitop3:0xfe
+; GFX950-NEXT: s_and_b64 vcc, s[0:1], vcc
+; GFX950-NEXT: v_cndmask_b32_e32 v0, v3, v0, vcc
+; GFX950-NEXT: v_bitop3_b16 v3, v4, v2, 15 bitop3:0xec
+; GFX950-NEXT: v_cmp_eq_u16_e32 vcc, 0, v3
+; GFX950-NEXT: v_cmp_eq_u16_e64 s[0:1], 15, v5
+; GFX950-NEXT: s_nop 0
+; GFX950-NEXT: v_cndmask_b32_e32 v0, v0, v1, vcc
+; GFX950-NEXT: v_cmp_eq_u16_e32 vcc, 7, v2
+; GFX950-NEXT: v_mov_b32_e32 v1, 0x7e00
+; GFX950-NEXT: s_and_b64 vcc, s[0:1], vcc
+; GFX950-NEXT: v_cndmask_b32_e32 v0, v0, v1, vcc
+; GFX950-NEXT: s_setpc_b64 s[30:31]
%r = call half @llvm.convert.from.arbitrary.fp.f16.i8(i8 %x, metadata !"Float8E4M3FN")
ret half %r
}
@@ -39,6 +79,33 @@ define half @from_bf8_f16_s(i8 %x) {
; GFX1250-FAKE16-NEXT: s_wait_kmcnt 0x0
; GFX1250-FAKE16-NEXT: v_cvt_f16_bf8_e32 v0, v0
; GFX1250-FAKE16-NEXT: s_set_pc_i64 s[30:31]
+;
+; GFX950-LABEL: from_bf8_f16_s:
+; GFX950: ; %bb.0:
+; GFX950-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX950-NEXT: v_and_b32_e32 v1, 3, v0
+; GFX950-NEXT: v_lshlrev_b16_e32 v3, 8, v0
+; GFX950-NEXT: v_lshrrev_b16_e32 v0, 2, v0
+; GFX950-NEXT: v_and_b32_e32 v5, 31, v0
+; GFX950-NEXT: v_lshlrev_b16_e32 v2, 8, v1
+; GFX950-NEXT: v_and_b32_e32 v4, 0xffff8000, v3
+; GFX950-NEXT: v_lshlrev_b16_e32 v6, 10, v5
+; GFX950-NEXT: v_bitop3_b16 v0, v0, v1, 31 bitop3:0xec
+; GFX950-NEXT: v_bitop3_b16 v2, v4, v2, v6 bitop3:0xfe
+; GFX950-NEXT: v_cmp_eq_u16_e32 vcc, 0, v0
+; GFX950-NEXT: v_cmp_eq_u16_e64 s[0:1], 31, v5
+; GFX950-NEXT: s_movk_i32 s2, 0x7c00
+; GFX950-NEXT: v_cndmask_b32_e32 v0, v2, v4, vcc
+; GFX950-NEXT: v_cmp_eq_u16_e32 vcc, 0, v1
+; GFX950-NEXT: v_mov_b32_e32 v2, 0xffff8000
+; GFX950-NEXT: v_bitop3_b16 v2, v3, s2, v2 bitop3:0xec
+; GFX950-NEXT: s_and_b64 vcc, s[0:1], vcc
+; GFX950-NEXT: v_cndmask_b32_e32 v0, v0, v2, vcc
+; GFX950-NEXT: v_cmp_ne_u16_e32 vcc, 0, v1
+; GFX950-NEXT: v_mov_b32_e32 v1, 0x7e00
+; GFX950-NEXT: s_and_b64 vcc, s[0:1], vcc
+; GFX950-NEXT: v_cndmask_b32_e32 v0, v0, v1, vcc
+; GFX950-NEXT: s_setpc_b64 s[30:31]
%r = call half @llvm.convert.from.arbitrary.fp.f16.i8(i8 %x, metadata !"Float8E5M2")
ret half %r
}
@@ -64,6 +131,75 @@ define <2 x half> @from_fp8_v2f16(<2 x i8> %x) {
; GFX1250-FAKE16-NEXT: v_bitop3_b16 v0, v0, v1, 0xff bitop3:0xec
; GFX1250-FAKE16-NEXT: v_cvt_pk_f16_fp8 v0, v0
; GFX1250-FAKE16-NEXT: s_set_pc_i64 s[30:31]
+;
+; GFX950-LABEL: from_fp8_v2f16:
+; GFX950: ; %bb.0:
+; GFX950-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX950-NEXT: v_lshrrev_b16_e32 v5, 3, v0
+; GFX950-NEXT: v_lshlrev_b16_e32 v2, 8, v0
+; GFX950-NEXT: v_and_b32_e32 v3, 7, v0
+; GFX950-NEXT: v_and_b32_e32 v6, 15, v5
+; GFX950-NEXT: v_and_b32_e32 v2, 0xffff8000, v2
+; GFX950-NEXT: v_lshlrev_b16_e32 v4, 7, v3
+; GFX950-NEXT: v_lshlrev_b16_e32 v7, 10, v6
+; GFX950-NEXT: v_bitop3_b16 v4, v7, v4, v2 bitop3:0xfe
+; GFX950-NEXT: v_lshlrev_b32_e32 v7, 16, v3
+; GFX950-NEXT: v_ffbh_u32_e32 v7, v7
+; GFX950-NEXT: v_sub_u16_e32 v8, 15, v7
+; GFX950-NEXT: v_lshlrev_b16_e64 v8, v8, 1
+; GFX950-NEXT: v_bitop3_b16 v0, v0, v8, 7 bitop3:0x6c
+; GFX950-NEXT: v_add_u16_e32 v8, -5, v7
+; GFX950-NEXT: v_sub_u16_e32 v7, 21, v7
+; GFX950-NEXT: v_lshlrev_b16_e32 v0, v8, v0
+; GFX950-NEXT: v_lshlrev_b16_e32 v7, 10, v7
+; GFX950-NEXT: v_cmp_ne_u16_e32 vcc, 0, v3
+; GFX950-NEXT: v_cmp_eq_u16_e64 s[0:1], 0, v6
+; GFX950-NEXT: v_add_u16_e32 v4, 0x2000, v4
+; GFX950-NEXT: v_bitop3_b16 v0, v2, v0, v7 bitop3:0xfe
+; GFX950-NEXT: s_and_b64 vcc, s[0:1], vcc
+; GFX950-NEXT: v_cndmask_b32_e32 v0, v4, v0, vcc
+; GFX950-NEXT: v_bitop3_b16 v4, v5, v3, 15 bitop3:0xec
+; GFX950-NEXT: v_cmp_eq_u16_e32 vcc, 0, v4
+; GFX950-NEXT: v_cmp_eq_u16_e64 s[0:1], 15, v6
+; GFX950-NEXT: v_lshrrev_b16_e32 v6, 3, v1
+; GFX950-NEXT: v_cndmask_b32_e32 v0, v0, v2, vcc
+; GFX950-NEXT: v_cmp_eq_u16_e32 vcc, 7, v3
+; GFX950-NEXT: v_lshlrev_b16_e32 v3, 8, v1
+; GFX950-NEXT: v_and_b32_e32 v4, 7, v1
+; GFX950-NEXT: v_and_b32_e32 v7, 15, v6
+; GFX950-NEXT: v_and_b32_e32 v3, 0xffff8000, v3
+; GFX950-NEXT: v_lshlrev_b16_e32 v5, 7, v4
+; GFX950-NEXT: v_lshlrev_b16_e32 v8, 10, v7
+; GFX950-NEXT: v_bitop3_b16 v5, v8, v5, v3 bitop3:0xfe
+; GFX950-NEXT: v_lshlrev_b32_e32 v8, 16, v4
+; GFX950-NEXT: v_ffbh_u32_e32 v8, v8
+; GFX950-NEXT: v_sub_u16_e32 v9, 15, v8
+; GFX950-NEXT: v_lshlrev_b16_e64 v9, v9, 1
+; GFX950-NEXT: v_mov_b32_e32 v2, 0x7e00
+; GFX950-NEXT: s_and_b64 vcc, s[0:1], vcc
+; GFX950-NEXT: v_bitop3_b16 v1, v1, v9, 7 bitop3:0x6c
+; GFX950-NEXT: v_add_u16_e32 v9, -5, v8
+; GFX950-NEXT: v_sub_u16_e32 v8, 21, v8
+; GFX950-NEXT: v_cndmask_b32_e32 v0, v0, v2, vcc
+; GFX950-NEXT: v_lshlrev_b16_e32 v1, v9, v1
+; GFX950-NEXT: v_lshlrev_b16_e32 v8, 10, v8
+; GFX950-NEXT: v_cmp_ne_u16_e32 vcc, 0, v4
+; GFX950-NEXT: v_cmp_eq_u16_e64 s[0:1], 0, v7
+; GFX950-NEXT: v_add_u16_e32 v5, 0x2000, v5
+; GFX950-NEXT: v_bitop3_b16 v1, v3, v1, v8 bitop3:0xfe
+; GFX950-NEXT: s_and_b64 vcc, s[0:1], vcc
+; GFX950-NEXT: v_cndmask_b32_e32 v1, v5, v1, vcc
+; GFX950-NEXT: v_bitop3_b16 v5, v6, v4, 15 bitop3:0xec
+; GFX950-NEXT: v_cmp_eq_u16_e32 vcc, 0, v5
+; GFX950-NEXT: v_cmp_eq_u16_e64 s[0:1], 15, v7
+; GFX950-NEXT: s_nop 0
+; GFX950-NEXT: v_cndmask_b32_e32 v1, v1, v3, vcc
+; GFX950-NEXT: v_cmp_eq_u16_e32 vcc, 7, v4
+; GFX950-NEXT: s_and_b64 vcc, s[0:1], vcc
+; GFX950-NEXT: s_mov_b32 s0, 0x5040100
+; GFX950-NEXT: v_cndmask_b32_e32 v1, v1, v2, vcc
+; GFX950-NEXT: v_perm_b32 v0, v1, v0, s0
+; GFX950-NEXT: s_setpc_b64 s[30:31]
%r = call <2 x half> @llvm.convert.from.arbitrary.fp.v2f16.v2i8(<2 x i8> %x, metadata !"Float8E4M3FN")
ret <2 x half> %r
}
@@ -89,6 +225,55 @@ define <2 x half> @from_bf8_v2f16(<2 x i8> %x) {
; GFX1250-FAKE16-NEXT: v_bitop3_b16 v0, v0, v1, 0xff bitop3:0xec
; GFX1250-FAKE16-NEXT: v_cvt_pk_f16_bf8 v0, v0
; GFX1250-FAKE16-NEXT: s_set_pc_i64 s[30:31]
+;
+; GFX950-LABEL: from_bf8_v2f16:
+; GFX950: ; %bb.0:
+; GFX950-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX950-NEXT: v_and_b32_e32 v2, 3, v0
+; GFX950-NEXT: v_lshlrev_b16_e32 v4, 8, v0
+; GFX950-NEXT: v_lshrrev_b16_e32 v0, 2, v0
+; GFX950-NEXT: v_and_b32_e32 v6, 31, v0
+; GFX950-NEXT: v_lshlrev_b16_e32 v3, 8, v2
+; GFX950-NEXT: v_and_b32_e32 v5, 0xffff8000, v4
+; GFX950-NEXT: v_lshlrev_b16_e32 v7, 10, v6
+; GFX950-NEXT: v_bitop3_b16 v0, v0, v2, 31 bitop3:0xec
+; GFX950-NEXT: v_bitop3_b16 v3, v5, v3, v7 bitop3:0xfe
+; GFX950-NEXT: v_cmp_eq_u16_e32 vcc, 0, v0
+; GFX950-NEXT: v_cmp_eq_u16_e64 s[0:1], 31, v6
+; GFX950-NEXT: s_movk_i32 s2, 0x7c00
+; GFX950-NEXT: v_cndmask_b32_e32 v0, v3, v5, vcc
+; GFX950-NEXT: v_cmp_eq_u16_e32 vcc, 0, v2
+; GFX950-NEXT: v_mov_b32_e32 v3, 0xffff8000
+; GFX950-NEXT: v_bitop3_b16 v4, v4, s2, v3 bitop3:0xec
+; GFX950-NEXT: s_and_b64 vcc, s[0:1], vcc
+; GFX950-NEXT: v_cndmask_b32_e32 v0, v0, v4, vcc
+; GFX950-NEXT: v_and_b32_e32 v4, 3, v1
+; GFX950-NEXT: v_lshlrev_b16_e32 v6, 8, v1
+; GFX950-NEXT: v_lshrrev_b16_e32 v1, 2, v1
+; GFX950-NEXT: v_cmp_ne_u16_e32 vcc, 0, v2
+; GFX950-NEXT: v_and_b32_e32 v8, 31, v1
+; GFX950-NEXT: v_mov_b32_e32 v2, 0x7e00
+; GFX950-NEXT: s_and_b64 vcc, s[0:1], vcc
+; GFX950-NEXT: v_lshlrev_b16_e32 v5, 8, v4
+; GFX950-NEXT: v_and_b32_e32 v7, 0xffff8000, v6
+; GFX950-NEXT: v_lshlrev_b16_e32 v9, 10, v8
+; GFX950-NEXT: v_bitop3_b16 v1, v1, v4, 31 bitop3:0xec
+; GFX950-NEXT: v_cndmask_b32_e32 v0, v0, v2, vcc
+; GFX950-NEXT: v_bitop3_b16 v5, v7, v5, v9 bitop3:0xfe
+; GFX950-NEXT: v_cmp_eq_u16_e32 vcc, 0, v1
+; GFX950-NEXT: v_cmp_eq_u16_e64 s[0:1], 31, v8
+; GFX950-NEXT: v_bitop3_b16 v3, v6, s2, v3 bitop3:0xec
+; GFX950-NEXT: v_cndmask_b32_e32 v1, v5, v7, vcc
+; GFX950-NEXT: v_cmp_eq_u16_e32 vcc, 0, v4
+; GFX950-NEXT: s_and_b64 vcc, s[0:1], vcc
+; GFX950-NEXT: s_nop 0
+; GFX950-NEXT: v_cndmask_b32_e32 v1, v1, v3, vcc
+; GFX950-NEXT: v_cmp_ne_u16_e32 vcc, 0, v4
+; GFX950-NEXT: s_and_b64 vcc, s[0:1], vcc
+; GFX950-NEXT: s_mov_b32 s0, 0x5040100
+; GFX950-NEXT: v_cndmask_b32_e32 v1, v1, v2, vcc
+; GFX950-NEXT: v_perm_b32 v0, v1, v0, s0
+; GFX950-NEXT: s_setpc_b64 s[30:31]
%r = call <2 x half> @llvm.convert.from.arbitrary.fp.v2f16.v2i8(<2 x i8> %x, metadata !"Float8E5M2")
ret <2 x half> %r
}
@@ -120,6 +305,106 @@ define <3 x half> @from_fp8_v3f16(<3 x i8> %x) {
; GFX1250-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2)
; GFX1250-FAKE16-NEXT: v_cvt_pk_f16_fp8 v1, v1
; GFX1250-FAKE16-NEXT: s_set_pc_i64 s[30:31]
+;
+; GFX950-LABEL: from_fp8_v3f16:
+; GFX950: ; %bb.0:
+; GFX950-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX950-NEXT: v_lshrrev_b16_e32 v6, 3, v2
+; GFX950-NEXT: v_lshlrev_b16_e32 v3, 8, v2
+; GFX950-NEXT: v_and_b32_e32 v4, 7, v2
+; GFX950-NEXT: v_and_b32_e32 v7, 15, v6
+; GFX950-NEXT: v_and_b32_e32 v3, 0xffff8000, v3
+; GFX950-NEXT: v_lshlrev_b16_e32 v5, 7, v4
+; GFX950-NEXT: v_lshlrev_b16_e32 v8, 10, v7
+; GFX950-NEXT: v_bitop3_b16 v5, v8, v5, v3 bitop3:0xfe
+; GFX950-NEXT: v_lshlrev_b32_e32 v8, 16, v4
+; GFX950-NEXT: v_ffbh_u32_e32 v8, v8
+; GFX950-NEXT: v_sub_u16_e32 v9, 15, v8
+; GFX950-NEXT: v_lshlrev_b16_e64 v9, v9, 1
+; GFX950-NEXT: v_bitop3_b16 v2, v2, v9, 7 bitop3:0x6c
+; GFX950-NEXT: v_add_u16_e32 v9, -5, v8
+; GFX950-NEXT: v_sub_u16_e32 v8, 21, v8
+; GFX950-NEXT: v_lshlrev_b16_e32 v2, v9, v2
+; GFX950-NEXT: v_lshlrev_b16_e32 v8, 10, v8
+; GFX950-NEXT: v_cmp_ne_u16_e32 vcc, 0, v4
+; GFX950-NEXT: v_cmp_eq_u16_e64 s[0:1], 0, v7
+; GFX950-NEXT: v_add_u16_e32 v5, 0x2000, v5
+; GFX950-NEXT: v_bitop3_b16 v2, v3, v2, v8 bitop3:0xfe
+; GFX950-NEXT: s_and_b64 vcc, s[0:1], vcc
+; GFX950-NEXT: v_cndmask_b32_e32 v2, v5, v2, vcc
+; GFX950-NEXT: v_bitop3_b16 v5, v6, v4, 15 bitop3:0xec
+; GFX950-NEXT: v_cmp_eq_u16_e32 vcc, 0, v5
+; GFX950-NEXT: v_cmp_eq_u16_e64 s[0:1], 15, v7
+; GFX950-NEXT: v_lshrrev_b16_e32 v7, 3, v0
+; GFX950-NEXT: v_cndmask_b32_e32 v2, v2, v3, vcc
+; GFX950-NEXT: v_cmp_eq_u16_e32 vcc, 7, v4
+; GFX950-NEXT: v_lshlrev_b16_e32 v4, 8, v0
+; GFX950-NEXT: v_and_b32_e32 v5, 7, v0
+; GFX950-NEXT: v_and_b32_e32 v8, 15, v7
+; GFX950-NEXT: v_and_b32_e32 v4, 0xffff8000, v4
+; GFX950-NEXT: v_lshlrev_b16_e32 v6, 7, v5
+; GFX950-NEXT: v_lshlrev_b16_e32 v9, 10, v8
+; GFX950-NEXT: v_bitop3_b16 v6, v9, v6, v4 bitop3:0xfe
+; GFX950-NEXT: v_lshlrev_b32_e32 v9, 16, v5
+; GFX950-NEXT: v_ffbh_u32_e32 v9, v9
+; GFX950-NEXT: v_sub_u16_e32 v10, 15, v9
+; GFX950-NEXT: v_lshlrev_b16_e64 v10, v10, 1
+; GFX950-NEXT: v_mov_b32_e32 v3, 0x7e00
+; GFX950-NEXT: s_and_b64 vcc, s[0:1], vcc
+; GFX950-NEXT: v_bitop3_b16 v0, v0, v10, 7 bitop3:0x6c
+; GFX950-NEXT: v_add_u16_e32 v10, -5, v9
+; GFX950-NEXT: v_sub_u16_e32 v9, 21, v9
+; GFX950-NEXT: v_cndmask_b32_e32 v2, v2, v3, vcc
+; GFX950-NEXT: v_lshlrev_b16_e32 v0, v10, v0
+; GFX950-NEXT: v_lshlrev_b16_e32 v9, 10, v9
+; GFX950-NEXT: v_cmp_ne_u16_e32 vcc, 0, v5
+; GFX950-NEXT: v_cmp_eq_u16_e64 s[0:1], 0, v8
+; GFX950-NEXT: v_add_u16_e32 v6, 0x2000, v6
+; GFX950-NEXT: v_bitop3_b16 v0, v4, v0, v9 bitop3:0xfe
+; GFX950-NEXT: s_and_b64 vcc, s[0:1], vcc
+; GFX950-NEXT: v_cndmask_b32_e32 v0, v6, v0, vcc
+; GFX950-NEXT: v_bitop3_b16 v6, v7, v5, 15 bitop3:0xec
+; GFX950-NEXT: v_cmp_eq_u16_e32 vcc, 0, v6
+; GFX950-NEXT: v_lshrrev_b16_e32 v7, 3, v1
+; GFX950-NEXT: v_cmp_eq_u16_e64 s[0:1], 15, v8
+; GFX950-NEXT: v_cndmask_b32_e32 v0, v0, v4, vcc
+; GFX950-NEXT: v_cmp_eq_u16_e32 vcc, 7, v5
+; GFX950-NEXT: v_lshlrev_b16_e32 v4, 8, v1
+; GFX950-NEXT: v_and_b32_e32 v5, 7, v1
+; GFX950-NEXT: v_and_b32_e32 v8, 15, v7
+; GFX950-NEXT: v_and_b32_e32 v4, 0xffff8000, v4
+; GFX950-NEXT: v_lshlrev_b16_e32 v6, 7, v5
+; GFX950-NEXT: v_lshlrev_b16_e32 v9, 10, v8
+; GFX950-NEXT: v_bitop3_b16 v6, v9, v6, v4 bitop3:0xfe
+; GFX950-NEXT: v_lshlrev_b32_e32 v9, 16, v5
+; GFX950-NEXT: v_ffbh_u32_e32 v9, v9
+; GFX950-NEXT: v_sub_u16_e32 v10, 15, v9
+; GFX950-NEXT: v_lshlrev_b16_e64 v10, v10, 1
+; GFX950-NEXT: s_and_b64 vcc, s[0:1], vcc
+; GFX950-NEXT: v_bitop3_b16 v1, v1, v10, 7 bitop3:0x6c
+; GFX950-NEXT: v_add_u16_e32 v10, -5, v9
+; GFX950-NEXT: v_sub_u16_e32 v9, 21, v9
+; GFX950-NEXT: v_cndmask_b32_e32 v0, v0, v3, vcc
+; GFX950-NEXT: v_lshlrev_b16_e32 v1, v10, v1
+; GFX950-NEXT: v_lshlrev_b16_e32 v9, 10, v9
+; GFX950-NEXT: v_cmp_ne_u16_e32 vcc, 0, v5
+; GFX950-NEXT: v_cmp_eq_u16_e64 s[0:1], 0, v8
+; GFX950-NEXT: v_add_u16_e32 v6, 0x2000, v6
+; GFX950-NEXT: v_bitop3_b16 v1, v4, v1, v9 bitop3:0xfe
+; GFX950-NEXT: s_and_b64 vcc, s[0:1], vcc
+; GFX950-NEXT: v_cndmask_b32_e32 v1, v6, v1, vcc
+; GFX950-NEXT: v_bitop3_b16 v6, v7, v5, 15 bitop3:0xec
+; GFX950-NEXT: v_cmp_eq_u16_e32 vcc, 0, v6
+; GFX950-NEXT: v_cmp_eq_u16_e64 s[0:1], 15, v8
+; GFX950-NEXT: s_nop 0
+; GFX950-NEXT: v_cndmask_b32_e32 v1, v1, v4, vcc
+; GFX950-NEXT: v_cmp_eq_u16_e32 vcc, 7, v5
+; GFX950-NEXT: s_and_b64 vcc, s[0:1], vcc
+; GFX950-NEXT: s_mov_b32 s0, 0x5040100
+; GFX950-NEXT: v_cndmask_b32_e32 v1, v1, v3, vcc
+; GFX950-NEXT: v_perm_b32 v0, v1, v0, s0
+; GFX950-NEXT: v_mov_b32_e32 v1, v2
+; GFX950-NEXT: s_setpc_b64 s[30:31]
%r = call <3 x half> @llvm.convert.from.arbitrary.fp.v3f16.v3i8(<3 x i8> %x, metadata !"Float8E4M3FN")
ret <3 x half> %r
}
@@ -151,6 +436,76 @@ define <3 x half> @from_bf8_v3f16(<3 x i8> %x) {
; GFX1250-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2)
; GFX1250-FAKE16-NEXT: v_cvt_pk_f16_bf8 v1, v1
; GFX1250-FAKE16-NEXT: s_set_pc_i64 s[30:31]
+;
+; GFX950-LABEL: from_bf8_v3f16:
+; GFX950: ; %bb.0:
+; GFX950-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX950-NEXT: v_and_b32_e32 v3, 3, v2
+; GFX950-NEXT: v_lshlrev_b16_e32 v5, 8, v2
+; GFX950-NEXT: v_lshrrev_b16_e32 v2, 2, v2
+; GFX950-NEXT: v_and_b32_e32 v7, 31, v2
+; GFX950-NEXT: v_lshlrev_b16_e32 v4, 8, v3
+; GFX950-NEXT: v_and_b32_e32 v6, 0xffff8000, v5
+; GFX950-NEXT: v_lshlrev_b16_e32 v8, 10, v7
+; GFX950-NEXT: v_bitop3_b16 v2, v2, v3, 31 bitop3:0xec
+; GFX950-NEXT: v_bitop3_b16 v4, v6, v4, v8 bitop3:0xfe
+; GFX950-NEXT: v_cmp_eq_u16_e32 vcc, 0, v2
+; GFX950-NEXT: v_cmp_eq_u16_e64 s[0:1], 31, v7
+; GFX950-NEXT: s_movk_i32 s2, 0x7c00
+; GFX950-NEXT: v_cndmask_b32_e32 v2, v4, v6, vcc
+; GFX950-NEXT: v_cmp_eq_u16_e32 vcc, 0, v3
+; GFX950-NEXT: v_mov_b32_e32 v4, 0xffff8000
+; GFX950-NEXT: v_bitop3_b16 v5, v5, s2, v4 bitop3:0xec
+; GFX950-NEXT: s_and_b64 vcc, s[0:1], vcc
+; GFX950-NEXT: v_cndmask_b32_e32 v2, v2, v5, vcc
+; GFX950-NEXT: v_and_b32_e32 v5, 3, v0
+; GFX950-NEXT: v_lshlrev_b16_e32 v7, 8, v0
+; GFX950-NEXT: v_lshrrev_b16_e32 v0, 2, v0
+; GFX950-NEXT: v_cmp_ne_u16_e32 vcc, 0, v3
+; GFX950-NEXT: v_and_b32_e32 v9, 31, v0
+; GFX950-NEXT: v_mov_b32_e32 v3, 0x7e00
+; GFX950-NEXT: s_and_b64 vcc, s[0:1], vcc
+; GFX950-NEXT: v_lshlrev_b16_e32 v6, 8, v5
+; GFX950-NEXT: v_and_b32_e32 v8, 0xffff8000, v7
+; GFX950-NEXT: v_lshlrev_b16_e32 v10, 10, v9
+; GFX950-NEXT: v_bitop3_b16 v0, v0, v5, 31 bitop3:0xec
+; GFX950-NEXT: v_cndmask_b32_e32 v2, v2, v3, vcc
+; GFX950-NEXT: v_bitop3_b16 v6, v8, v6, v10 bitop3:0xfe
+; GFX950-NEXT: v_cmp_eq_u16_e32 vcc, 0, v0
+; GFX950-NEXT: v_cmp_eq_u16_e64 s[0:1], 31, v9
+; GFX950-NEXT: s_nop 0
+; GFX950-NEXT: v_cndmask_b32_e32 v0, v6, v8, vcc
+; GFX950-NEXT: v_cmp_eq_u16_e32 vcc, 0, v5
+; GFX950-NEXT: v_bitop3_b16 v6, v7, s2, v4 bitop3:0xec
+; GFX950-NEXT: s_and_b64 vcc, s[0:1], vcc
+; GFX950-NEXT: v_cndmask_b32_e32 v0, v0, v6, vcc
+; GFX950-NEXT: v_cmp_ne_u16_e32 vcc, 0, v5
+; GFX950-NEXT: v_and_b32_e32 v5, 3, v1
+; GFX950-NEXT: v_lshlrev_b16_e32 v7, 8, v1
+; GFX950-NEXT: v_lshrrev_b16_e32 v1, 2, v1
+; GFX950-NEXT: v_and_b32_e32 v9, 31, v1
+; GFX950-NEXT: s_and_b64 vcc, s[0:1], vcc
+; GFX950-NEXT: v_lshlrev_b16_e32 v6, 8, v5
+; GFX950-NEXT: v_and_b32_e32 v8, 0xffff8000, v7
+; GFX950-NEXT: v_lshlrev_b16_e32 v10, 10, v9
+; GFX950-NEXT: v_bitop3_b16 v1, v1, v5, 31 bitop3:0xec
+; GFX950-NEXT: v_cndmask_b32_e32 v0, v0, v3, vcc
+; GFX950-NEXT: v_bitop3_b16 v6, v8, v6, v10 bitop3:0xfe
+; GFX950-NEXT: v_cmp_eq_u16_e32 vcc, 0, v1
+; GFX950-NEXT: v_cmp_eq_u16_e64 s[0:1], 31, v9
+; GFX950-NEXT: v_bitop3_b16 v4, v7, s2, v4 bitop3:0xec
+; GFX950-NEXT: v_cndmask_b32_e32 v1, v6, v8, vcc
+; GFX950-NEXT: v_cmp_eq_u16_e32 vcc, 0, v5
+; GFX950-NEXT: s_and_b64 vcc, s[0:1], vcc
+; GFX950-NEXT: s_nop 0
+; GFX950-NEXT: v_cndmask_b32_e32 v1, v1, v4, vcc
+; GFX950-NEXT: v_cmp_ne_u16_e32 vcc, 0, v5
+; GFX950-NEXT: s_and_b64 vcc, s[0:1], vcc
+; GFX950-NEXT: s_mov_b32 s0, 0x5040100
+; GFX950-NEXT: v_cndmask_b32_e32 v1, v1, v3, vcc
+; GFX950-NEXT: v_perm_b32 v0, v1, v0, s0
+; GFX950-NEXT: v_mov_b32_e32 v1, v2
+; GFX950-NEXT: s_setpc_b64 s[30:31]
%r = call <3 x half> @llvm.convert.from.arbitrary.fp.v3f16.v3i8(<3 x i8> %x, metadata !"Float8E5M2")
ret <3 x half> %r
}
@@ -184,6 +539,136 @@ define <4 x half> @from_fp8_v4f16(<4 x i8> %x) {
; GFX1250-FAKE16-NEXT: v_cvt_pk_f16_fp8 v0, v0
; GFX1250-FAKE16-NEXT: v_cvt_pk_f16_fp8 v1, v1
; GFX1250-FAKE16-NEXT: s_set_pc_i64 s[30:31]
+;
+; GFX950-LABEL: from_fp8_v4f16:
+; GFX950: ; %bb.0:
+; GFX950-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX950-NEXT: v_lshrrev_b16_e32 v7, 3, v2
+; GFX950-NEXT: v_lshlrev_b16_e32 v4, 8, v2
+; GFX950-NEXT: v_and_b32_e32 v5, 7, v2
+; GFX950-NEXT: v_and_b32_e32 v8, 15, v7
+; GFX950-NEXT: v_and_b32_e32 v4, 0xffff8000, v4
+; GFX950-NEXT: v_lshlrev_b16_e32 v6, 7, v5
+; GFX950-NEXT: v_lshlrev_b16_e32 v9, 10, v8
+; GFX950-NEXT: v_bitop3_b16 v6, v9, v6, v4 bitop3:0xfe
+; GFX950-NEXT: v_lshlrev_b32_e32 v9, 16, v5
+; GFX950-NEXT: v_ffbh_u32_e32 v9, v9
+; GFX950-NEXT: v_sub_u16_e32 v10, 15, v9
+; GFX950-NEXT: v_lshlrev_b16_e64 v10, v10, 1
+; GFX950-NEXT: v_bitop3_b16 v2, v2, v10, 7 bitop3:0x6c
+; GFX950-NEXT: v_add_u16_e32 v10, -5, v9
+; GFX950-NEXT: v_sub_u16_e32 v9, 21, v9
+; GFX950-NEXT: v_lshlrev_b16_e32 v2, v10, v2
+; GFX950-NEXT: v_lshlrev_b16_e32 v9, 10, v9
+; GFX950-NEXT: v_cmp_ne_u16_e32 vcc, 0, v5
+; GFX950-NEXT: v_cmp_eq_u16_e64 s[0:1], 0, v8
+; GFX950-NEXT: v_add_u16_e32 v6, 0x2000, v6
+; GFX950-NEXT: v_bitop3_b16 v2, v4, v2, v9 bitop3:0xfe
+; GFX950-NEXT: s_and_b64 vcc, s[0:1], vcc
+; GFX950-NEXT: v_cndmask_b32_e32 v2, v6, v2, vcc
+; GFX950-NEXT: v_bitop3_b16 v6, v7, v5, 15 bitop3:0xec
+; GFX950-NEXT: v_cmp_eq_u16_e32 vcc, 0, v6
+; GFX950-NEXT: v_cmp_eq_u16_e64 s[0:1], 15, v8
+; GFX950-NEXT: v_lshrrev_b16_e32 v8, 3, v3
+; GFX950-NEXT: v_cndmask_b32_e32 v2, v2, v4, vcc
+; GFX950-NEXT: v_cmp_eq_u16_e32 vcc, 7, v5
+; GFX950-NEXT: v_lshlrev_b16_e32 v5, 8, v3
+; GFX950-NEXT: v_and_b32_e32 v6, 7, v3
+; GFX950-NEXT: v_and_b32_e32 v9, 15, v8
+; GFX950-NEXT: v_and_b32_e32 v5, 0xffff8000, v5
+; GFX950-NEXT: v_lshlrev_b16_e32 v7, 7, v6
+; GFX950-NEXT: v_lshlrev_b16_e32 v10, 10, v9
+; GFX950-NEXT: v_bitop3_b16 v7, v10, v7, v5 bitop3:0xfe
+; GFX950-NEXT: v_lshlrev_b32_e32 v10, 16, v6
+; GFX950-NEXT: v_ffbh_u32_e32 v10, v10
+; GFX950-NEXT: v_sub_u16_e32 v11, 15, v10
+; GFX950-NEXT: v_lshlrev_b16_e64 v11, v11, 1
+; GFX950-NEXT: v_mov_b32_e32 v4, 0x7e00
+; GFX950-NEXT: s_and_b64 vcc, s[0:1], vcc
+; GFX950-NEXT: v_bitop3_b16 v3, v3, v11, 7 bitop3:0x6c
+; GFX950-NEXT: v_add_u16_e32 v11, -5, v10
+; GFX950-NEXT: v_sub_u16_e32 v10, 21, v10
+; GFX950-NEXT: v_cndmask_b32_e32 v2, v2, v4, vcc
+; GFX950-NEXT: v_lshlrev_b16_e32 v3, v11, v3
+; GFX950-NEXT: v_lshlrev_b16_e32 v10, 10, v10
+; GFX950-NEXT: v_cmp_ne_u16_e32 vcc, 0, v6
+; GFX950-NEXT: v_cmp_eq_u16_e64 s[0:1], 0, v9
+; GFX950-NEXT: v_add_u16_e32 v7, 0x2000, v7
+; GFX950-NEXT: v_bitop3_b16 v3, v5, v3, v10 bitop3:0xfe
+; GFX950-NEXT: s_and_b64 vcc, s[0:1], vcc
+; GFX950-NEXT: v_cndmask_b32_e32 v3, v7, v3, vcc
+; GFX950-NEXT: v_bitop3_b16 v7, v8, v6, 15 bitop3:0xec
+; GFX950-NEXT: v_cmp_eq_u16_e32 vcc, 0, v7
+; GFX950-NEXT: v_lshrrev_b16_e32 v8, 3, v0
+; GFX950-NEXT: v_cmp_eq_u16_e64 s[0:1], 15, v9
+; GFX950-NEXT: v_cndmask_b32_e32 v3, v3, v5, vcc
+; GFX950-NEXT: v_cmp_eq_u16_e32 vcc, 7, v6
+; GFX950-NEXT: v_lshlrev_b16_e32 v5, 8, v0
+; GFX950-NEXT: v_and_b32_e32 v6, 7, v0
+; GFX950-NEXT: v_and_b32_e32 v9, 15, v8
+; GFX950-NEXT: v_and_b32_e32 v5, 0xffff8000, v5
+; GFX950-NEXT: v_lshlrev_b16_e32 v7, 7, v6
+; GFX950-NEXT: v_lshlrev_b16_e32 v10, 10, v9
+; GFX950-NEXT: v_bitop3_b16 v7, v10, v7, v5 bitop3:0xfe
+; GFX950-NEXT: v_lshlrev_b32_e32 v10, 16, v6
+; GFX950-NEXT: v_ffbh_u32_e32 v10, v10
+; GFX950-NEXT: v_sub_u16_e32 v11, 15, v10
+; GFX950-NEXT: v_lshlrev_b16_e64 v11, v11, 1
+; GFX950-NEXT: s_and_b64 vcc, s[0:1], vcc
+; GFX950-NEXT: v_bitop3_b16 v0, v0, v11, 7 bitop3:0x6c
+; GFX950-NEXT: v_add_u16_e32 v11, -5, v10
+; GFX950-NEXT: v_sub_u16_e32 v10, 21, v10
+; GFX950-NEXT: v_cndmask_b32_e32 v3, v3, v4, vcc
+; GFX950-NEXT: v_lshlrev_b16_e32 v0, v11, v0
+; GFX950-NEXT: v_lshlrev_b16_e32 v10, 10, v10
+; GFX950-NEXT: v_cmp_ne_u16_e32 vcc, 0, v6
+; GFX950-NEXT: v_cmp_eq_u16_e64 s[0:1], 0, v9
+; GFX950-NEXT: v_add_u16_e32 v7, 0x2000, v7
+; GFX950-NEXT: v_bitop3_b16 v0, v5, v0, v10 bitop3:0xfe
+; GFX950-NEXT: s_and_b64 vcc, s[0:1], vcc
+; GFX950-NEXT: v_cndmask_b32_e32 v0, v7, v0, vcc
+; GFX950-NEXT: v_bitop3_b16 v7, v8, v6, 15 bitop3:0xec
+; GFX950-NEXT: v_cmp_eq_u16_e32 vcc, 0, v7
+; GFX950-NEXT: v_lshrrev_b16_e32 v8, 3, v1
+; GFX950-NEXT: v_cmp_eq_u16_e64 s[0:1], 15, v9
+; GFX950-NEXT: v_cndmask_b32_e32 v0, v0, v5, vcc
+; GFX950-NEXT: v_cmp_eq_u16_e32 vcc, 7, v6
+; GFX950-NEXT: v_lshlrev_b16_e32 v5, 8, v1
+; GFX950-NEXT: v_and_b32_e32 v6, 7, v1
+; GFX950-NEXT: v_and_b32_e32 v9, 15, v8
+; GFX950-NEXT: v_and_b32_e32 v5, 0xffff8000, v5
+; GFX950-NEXT: v_lshlrev_b16_e32 v7, 7, v6
+; GFX950-NEXT: v_lshlrev_b16_e32 v10, 10, v9
+; GFX950-NEXT: v_bitop3_b16 v7, v10, v7, v5 bitop3:0xfe
+; GFX950-NEXT: v_lshlrev_b32_e32 v10, 16, v6
+; GFX950-NEXT: v_ffbh_u32_e32 v10, v10
+; GFX950-NEXT: v_sub_u16_e32 v11, 15, v10
+; GFX950-NEXT: v_lshlrev_b16_e64 v11, v11, 1
+; GFX950-NEXT: s_and_b64 vcc, s[0:1], vcc
+; GFX950-NEXT: v_bitop3_b16 v1, v1, v11, 7 bitop3:0x6c
+; GFX950-NEXT: v_add_u16_e32 v11, -5, v10
+; GFX950-NEXT: v_sub_u16_e32 v10, 21, v10
+; GFX950-NEXT: v_cndmask_b32_e32 v0, v0, v4, vcc
+; GFX950-NEXT: v_lshlrev_b16_e32 v1, v11, v1
+; GFX950-NEXT: v_lshlrev_b16_e32 v10, 10, v10
+; GFX950-NEXT: v_cmp_ne_u16_e32 vcc, 0, v6
+; GFX950-NEXT: v_cmp_eq_u16_e64 s[0:1], 0, v9
+; GFX950-NEXT: v_add_u16_e32 v7, 0x2000, v7
+; GFX950-NEXT: v_bitop3_b16 v1, v5, v1, v10 bitop3:0xfe
+; GFX950-NEXT: s_and_b64 vcc, s[0:1], vcc
+; GFX950-NEXT: v_cndmask_b32_e32 v1, v7, v1, vcc
+; GFX950-NEXT: v_bitop3_b16 v7, v8, v6, 15 bitop3:0xec
+; GFX950-NEXT: v_cmp_eq_u16_e32 vcc, 0, v7
+; GFX950-NEXT: v_cmp_eq_u16_e64 s[0:1], 15, v9
+; GFX950-NEXT: s_nop 0
+; GFX950-NEXT: v_cndmask_b32_e32 v1, v1, v5, vcc
+; GFX950-NEXT: v_cmp_eq_u16_e32 vcc, 7, v6
+; GFX950-NEXT: s_and_b64 vcc, s[0:1], vcc
+; GFX950-NEXT: s_mov_b32 s0, 0x5040100
+; GFX950-NEXT: v_cndmask_b32_e32 v1, v1, v4, vcc
+; GFX950-NEXT: v_perm_b32 v0, v1, v0, s0
+; GFX950-NEXT: v_perm_b32 v1, v3, v2, s0
+; GFX950-NEXT: s_setpc_b64 s[30:31]
%r = call <4 x half> @llvm.convert.from.arbitrary.fp.v4f16.v4i8(<4 x i8> %x, metadata !"Float8E4M3FN")
ret <4 x half> %r
}
@@ -217,6 +702,96 @@ define <4 x half> @from_bf8_v4f16(<4 x i8> %x) {
; GFX1250-FAKE16-NEXT: v_cvt_pk_f16_bf8 v0, v0
; GFX1250-FAKE16-NEXT: v_cvt_pk_f16_bf8 v1, v1
; GFX1250-FAKE16-NEXT: s_set_pc_i64 s[30:31]
+;
+; GFX950-LABEL: from_bf8_v4f16:
+; GFX950: ; %bb.0:
+; GFX950-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX950-NEXT: v_and_b32_e32 v4, 3, v2
+; GFX950-NEXT: v_lshlrev_b16_e32 v6, 8, v2
+; GFX950-NEXT: v_lshrrev_b16_e32 v2, 2, v2
+; GFX950-NEXT: v_and_b32_e32 v8, 31, v2
+; GFX950-NEXT: v_lshlrev_b16_e32 v5, 8, v4
+; GFX950-NEXT: v_and_b32_e32 v7, 0xffff8000, v6
+; GFX950-NEXT: v_lshlrev_b16_e32 v9, 10, v8
+; GFX950-NEXT: v_bitop3_b16 v2, v2, v4, 31 bitop3:0xec
+; GFX950-NEXT: v_bitop3_b16 v5, v7, v5, v9 bitop3:0xfe
+; GFX950-NEXT: v_cmp_eq_u16_e32 vcc, 0, v2
+; GFX950-NEXT: v_cmp_eq_u16_e64 s[0:1], 31, v8
+; GFX950-NEXT: s_movk_i32 s2, 0x7c00
+; GFX950-NEXT: v_cndmask_b32_e32 v2, v5, v7, vcc
+; GFX950-NEXT: v_cmp_eq_u16_e32 vcc, 0, v4
+; GFX950-NEXT: v_mov_b32_e32 v5, 0xffff8000
+; GFX950-NEXT: v_bitop3_b16 v6, v6, s2, v5 bitop3:0xec
+; GFX950-NEXT: s_and_b64 vcc, s[0:1], vcc
+; GFX950-NEXT: v_cndmask_b32_e32 v2, v2, v6, vcc
+; GFX950-NEXT: v_and_b32_e32 v6, 3, v3
+; GFX950-NEXT: v_lshlrev_b16_e32 v8, 8, v3
+; GFX950-NEXT: v_lshrrev_b16_e32 v3, 2, v3
+; GFX950-NEXT: v_cmp_ne_u16_e32 vcc, 0, v4
+; GFX950-NEXT: v_and_b32_e32 v10, 31, v3
+; GFX950-NEXT: v_mov_b32_e32 v4, 0x7e00
+; GFX950-NEXT: s_and_b64 vcc, s[0:1], vcc
+; GFX950-NEXT: v_lshlrev_b16_e32 v7, 8, v6
+; GFX950-NEXT: v_and_b32_e32 v9, 0xffff8000, v8
+; GFX950-NEXT: v_lshlrev_b16_e32 v11, 10, v10
+; GFX950-NEXT: v_bitop3_b16 v3, v3, v6, 31 bitop3:0xec
+; GFX950-NEXT: v_cndmask_b32_e32 v2, v2, v4, vcc
+; GFX950-NEXT: v_bitop3_b16 v7, v9, v7, v11 bitop3:0xfe
+; GFX950-NEXT: v_cmp_eq_u16_e32 vcc, 0, v3
+; GFX950-NEXT: v_cmp_eq_u16_e64 s[0:1], 31, v10
+; GFX950-NEXT: s_nop 0
+; GFX950-NEXT: v_cndmask_b32_e32 v3, v7, v9, vcc
+; GFX950-NEXT: v_cmp_eq_u16_e32 vcc, 0, v6
+; GFX950-NEXT: v_bitop3_b16 v7, v8, s2, v5 bitop3:0xec
+; GFX950-NEXT: s_and_b64 vcc, s[0:1], vcc
+; GFX950-NEXT: v_cndmask_b32_e32 v3, v3, v7, vcc
+; GFX950-NEXT: v_cmp_ne_u16_e32 vcc, 0, v6
+; GFX950-NEXT: v_and_b32_e32 v6, 3, v0
+; GFX950-NEXT: v_lshlrev_b16_e32 v8, 8, v0
+; GFX950-NEXT: v_lshrrev_b16_e32 v0, 2, v0
+; GFX950-NEXT: v_and_b32_e32 v10, 31, v0
+; GFX950-NEXT: s_and_b64 vcc, s[0:1], vcc
+; GFX950-NEXT: v_lshlrev_b16_e32 v7, 8, v6
+; GFX950-NEXT: v_and_b32_e32 v9, 0xffff8000, v8
+; GFX950-NEXT: v_lshlrev_b16_e32 v11, 10, v10
+; GFX950-NEXT: v_bitop3_b16 v0, v0, v6, 31 bitop3:0xec
+; GFX950-NEXT: v_cndmask_b32_e32 v3, v3, v4, vcc
+; GFX950-NEXT: v_bitop3_b16 v7, v9, v7, v11 bitop3:0xfe
+; GFX950-NEXT: v_cmp_eq_u16_e32 vcc, 0, v0
+; GFX950-NEXT: v_cmp_eq_u16_e64 s[0:1], 31, v10
+; GFX950-NEXT: s_nop 0
+; GFX950-NEXT: v_cndmask_b32_e32 v0, v7, v9, vcc
+; GFX950-NEXT: v_cmp_eq_u16_e32 vcc, 0, v6
+; GFX950-NEXT: v_bitop3_b16 v7, v8, s2, v5 bitop3:0xec
+; GFX950-NEXT: s_and_b64 vcc, s[0:1], vcc
+; GFX950-NEXT: v_cndmask_b32_e32 v0, v0, v7, vcc
+; GFX950-NEXT: v_cmp_ne_u16_e32 vcc, 0, v6
+; GFX950-NEXT: v_and_b32_e32 v6, 3, v1
+; GFX950-NEXT: v_lshlrev_b16_e32 v8, 8, v1
+; GFX950-NEXT: v_lshrrev_b16_e32 v1, 2, v1
+; GFX950-NEXT: v_and_b32_e32 v10, 31, v1
+; GFX950-NEXT: s_and_b64 vcc, s[0:1], vcc
+; GFX950-NEXT: v_lshlrev_b16_e32 v7, 8, v6
+; GFX950-NEXT: v_and_b32_e32 v9, 0xffff8000, v8
+; GFX950-NEXT: v_lshlrev_b16_e32 v11, 10, v10
+; GFX950-NEXT: v_bitop3_b16 v1, v1, v6, 31 bitop3:0xec
+; GFX950-NEXT: v_cndmask_b32_e32 v0, v0, v4, vcc
+; GFX950-NEXT: v_bitop3_b16 v7, v9, v7, v11 bitop3:0xfe
+; GFX950-NEXT: v_cmp_eq_u16_e32 vcc, 0, v1
+; GFX950-NEXT: v_cmp_eq_u16_e64 s[0:1], 31, v10
+; GFX950-NEXT: v_bitop3_b16 v5, v8, s2, v5 bitop3:0xec
+; GFX950-NEXT: v_cndmask_b32_e32 v1, v7, v9, vcc
+; GFX950-NEXT: v_cmp_eq_u16_e32 vcc, 0, v6
+; GFX950-NEXT: s_and_b64 vcc, s[0:1], vcc
+; GFX950-NEXT: s_nop 0
+; GFX950-NEXT: v_cndmask_b32_e32 v1, v1, v5, vcc
+; GFX950-NEXT: v_cmp_ne_u16_e32 vcc, 0, v6
+; GFX950-NEXT: s_and_b64 vcc, s[0:1], vcc
+; GFX950-NEXT: s_mov_b32 s0, 0x5040100
+; GFX950-NEXT: v_cndmask_b32_e32 v1, v1, v4, vcc
+; GFX950-NEXT: v_perm_b32 v0, v1, v0, s0
+; GFX950-NEXT: v_perm_b32 v1, v3, v2, s0
+; GFX950-NEXT: s_setpc_b64 s[30:31]
%r = call <4 x half> @llvm.convert.from.arbitrary.fp.v4f16.v4i8(<4 x i8> %x, metadata !"Float8E5M2")
ret <4 x half> %r
}
More information about the llvm-commits
mailing list