[llvm] [NFC][AMDGPU] Add tests for fpround of fadd and fsub feeding the mix instructions (PR #224909)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Sep 20 04:15:53 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-amdgpu
Author: Dmitry Sidorov (MrSidims)
<details>
<summary>Changes</summary>
The f32 mix patterns already fold fadd and fsub into v_mad_mix_f32 and
v_fma_mix_f32, but the f16 and bf16 forms only fold fmul, so a half or
bfloat result still pays for a separate convert.
Also cover the denormal modes an f16 result depends on and an f16
source feeding an f16 or bf16 mix. The existing mad-mix-lo and
mad-mix-hi functions now flush denormals for every type rather than
for f32 alone.
Assisted-by: Claude Code Opus 5
---
<sub>Stack created with <a href="https://github.com/github/gh-stack">GitHub Stacks CLI</a> • <a href="https://gh.io/stacks-feedback">Give Feedback 💬</a></sub>
---
Patch is 70.07 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/224909.diff
4 Files Affected:
- (modified) llvm/test/CodeGen/AMDGPU/mad-mix-hi-bf16.ll (+104)
- (modified) llvm/test/CodeGen/AMDGPU/mad-mix-hi.ll (+485-1)
- (modified) llvm/test/CodeGen/AMDGPU/mad-mix-lo-bf16.ll (+152)
- (modified) llvm/test/CodeGen/AMDGPU/mad-mix-lo.ll (+721-3)
``````````diff
diff --git a/llvm/test/CodeGen/AMDGPU/mad-mix-hi-bf16.ll b/llvm/test/CodeGen/AMDGPU/mad-mix-hi-bf16.ll
index 10c55a59f84d4..7e258cf7db4df 100644
--- a/llvm/test/CodeGen/AMDGPU/mad-mix-hi-bf16.ll
+++ b/llvm/test/CodeGen/AMDGPU/mad-mix-hi-bf16.ll
@@ -18,6 +18,22 @@ define <2 x bfloat> @v_mad_mixhi_bf16_bf16lo_bf16lo_bf16lo_undeflo(bfloat %src0,
ret <2 x bfloat> %vec.result
}
+define <2 x bfloat> @v_mad_mixhi_bf16_f16lo_bf16lo_bf16lo_undeflo(half %src0, bfloat %src1, bfloat %src2) #0 {
+; GFX1250-LABEL: v_mad_mixhi_bf16_f16lo_bf16lo_bf16lo_undeflo:
+; GFX1250: ; %bb.0:
+; GFX1250-NEXT: s_wait_loadcnt_dscnt 0x0
+; GFX1250-NEXT: s_wait_kmcnt 0x0
+; GFX1250-NEXT: v_fma_mixhi_bf16 v0, v0, v1, v2 op_sel_hi:[0,1,1]
+; GFX1250-NEXT: s_set_pc_i64 s[30:31]
+ %src0.ext = fpext half %src0 to float
+ %src1.ext = fpext bfloat %src1 to float
+ %src2.ext = fpext bfloat %src2 to float
+ %result = tail call float @llvm.fmuladd.f32(float %src0.ext, float %src1.ext, float %src2.ext)
+ %cvt.result = fptrunc float %result to bfloat
+ %vec.result = insertelement <2 x bfloat> undef, bfloat %cvt.result, i32 1
+ ret <2 x bfloat> %vec.result
+}
+
define <2 x bfloat> @v_mad_mixhi_bf16_bf16lo_bf16lo_bf16lo_constlo(bfloat %src0, bfloat %src1, bfloat %src2) #0 {
; GFX1250-FAKE16-LABEL: v_mad_mixhi_bf16_bf16lo_bf16lo_bf16lo_constlo:
; GFX1250-FAKE16: ; %bb.0:
@@ -195,6 +211,94 @@ define <2 x bfloat> @v_mad_mixhi_bf16_bf16lo_bf16lo_bf16lo_undeflo_clamp_postcvt
ret <2 x bfloat> %vec.result
}
+define <2 x bfloat> @mixhi_fptrunc_fadd(float %a, float %b, bfloat %lo) #0 {
+; GFX1250-FAKE16-LABEL: mixhi_fptrunc_fadd:
+; GFX1250-FAKE16: ; %bb.0: ; %.entry
+; GFX1250-FAKE16-NEXT: s_wait_loadcnt_dscnt 0x0
+; GFX1250-FAKE16-NEXT: s_wait_kmcnt 0x0
+; GFX1250-FAKE16-NEXT: v_add_f32_e32 v0, v0, v1
+; GFX1250-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX1250-FAKE16-NEXT: v_cvt_pk_bf16_f32 v0, v0, s0
+; GFX1250-FAKE16-NEXT: v_perm_b32 v0, v0, v2, 0x5040100
+; GFX1250-FAKE16-NEXT: s_set_pc_i64 s[30:31]
+;
+; GFX1250-REAL16-LABEL: mixhi_fptrunc_fadd:
+; GFX1250-REAL16: ; %bb.0: ; %.entry
+; GFX1250-REAL16-NEXT: s_wait_loadcnt_dscnt 0x0
+; GFX1250-REAL16-NEXT: s_wait_kmcnt 0x0
+; GFX1250-REAL16-NEXT: v_add_f32_e32 v0, v0, v1
+; GFX1250-REAL16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX1250-REAL16-NEXT: v_cvt_pk_bf16_f32 v1, v0, s0
+; GFX1250-REAL16-NEXT: v_mov_b16_e32 v0.l, v2.l
+; GFX1250-REAL16-NEXT: v_mov_b16_e32 v0.h, v1.l
+; GFX1250-REAL16-NEXT: s_set_pc_i64 s[30:31]
+.entry:
+ %add = fadd float %a, %b
+ %trunc = fptrunc float %add to bfloat
+ %vec = insertelement <2 x bfloat> poison, bfloat %lo, i32 0
+ %vec.result = insertelement <2 x bfloat> %vec, bfloat %trunc, i32 1
+ ret <2 x bfloat> %vec.result
+}
+
+define <2 x bfloat> @mixhi_fptrunc_fadd_f16_src(half %a, float %b, bfloat %lo) #0 {
+; GFX1250-FAKE16-LABEL: mixhi_fptrunc_fadd_f16_src:
+; GFX1250-FAKE16: ; %bb.0: ; %.entry
+; GFX1250-FAKE16-NEXT: s_wait_loadcnt_dscnt 0x0
+; GFX1250-FAKE16-NEXT: s_wait_kmcnt 0x0
+; GFX1250-FAKE16-NEXT: v_fma_mix_f32 v0, v0, 1.0, v1 op_sel_hi:[1,1,0]
+; GFX1250-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX1250-FAKE16-NEXT: v_cvt_pk_bf16_f32 v0, v0, s0
+; GFX1250-FAKE16-NEXT: v_perm_b32 v0, v0, v2, 0x5040100
+; GFX1250-FAKE16-NEXT: s_set_pc_i64 s[30:31]
+;
+; GFX1250-REAL16-LABEL: mixhi_fptrunc_fadd_f16_src:
+; GFX1250-REAL16: ; %bb.0: ; %.entry
+; GFX1250-REAL16-NEXT: s_wait_loadcnt_dscnt 0x0
+; GFX1250-REAL16-NEXT: s_wait_kmcnt 0x0
+; GFX1250-REAL16-NEXT: v_fma_mix_f32 v0, v0, 1.0, v1 op_sel_hi:[1,1,0]
+; GFX1250-REAL16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX1250-REAL16-NEXT: v_cvt_pk_bf16_f32 v1, v0, s0
+; GFX1250-REAL16-NEXT: v_mov_b16_e32 v0.l, v2.l
+; GFX1250-REAL16-NEXT: v_mov_b16_e32 v0.h, v1.l
+; GFX1250-REAL16-NEXT: s_set_pc_i64 s[30:31]
+.entry:
+ %a.ext = fpext half %a to float
+ %add = fadd float %a.ext, %b
+ %trunc = fptrunc float %add to bfloat
+ %vec = insertelement <2 x bfloat> poison, bfloat %lo, i32 0
+ %vec.result = insertelement <2 x bfloat> %vec, bfloat %trunc, i32 1
+ ret <2 x bfloat> %vec.result
+}
+
+define <2 x bfloat> @mixhi_fptrunc_fsub(float %a, float %b, bfloat %lo) #0 {
+; GFX1250-FAKE16-LABEL: mixhi_fptrunc_fsub:
+; GFX1250-FAKE16: ; %bb.0: ; %.entry
+; GFX1250-FAKE16-NEXT: s_wait_loadcnt_dscnt 0x0
+; GFX1250-FAKE16-NEXT: s_wait_kmcnt 0x0
+; GFX1250-FAKE16-NEXT: v_sub_f32_e32 v0, v0, v1
+; GFX1250-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX1250-FAKE16-NEXT: v_cvt_pk_bf16_f32 v0, v0, s0
+; GFX1250-FAKE16-NEXT: v_perm_b32 v0, v0, v2, 0x5040100
+; GFX1250-FAKE16-NEXT: s_set_pc_i64 s[30:31]
+;
+; GFX1250-REAL16-LABEL: mixhi_fptrunc_fsub:
+; GFX1250-REAL16: ; %bb.0: ; %.entry
+; GFX1250-REAL16-NEXT: s_wait_loadcnt_dscnt 0x0
+; GFX1250-REAL16-NEXT: s_wait_kmcnt 0x0
+; GFX1250-REAL16-NEXT: v_sub_f32_e32 v0, v0, v1
+; GFX1250-REAL16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX1250-REAL16-NEXT: v_cvt_pk_bf16_f32 v1, v0, s0
+; GFX1250-REAL16-NEXT: v_mov_b16_e32 v0.l, v2.l
+; GFX1250-REAL16-NEXT: v_mov_b16_e32 v0.h, v1.l
+; GFX1250-REAL16-NEXT: s_set_pc_i64 s[30:31]
+.entry:
+ %sub = fsub float %a, %b
+ %trunc = fptrunc float %sub to bfloat
+ %vec = insertelement <2 x bfloat> poison, bfloat %lo, i32 0
+ %vec.result = insertelement <2 x bfloat> %vec, bfloat %trunc, i32 1
+ ret <2 x bfloat> %vec.result
+}
+
declare bfloat @llvm.minnum.bf16(bfloat, bfloat) #1
declare bfloat @llvm.maxnum.bf16(bfloat, bfloat) #1
declare float @llvm.minnum.f32(float, float) #1
diff --git a/llvm/test/CodeGen/AMDGPU/mad-mix-hi.ll b/llvm/test/CodeGen/AMDGPU/mad-mix-hi.ll
index db028d4364f35..9aeef7abb3473 100644
--- a/llvm/test/CodeGen/AMDGPU/mad-mix-hi.ll
+++ b/llvm/test/CodeGen/AMDGPU/mad-mix-hi.ll
@@ -751,6 +751,489 @@ define <2 x half> @v_mad_mixhi_f16_f16lo_f16lo_f16lo_undeflo_clamp_postcvt_multi
ret <2 x half> %vec.result
}
+define <2 x half> @mixhi_fptrunc_f16_denormals(float %a, float %b, half %lo) #2 {
+; SDAG-GFX11-TRUE16-LABEL: mixhi_fptrunc_f16_denormals:
+; SDAG-GFX11-TRUE16: ; %bb.0: ; %.entry
+; SDAG-GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; SDAG-GFX11-TRUE16-NEXT: v_fma_mixhi_f16 v0, v0, v1, neg(0)
+; SDAG-GFX11-TRUE16-NEXT: v_mov_b16_e32 v0.l, v2.l
+; SDAG-GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]
+;
+; SDAG-GFX11-FAKE16-LABEL: mixhi_fptrunc_f16_denormals:
+; SDAG-GFX11-FAKE16: ; %bb.0: ; %.entry
+; SDAG-GFX11-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; SDAG-GFX11-FAKE16-NEXT: v_fma_mixhi_f16 v2, v0, v1, neg(0)
+; SDAG-GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1)
+; SDAG-GFX11-FAKE16-NEXT: v_mov_b32_e32 v0, v2
+; SDAG-GFX11-FAKE16-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: mixhi_fptrunc_f16_denormals:
+; GFX9: ; %bb.0: ; %.entry
+; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT: v_mad_mixhi_f16 v2, v0, v1, neg(0)
+; GFX9-NEXT: v_mov_b32_e32 v0, v2
+; GFX9-NEXT: s_setpc_b64 s[30:31]
+;
+; SDAG-VI-LABEL: mixhi_fptrunc_f16_denormals:
+; SDAG-VI: ; %bb.0: ; %.entry
+; SDAG-VI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; SDAG-VI-NEXT: v_mul_f32_e32 v0, v0, v1
+; SDAG-VI-NEXT: v_cvt_f16_f32_sdwa v0, v0 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:DWORD
+; SDAG-VI-NEXT: v_or_b32_sdwa v0, v2, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_0 src1_sel:DWORD
+; SDAG-VI-NEXT: s_setpc_b64 s[30:31]
+;
+; SDAG-CI-LABEL: mixhi_fptrunc_f16_denormals:
+; SDAG-CI: ; %bb.0: ; %.entry
+; SDAG-CI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; SDAG-CI-NEXT: v_mul_f32_e32 v0, v0, v1
+; SDAG-CI-NEXT: v_cvt_f16_f32_e32 v0, v0
+; SDAG-CI-NEXT: v_and_b32_e32 v1, 0xffff, v2
+; SDAG-CI-NEXT: v_lshlrev_b32_e32 v0, 16, v0
+; SDAG-CI-NEXT: v_or_b32_e32 v0, v1, v0
+; SDAG-CI-NEXT: s_setpc_b64 s[30:31]
+;
+; GISEL-GFX11-LABEL: mixhi_fptrunc_f16_denormals:
+; GISEL-GFX11: ; %bb.0: ; %.entry
+; GISEL-GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GISEL-GFX11-NEXT: v_fma_mixhi_f16 v2, v0, v1, neg(0)
+; GISEL-GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1)
+; GISEL-GFX11-NEXT: v_mov_b32_e32 v0, v2
+; GISEL-GFX11-NEXT: s_setpc_b64 s[30:31]
+;
+; GISEL-VI-LABEL: mixhi_fptrunc_f16_denormals:
+; GISEL-VI: ; %bb.0: ; %.entry
+; GISEL-VI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GISEL-VI-NEXT: v_mul_f32_e32 v0, v0, v1
+; GISEL-VI-NEXT: v_cvt_f16_f32_e32 v0, v0
+; GISEL-VI-NEXT: v_mov_b32_e32 v1, 16
+; GISEL-VI-NEXT: v_lshlrev_b32_sdwa v0, v1, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_0
+; GISEL-VI-NEXT: v_or_b32_sdwa v0, v2, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_0 src1_sel:DWORD
+; GISEL-VI-NEXT: s_setpc_b64 s[30:31]
+;
+; GISEL-CI-LABEL: mixhi_fptrunc_f16_denormals:
+; GISEL-CI: ; %bb.0: ; %.entry
+; GISEL-CI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GISEL-CI-NEXT: v_mul_f32_e32 v0, v0, v1
+; GISEL-CI-NEXT: v_cvt_f16_f32_e32 v0, v0
+; GISEL-CI-NEXT: v_and_b32_e32 v1, 0xffff, v2
+; GISEL-CI-NEXT: v_bfe_u32 v0, v0, 0, 16
+; GISEL-CI-NEXT: v_lshlrev_b32_e32 v0, 16, v0
+; GISEL-CI-NEXT: v_or_b32_e32 v0, v1, v0
+; GISEL-CI-NEXT: s_setpc_b64 s[30:31]
+.entry:
+ %mul = fmul float %a, %b
+ %trunc = fptrunc float %mul to half
+ %vec = insertelement <2 x half> poison, half %lo, i32 0
+ %vec.result = insertelement <2 x half> %vec, half %trunc, i32 1
+ ret <2 x half> %vec.result
+}
+
+define <2 x half> @mixhi_fptrunc_fadd(float %a, float %b, half %lo) #0 {
+; SDAG-GFX11-TRUE16-LABEL: mixhi_fptrunc_fadd:
+; SDAG-GFX11-TRUE16: ; %bb.0: ; %.entry
+; SDAG-GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; SDAG-GFX11-TRUE16-NEXT: v_add_f32_e32 v0, v0, v1
+; SDAG-GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1)
+; SDAG-GFX11-TRUE16-NEXT: v_cvt_f16_f32_e32 v0.h, v0
+; SDAG-GFX11-TRUE16-NEXT: v_mov_b16_e32 v0.l, v2.l
+; SDAG-GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]
+;
+; SDAG-GFX11-FAKE16-LABEL: mixhi_fptrunc_fadd:
+; SDAG-GFX11-FAKE16: ; %bb.0: ; %.entry
+; SDAG-GFX11-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; SDAG-GFX11-FAKE16-NEXT: v_add_f32_e32 v0, v0, v1
+; SDAG-GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; SDAG-GFX11-FAKE16-NEXT: v_cvt_f16_f32_e32 v0, v0
+; SDAG-GFX11-FAKE16-NEXT: v_perm_b32 v0, v0, v2, 0x5040100
+; SDAG-GFX11-FAKE16-NEXT: s_setpc_b64 s[30:31]
+;
+; SDAG-GFX9-LABEL: mixhi_fptrunc_fadd:
+; SDAG-GFX9: ; %bb.0: ; %.entry
+; SDAG-GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; SDAG-GFX9-NEXT: v_add_f32_e32 v0, v0, v1
+; SDAG-GFX9-NEXT: v_cvt_f16_f32_e32 v0, v0
+; SDAG-GFX9-NEXT: s_mov_b32 s4, 0x5040100
+; SDAG-GFX9-NEXT: v_perm_b32 v0, v0, v2, s4
+; SDAG-GFX9-NEXT: s_setpc_b64 s[30:31]
+;
+; SDAG-VI-LABEL: mixhi_fptrunc_fadd:
+; SDAG-VI: ; %bb.0: ; %.entry
+; SDAG-VI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; SDAG-VI-NEXT: v_add_f32_e32 v0, v0, v1
+; SDAG-VI-NEXT: v_cvt_f16_f32_sdwa v0, v0 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:DWORD
+; SDAG-VI-NEXT: v_or_b32_sdwa v0, v2, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_0 src1_sel:DWORD
+; SDAG-VI-NEXT: s_setpc_b64 s[30:31]
+;
+; SDAG-CI-LABEL: mixhi_fptrunc_fadd:
+; SDAG-CI: ; %bb.0: ; %.entry
+; SDAG-CI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; SDAG-CI-NEXT: v_add_f32_e32 v0, v0, v1
+; SDAG-CI-NEXT: v_cvt_f16_f32_e32 v0, v0
+; SDAG-CI-NEXT: v_and_b32_e32 v1, 0xffff, v2
+; SDAG-CI-NEXT: v_lshlrev_b32_e32 v0, 16, v0
+; SDAG-CI-NEXT: v_or_b32_e32 v0, v1, v0
+; SDAG-CI-NEXT: s_setpc_b64 s[30:31]
+;
+; GISEL-GFX11-TRUE16-LABEL: mixhi_fptrunc_fadd:
+; GISEL-GFX11-TRUE16: ; %bb.0: ; %.entry
+; GISEL-GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GISEL-GFX11-TRUE16-NEXT: v_add_f32_e32 v0, v0, v1
+; GISEL-GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GISEL-GFX11-TRUE16-NEXT: v_cvt_f16_f32_e32 v2.h, v0
+; GISEL-GFX11-TRUE16-NEXT: v_mov_b32_e32 v0, v2
+; GISEL-GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]
+;
+; GISEL-GFX11-FAKE16-LABEL: mixhi_fptrunc_fadd:
+; GISEL-GFX11-FAKE16: ; %bb.0: ; %.entry
+; GISEL-GFX11-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GISEL-GFX11-FAKE16-NEXT: v_dual_add_f32 v0, v0, v1 :: v_dual_and_b32 v1, 0xffff, v2
+; GISEL-GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GISEL-GFX11-FAKE16-NEXT: v_cvt_f16_f32_e32 v0, v0
+; GISEL-GFX11-FAKE16-NEXT: v_lshl_or_b32 v0, v0, 16, v1
+; GISEL-GFX11-FAKE16-NEXT: s_setpc_b64 s[30:31]
+;
+; GISEL-GFX9-LABEL: mixhi_fptrunc_fadd:
+; GISEL-GFX9: ; %bb.0: ; %.entry
+; GISEL-GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GISEL-GFX9-NEXT: v_add_f32_e32 v0, v0, v1
+; GISEL-GFX9-NEXT: v_cvt_f16_f32_sdwa v0, v0 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:DWORD
+; GISEL-GFX9-NEXT: v_or_b32_sdwa v0, v0, v2 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_0
+; GISEL-GFX9-NEXT: s_setpc_b64 s[30:31]
+;
+; GISEL-VI-LABEL: mixhi_fptrunc_fadd:
+; GISEL-VI: ; %bb.0: ; %.entry
+; GISEL-VI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GISEL-VI-NEXT: v_add_f32_e32 v0, v0, v1
+; GISEL-VI-NEXT: v_cvt_f16_f32_e32 v0, v0
+; GISEL-VI-NEXT: v_mov_b32_e32 v1, 16
+; GISEL-VI-NEXT: v_lshlrev_b32_sdwa v0, v1, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_0
+; GISEL-VI-NEXT: v_or_b32_sdwa v0, v2, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_0 src1_sel:DWORD
+; GISEL-VI-NEXT: s_setpc_b64 s[30:31]
+;
+; GISEL-CI-LABEL: mixhi_fptrunc_fadd:
+; GISEL-CI: ; %bb.0: ; %.entry
+; GISEL-CI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GISEL-CI-NEXT: v_add_f32_e32 v0, v0, v1
+; GISEL-CI-NEXT: v_cvt_f16_f32_e32 v0, v0
+; GISEL-CI-NEXT: v_and_b32_e32 v1, 0xffff, v2
+; GISEL-CI-NEXT: v_bfe_u32 v0, v0, 0, 16
+; GISEL-CI-NEXT: v_lshlrev_b32_e32 v0, 16, v0
+; GISEL-CI-NEXT: v_or_b32_e32 v0, v1, v0
+; GISEL-CI-NEXT: s_setpc_b64 s[30:31]
+.entry:
+ %add = fadd float %a, %b
+ %trunc = fptrunc float %add to half
+ %vec = insertelement <2 x half> poison, half %lo, i32 0
+ %vec.result = insertelement <2 x half> %vec, half %trunc, i32 1
+ ret <2 x half> %vec.result
+}
+
+define <2 x half> @mixhi_fptrunc_fadd_f16_denormals(float %a, float %b, half %lo) #2 {
+; SDAG-GFX11-TRUE16-LABEL: mixhi_fptrunc_fadd_f16_denormals:
+; SDAG-GFX11-TRUE16: ; %bb.0: ; %.entry
+; SDAG-GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; SDAG-GFX11-TRUE16-NEXT: v_add_f32_e32 v0, v0, v1
+; SDAG-GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1)
+; SDAG-GFX11-TRUE16-NEXT: v_cvt_f16_f32_e32 v0.h, v0
+; SDAG-GFX11-TRUE16-NEXT: v_mov_b16_e32 v0.l, v2.l
+; SDAG-GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]
+;
+; SDAG-GFX11-FAKE16-LABEL: mixhi_fptrunc_fadd_f16_denormals:
+; SDAG-GFX11-FAKE16: ; %bb.0: ; %.entry
+; SDAG-GFX11-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; SDAG-GFX11-FAKE16-NEXT: v_add_f32_e32 v0, v0, v1
+; SDAG-GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; SDAG-GFX11-FAKE16-NEXT: v_cvt_f16_f32_e32 v0, v0
+; SDAG-GFX11-FAKE16-NEXT: v_perm_b32 v0, v0, v2, 0x5040100
+; SDAG-GFX11-FAKE16-NEXT: s_setpc_b64 s[30:31]
+;
+; SDAG-GFX9-LABEL: mixhi_fptrunc_fadd_f16_denormals:
+; SDAG-GFX9: ; %bb.0: ; %.entry
+; SDAG-GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; SDAG-GFX9-NEXT: v_add_f32_e32 v0, v0, v1
+; SDAG-GFX9-NEXT: v_cvt_f16_f32_e32 v0, v0
+; SDAG-GFX9-NEXT: s_mov_b32 s4, 0x5040100
+; SDAG-GFX9-NEXT: v_perm_b32 v0, v0, v2, s4
+; SDAG-GFX9-NEXT: s_setpc_b64 s[30:31]
+;
+; SDAG-VI-LABEL: mixhi_fptrunc_fadd_f16_denormals:
+; SDAG-VI: ; %bb.0: ; %.entry
+; SDAG-VI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; SDAG-VI-NEXT: v_add_f32_e32 v0, v0, v1
+; SDAG-VI-NEXT: v_cvt_f16_f32_sdwa v0, v0 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:DWORD
+; SDAG-VI-NEXT: v_or_b32_sdwa v0, v2, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_0 src1_sel:DWORD
+; SDAG-VI-NEXT: s_setpc_b64 s[30:31]
+;
+; SDAG-CI-LABEL: mixhi_fptrunc_fadd_f16_denormals:
+; SDAG-CI: ; %bb.0: ; %.entry
+; SDAG-CI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; SDAG-CI-NEXT: v_add_f32_e32 v0, v0, v1
+; SDAG-CI-NEXT: v_cvt_f16_f32_e32 v0, v0
+; SDAG-CI-NEXT: v_and_b32_e32 v1, 0xffff, v2
+; SDAG-CI-NEXT: v_lshlrev_b32_e32 v0, 16, v0
+; SDAG-CI-NEXT: v_or_b32_e32 v0, v1, v0
+; SDAG-CI-NEXT: s_setpc_b64 s[30:31]
+;
+; GISEL-GFX11-TRUE16-LABEL: mixhi_fptrunc_fadd_f16_denormals:
+; GISEL-GFX11-TRUE16: ; %bb.0: ; %.entry
+; GISEL-GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GISEL-GFX11-TRUE16-NEXT: v_add_f32_e32 v0, v0, v1
+; GISEL-GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GISEL-GFX11-TRUE16-NEXT: v_cvt_f16_f32_e32 v2.h, v0
+; GISEL-GFX11-TRUE16-NEXT: v_mov_b32_e32 v0, v2
+; GISEL-GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]
+;
+; GISEL-GFX11-FAKE16-LABEL: mixhi_fptrunc_fadd_f16_denormals:
+; GISEL-GFX11-FAKE16: ; %bb.0: ; %.entry
+; GISEL-GFX11-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GISEL-GFX11-FAKE16-NEXT: v_dual_add_f32 v0, v0, v1 :: v_dual_and_b32 v1, 0xffff, v2
+; GISEL-GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GISEL-GFX11-FAKE16-NEXT: v_cvt_f16_f32_e32 v0, v0
+; GISEL-GFX11-FAKE16-NEXT: v_lshl_or_b32 v0, v0, 16, v1
+; GISEL-GFX11-FAKE16-NEXT: s_setpc_b64 s[30:31]
+;
+; GISEL-GFX9-LABEL: mixhi_fptrunc_fadd_f16_denormals:
+; GISEL-GFX9: ; %bb.0: ; %.entry
+; GISEL-GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GISEL-GFX9-NEXT: v_add_f32_e32 v0, v0, v1
+; GISEL-GFX9-NEXT: v_cvt_f16_f32_sdwa v0, v0 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:DWORD
+; GISEL-GFX9-NEXT: v_or_b32_sdwa v0, v0, v2 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_0
+; GISEL-GFX9-NEXT: s_setpc_b64 s[30:31]
+;
+; GISEL-VI-LABEL: mixhi_fptrunc_fadd_f16_denormals:
+; GISEL-VI: ; %bb.0: ; %.entry
+; GISEL-VI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GISEL-VI-NEXT: v_add_f32_e32 v0, v0, v1
+; GISEL-VI-NEXT: v_cvt_f16_f32_e32 v0, v0
+; GISEL-VI-NEXT: v_mov_b32_e32 v1, 16
+; GISEL-VI-NEXT: v_lshlrev_b32_sdwa v0, v1, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_0
+; GISEL-VI-NEXT: v_or_b32_sdwa v0, v2, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_0 src1_sel:DWORD
+; GISEL-VI-NEXT: s_setpc_b64 s[30:31]
+;
+; GISEL-CI-LABEL: mixhi_fptrunc_fadd_f16_denormals:
+; GISEL-CI: ; %bb.0: ; %.entry
+; GISEL-CI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GISEL-CI-NEXT: v_add_f32_e32 v0, v0, v1
+; GISEL-CI-NEXT: v_cvt_f16_f32_e32 v0, v0
+; GISEL-CI-NEXT: v_and_b32_e32 v1, 0xffff, v2
+; GISEL-CI-NEXT: v_bfe_u32 v0, v0, 0, 16
+; GISEL-CI-NEXT: v_lshlrev_b32_e32 v0, 16, v0
+; GISEL-CI-NEXT: v_or_b32_e32 v0, v1, v0
+; GISEL-CI-NEXT: s_setpc_b64 s[30:31]
+.entry:
+ %add = fadd float %a, %b
+ %trunc = fptrunc float %add to half
+ %vec = insertelement <2 x half> poison, half %lo, i32 0
+ %vec.result = insertelement <2 x half> %vec, half %trunc, i32 1
+ ret <2 x half> %vec.result
+}
+
+define <2 x half> @mixhi_fptrunc_fsub(float %a, float %b, half %lo) #0 {
+; SDAG-GFX11-TRUE16-LABEL: mixhi_fptrunc_fsub:
+; SDAG-GFX11-TRUE16: ; %bb.0: ; %.entry
+; SDAG-GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; SDAG-GFX11-TRUE16-NEXT: v_sub_f32_e32 v0, v0, v1
+; SDAG-GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1)
+; SDAG-GFX11-TRUE16-NEXT: v_cvt_f16_f32_e32 v0.h, v0
+; SDAG-GFX11-TRUE16-NEXT: v_mov_b16_e32 v0.l, v2.l
+; SDAG-GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]
+;
+; SDAG-GF...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/224909
More information about the llvm-commits
mailing list