[llvm] [AMDGPU] Use `v_cvt_pk_*` instructions for i16_f32 saturated conversions (PR #202680)
Igor Wodiany via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 12 03:31:50 PDT 2026
https://github.com/IgWod updated https://github.com/llvm/llvm-project/pull/202680
>From 457ceae5e06934ac2af881bcf2cf3f5de78f8f30 Mon Sep 17 00:00:00 2001
From: Igor Wodiany <igor.wodiany at amd.com>
Date: Thu, 9 Apr 2026 13:07:14 +0100
Subject: [PATCH 1/2] [AMDGPU] Use v_cvt_pk_* instructions for saturated
conversions
---
llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp | 3 +
.../lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp | 8 +-
.../AMDGPU/AMDGPURegBankLegalizeRules.cpp | 7 +-
llvm/lib/Target/AMDGPU/SOPInstructions.td | 15 +
llvm/lib/Target/AMDGPU/VOP3PInstructions.td | 46 ++
llvm/test/CodeGen/AMDGPU/fptosi-sat-scalar.ll | 96 ++--
llvm/test/CodeGen/AMDGPU/fptosi-sat-vector.ll | 418 ++++++++++++------
llvm/test/CodeGen/AMDGPU/fptoui-sat-scalar.ll | 45 +-
llvm/test/CodeGen/AMDGPU/fptoui-sat-vector.ll | 356 +++++++++++----
9 files changed, 696 insertions(+), 298 deletions(-)
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
index 78fcd0fd24b6f..9a64e1e6365ac 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
@@ -3949,6 +3949,9 @@ SDValue AMDGPUTargetLowering::LowerFP_TO_INT_SAT(const SDValue Op,
if (DstVT == MVT::i16 && SatWidth == DstWidth && SrcVT == MVT::f16)
return Op;
+ if (DstVT == MVT::i16 && SatWidth == 16 && SrcVT == MVT::f32)
+ return Op;
+
// Perform all saturation at selected width (i16 or i32) and truncate
if (SatWidth < DstWidth && SatWidth <= 32) {
// For f16 conversion with sub-i16 saturation perform saturation
diff --git a/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp b/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp
index e341392ae068a..b4461f2e990a2 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp
@@ -1210,14 +1210,18 @@ AMDGPULegalizerInfo::AMDGPULegalizerInfo(const GCNSubtarget &ST_,
// clang-format off
auto &FPToISat = getActionDefinitionsBuilder({G_FPTOSI_SAT, G_FPTOUI_SAT})
- .legalFor({{S32, S32}, {S32, S64}})
- .legalFor(ST.has16BitInsts(),{{S16, S16}})
+ .legalFor({{S32, S32}, {S32, S64}, {S16, S32}})
+ .legalFor(ST.has16BitInsts(), {{S16, S16}})
+ .legalFor(ST.hasGFX11Insts(), {{V2S16, V2S32}})
.narrowScalarFor({{S64, S16}}, changeTo(0, S32));
// If available, widen width <16 to i16, intead of i32 so v_cvt_i16/u16_f16 can be used.
if (ST.has16BitInsts())
FPToISat.minScalarIf(typeIs(1, S16), 0, S16);
+ if (ST.hasGFX11Insts())
+ FPToISat.clampMaxNumElements(0, S16, 2);
+
FPToISat.minScalar(1, S32);
FPToISat.minScalar(0, S32)
.widenScalarToNextPow2(0, 32)
diff --git a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp
index 60eb33b64fc0d..33f40df05ba44 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp
@@ -1502,11 +1502,16 @@ RegBankLegalizeRules::RegBankLegalizeRules(const GCNSubtarget &_ST,
.Any({{UniS32, S16}, {{Sgpr32}, {Sgpr16}}}, hasSALUFloat)
.Any({{UniS32, S16}, {{UniInVgprS32}, {Vgpr16}}}, !hasSALUFloat)
.Any({{DivS32, S16}, {{Vgpr32}, {Vgpr16}}})
+ .Any({{UniS16, S32}, {{Sgpr16}, {Sgpr32}}}, hasSALUFloat)
+ .Any({{UniS16, S32}, {{UniInVgprS16}, {Vgpr32}}}, !hasSALUFloat)
+ .Any({{DivS16, S32}, {{Vgpr16}, {Vgpr32}}})
.Any({{UniS32, S32}, {{Sgpr32}, {Sgpr32}}}, hasSALUFloat)
.Any({{UniS32, S32}, {{UniInVgprS32}, {Vgpr32}}}, !hasSALUFloat)
.Any({{DivS32, S32}, {{Vgpr32}, {Vgpr32}}})
.Any({{UniS32, S64}, {{UniInVgprS32}, {Vgpr64}}})
- .Any({{DivS32, S64}, {{Vgpr32}, {Vgpr64}}});
+ .Any({{DivS32, S64}, {{Vgpr32}, {Vgpr64}}})
+ .Any({{UniV2S16, V2S32}, {{UniInVgprV2S16}, {SgprV2S32}}})
+ .Any({{DivV2S16, V2S32}, {{VgprV2S16}, {VgprV2S32}}});
addRulesForGOpcs({G_UITOFP, G_SITOFP})
.Any({{UniS16, S16}, {{UniInVgprS16}, {Vgpr16}}})
diff --git a/llvm/lib/Target/AMDGPU/SOPInstructions.td b/llvm/lib/Target/AMDGPU/SOPInstructions.td
index ef4333ef055cd..a486bf7df52c7 100644
--- a/llvm/lib/Target/AMDGPU/SOPInstructions.td
+++ b/llvm/lib/Target/AMDGPU/SOPInstructions.td
@@ -724,6 +724,21 @@ def S_MAX_U32 : SOP2_32 <"s_max_u32",
} // End isCommutable = 1
} // End Defs = [SCC]
+// f32 -> i16 saturated conversions. Required because those conversions
+// are kept legal for the V_CVT_PK_[IU]16_F32 packed patterns.
+class SOP_FPToUSatPat<dag lhs, int hi> : GCNPat<
+ lhs, (S_MIN_U32 (S_CVT_U32_F32 (f32 $src0)), (i32 hi))>;
+class SOP_FPToSSatPat<dag lhs, int hi, int lo> : GCNPat<
+ lhs, (S_MAX_I32 (S_MIN_I32 (S_CVT_I32_F32 (f32 $src0)), (i32 hi)),
+ (i32 lo))>;
+
+let SubtargetPredicate = HasSALUFloatInsts, AddedComplexity = 9 in {
+ def : SOP_FPToUSatPat<(i16 (UniformBinFrag<fp_to_uint_sat> f32:$src0, i16)),
+ 0xffff>;
+ def : SOP_FPToSSatPat<(i16 (UniformBinFrag<fp_to_sint_sat> f32:$src0, i16)),
+ 0x7fff, 0xffff8000>;
+}
+
let SubtargetPredicate = isGFX12Plus in {
def S_ADD_U64 : SOP2_64<"s_add_u64">{
let isCommutable = 1;
diff --git a/llvm/lib/Target/AMDGPU/VOP3PInstructions.td b/llvm/lib/Target/AMDGPU/VOP3PInstructions.td
index 5371d7fce8812..5718eb503d5c8 100644
--- a/llvm/lib/Target/AMDGPU/VOP3PInstructions.td
+++ b/llvm/lib/Target/AMDGPU/VOP3PInstructions.td
@@ -3139,3 +3139,49 @@ defm V_DOT8_U32_U4 : VOP3P_Real_gfx10_gfx11_gfx12_gfx13<0x19>;
defm V_DOT4_I32_I8 : VOP3P_Real_gfx10 <0x16>;
defm V_DOT8_I32_I4 : VOP3P_Real_gfx10 <0x18>;
+
+//===----------------------------------------------------------------------===//
+// GFX11+ Patterns
+//===----------------------------------------------------------------------===//
+
+// Packed f32 -> i16 saturated conversion.
+multiclass CvtPkF32ToI16Pat<SDPatternOperator dagOp, Instruction inst> {
+ def : GCNPat<(v2i16 (build_vector
+ (i16 (dagOp (f32 (VOP3Mods f32:$src0, i32:$src0_modifiers)), i16)),
+ (i16 (dagOp (f32 (VOP3Mods f32:$src1, i32:$src1_modifiers)), i16)))),
+ (inst $src0_modifiers, $src0, $src1_modifiers, $src1)>;
+ def : GCNPat<(v2i16 (dagOp (v2f32 VReg_64:$src), i16)),
+ (inst 0, (EXTRACT_SUBREG VReg_64:$src, sub0),
+ 0, (EXTRACT_SUBREG VReg_64:$src, sub1))>;
+ def : GCNPat<(v2i16 (dagOp (v2f32 SReg_64:$src), i16)),
+ (inst 0, (EXTRACT_SUBREG SReg_64:$src, sub0),
+ 0, (EXTRACT_SUBREG SReg_64:$src, sub1))>;
+}
+
+multiclass FPToIntSatI16Pat<dag lhs, dag rhs> {
+ let True16Predicate = UseRealTrue16Insts in
+ def : GCNPat<lhs, (EXTRACT_SUBREG rhs, lo16)>;
+ let True16Predicate = NotUseRealTrue16Insts in
+ def : GCNPat<lhs, rhs>;
+}
+
+multiclass FPToSSatI16Pat<dag lhs, int hi, int lo> {
+ defm : FPToIntSatI16Pat<lhs,
+ (V_MED3_I32_e64 (V_CVT_I32_F32_e64 $src0_modifiers, $src0),
+ (V_MOV_B32_e32 (i32 lo)), (S_MOV_B32 (i32 hi)))>;
+}
+multiclass FPToUSatI16Pat<dag lhs, int hi> {
+ defm : FPToIntSatI16Pat<lhs,
+ (V_MIN_U32_e64 (V_CVT_U32_F32_e64 $src0_modifiers, $src0), (i32 hi))>;
+}
+
+let SubtargetPredicate = isGFX11Plus in {
+ // f32 -> i16 saturated conversion.
+ defm : CvtPkF32ToI16Pat<fp_to_sint_sat, V_CVT_PK_I16_F32_e64>;
+ defm : CvtPkF32ToI16Pat<fp_to_uint_sat, V_CVT_PK_U16_F32_e64>;
+}
+
+// Fallback for f32 -> i16 saturated conversion. Required because
+// f32 -> i16 has to be legal so that the packed pattern above can match.
+defm : FPToSSatI16Pat<(i16 (fp_to_sint_sat (f32 (VOP3Mods f32:$src0, i32:$src0_modifiers)), i16)), 0x7fff, 0x8000>;
+defm : FPToUSatI16Pat<(i16 (fp_to_uint_sat (f32 (VOP3Mods f32:$src0, i32:$src0_modifiers)), i16)), 0xffff>;
diff --git a/llvm/test/CodeGen/AMDGPU/fptosi-sat-scalar.ll b/llvm/test/CodeGen/AMDGPU/fptosi-sat-scalar.ll
index 92cad3f0f4bf3..c75f36e7df7d4 100644
--- a/llvm/test/CodeGen/AMDGPU/fptosi-sat-scalar.ll
+++ b/llvm/test/CodeGen/AMDGPU/fptosi-sat-scalar.ll
@@ -132,26 +132,26 @@ define i16 @test_signed_i16_f32(float %f) nounwind {
; GFX7-GI: ; %bb.0:
; GFX7-GI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX7-GI-NEXT: v_cvt_i32_f32_e32 v0, v0
-; GFX7-GI-NEXT: v_mov_b32_e32 v1, 0x7fff
-; GFX7-GI-NEXT: v_mov_b32_e32 v2, 0xffff8000
-; GFX7-GI-NEXT: v_med3_i32 v0, v0, v2, v1
+; GFX7-GI-NEXT: s_movk_i32 s4, 0x7fff
+; GFX7-GI-NEXT: v_mov_b32_e32 v1, 0x8000
+; GFX7-GI-NEXT: v_med3_i32 v0, v0, v1, s4
; GFX7-GI-NEXT: s_setpc_b64 s[30:31]
;
; GFX9-LABEL: test_signed_i16_f32:
; GFX9: ; %bb.0:
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-NEXT: v_cvt_i32_f32_e32 v0, v0
-; GFX9-NEXT: s_movk_i32 s4, 0x8000
-; GFX9-NEXT: v_mov_b32_e32 v1, 0x7fff
-; GFX9-NEXT: v_med3_i32 v0, v0, s4, v1
+; GFX9-NEXT: s_movk_i32 s4, 0x7fff
+; GFX9-NEXT: v_mov_b32_e32 v1, 0x8000
+; GFX9-NEXT: v_med3_i32 v0, v0, v1, s4
; GFX9-NEXT: s_setpc_b64 s[30:31]
;
; GFX11-LABEL: test_signed_i16_f32:
; GFX11: ; %bb.0:
; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX11-NEXT: v_cvt_i32_f32_e32 v0, v0
-; GFX11-NEXT: s_movk_i32 s0, 0x8000
-; GFX11-NEXT: v_med3_i32 v0, v0, s0, 0x7fff
+; GFX11-NEXT: v_mov_b32_e32 v1, 0x8000
+; GFX11-NEXT: v_med3_i32 v0, v0, v1, 0x7fff
; GFX11-NEXT: s_setpc_b64 s[30:31]
;
; GFX12-ISEL-LABEL: test_signed_i16_f32:
@@ -162,9 +162,8 @@ define i16 @test_signed_i16_f32(float %f) nounwind {
; GFX12-ISEL-NEXT: s_wait_bvhcnt 0x0
; GFX12-ISEL-NEXT: s_wait_kmcnt 0x0
; GFX12-ISEL-NEXT: v_cvt_i32_f32_e32 v0, v0
-; GFX12-ISEL-NEXT: s_movk_i32 s0, 0x8000
-; GFX12-ISEL-NEXT: s_wait_alu depctr_sa_sdst(0)
-; GFX12-ISEL-NEXT: v_med3_i32 v0, v0, s0, 0x7fff
+; GFX12-ISEL-NEXT: v_mov_b32_e32 v1, 0x8000
+; GFX12-ISEL-NEXT: v_med3_i32 v0, v0, v1, 0x7fff
; GFX12-ISEL-NEXT: s_setpc_b64 s[30:31]
;
; GFX12-GI-LABEL: test_signed_i16_f32:
@@ -174,8 +173,8 @@ define i16 @test_signed_i16_f32(float %f) nounwind {
; GFX12-GI-NEXT: s_wait_samplecnt 0x0
; GFX12-GI-NEXT: s_wait_bvhcnt 0x0
; GFX12-GI-NEXT: s_wait_kmcnt 0x0
+; GFX12-GI-NEXT: v_mov_b32_e32 v1, 0x8000
; GFX12-GI-NEXT: v_cvt_i32_f32_e32 v0, v0
-; GFX12-GI-NEXT: v_mov_b32_e32 v1, 0xffff8000
; GFX12-GI-NEXT: v_med3_i32 v0, v0, v1, 0x7fff
; GFX12-GI-NEXT: s_setpc_b64 s[30:31]
%x = call i16 @llvm.fptosi.sat.i16.f32(float %f)
@@ -548,57 +547,43 @@ define i16 @test_s_signed_i16_f32(float inreg %f) nounwind {
; GFX7-GI: ; %bb.0:
; GFX7-GI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX7-GI-NEXT: v_cvt_i32_f32_e32 v0, s16
-; GFX7-GI-NEXT: v_readfirstlane_b32 s4, v0
-; GFX7-GI-NEXT: s_min_i32 s4, s4, 0x7fff
-; GFX7-GI-NEXT: s_max_i32 s4, s4, 0xffff8000
-; GFX7-GI-NEXT: v_mov_b32_e32 v0, s4
+; GFX7-GI-NEXT: s_movk_i32 s4, 0x7fff
+; GFX7-GI-NEXT: v_mov_b32_e32 v1, 0x8000
+; GFX7-GI-NEXT: v_med3_i32 v0, v0, v1, s4
; GFX7-GI-NEXT: s_setpc_b64 s[30:31]
;
; GFX9-LABEL: test_s_signed_i16_f32:
; GFX9: ; %bb.0:
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-NEXT: v_cvt_i32_f32_e32 v0, s16
-; GFX9-NEXT: s_movk_i32 s4, 0x8000
-; GFX9-NEXT: v_mov_b32_e32 v1, 0x7fff
-; GFX9-NEXT: v_med3_i32 v0, v0, s4, v1
+; GFX9-NEXT: s_movk_i32 s4, 0x7fff
+; GFX9-NEXT: v_mov_b32_e32 v1, 0x8000
+; GFX9-NEXT: v_med3_i32 v0, v0, v1, s4
; GFX9-NEXT: s_setpc_b64 s[30:31]
;
; GFX11-LABEL: test_s_signed_i16_f32:
; GFX11: ; %bb.0:
; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX11-NEXT: v_cvt_i32_f32_e32 v0, s0
-; GFX11-NEXT: s_movk_i32 s0, 0x8000
-; GFX11-NEXT: v_med3_i32 v0, v0, s0, 0x7fff
+; GFX11-NEXT: v_mov_b32_e32 v1, 0x8000
+; GFX11-NEXT: v_med3_i32 v0, v0, v1, 0x7fff
; GFX11-NEXT: s_setpc_b64 s[30:31]
;
-; GFX12-ISEL-LABEL: test_s_signed_i16_f32:
-; GFX12-ISEL: ; %bb.0:
-; GFX12-ISEL-NEXT: s_wait_loadcnt_dscnt 0x0
-; GFX12-ISEL-NEXT: s_wait_expcnt 0x0
-; GFX12-ISEL-NEXT: s_wait_samplecnt 0x0
-; GFX12-ISEL-NEXT: s_wait_bvhcnt 0x0
-; GFX12-ISEL-NEXT: s_wait_kmcnt 0x0
-; GFX12-ISEL-NEXT: v_mov_b32_e32 v0, 0x7fff
-; GFX12-ISEL-NEXT: s_cvt_i32_f32 s0, s0
-; GFX12-ISEL-NEXT: s_wait_alu depctr_sa_sdst(0)
-; GFX12-ISEL-NEXT: v_med3_i32 v0, 0xffff8000, s0, v0
-; GFX12-ISEL-NEXT: s_setpc_b64 s[30:31]
-;
-; GFX12-GI-LABEL: test_s_signed_i16_f32:
-; GFX12-GI: ; %bb.0:
-; GFX12-GI-NEXT: s_wait_loadcnt_dscnt 0x0
-; GFX12-GI-NEXT: s_wait_expcnt 0x0
-; GFX12-GI-NEXT: s_wait_samplecnt 0x0
-; GFX12-GI-NEXT: s_wait_bvhcnt 0x0
-; GFX12-GI-NEXT: s_wait_kmcnt 0x0
-; GFX12-GI-NEXT: s_cvt_i32_f32 s0, s0
-; GFX12-GI-NEXT: s_wait_alu depctr_sa_sdst(0)
-; GFX12-GI-NEXT: s_min_i32 s0, s0, 0x7fff
-; GFX12-GI-NEXT: s_wait_alu depctr_sa_sdst(0)
-; GFX12-GI-NEXT: s_max_i32 s0, s0, 0xffff8000
-; GFX12-GI-NEXT: s_wait_alu depctr_sa_sdst(0)
-; GFX12-GI-NEXT: v_mov_b32_e32 v0, s0
-; GFX12-GI-NEXT: s_setpc_b64 s[30:31]
+; GFX12-LABEL: test_s_signed_i16_f32:
+; GFX12: ; %bb.0:
+; GFX12-NEXT: s_wait_loadcnt_dscnt 0x0
+; GFX12-NEXT: s_wait_expcnt 0x0
+; GFX12-NEXT: s_wait_samplecnt 0x0
+; GFX12-NEXT: s_wait_bvhcnt 0x0
+; GFX12-NEXT: s_wait_kmcnt 0x0
+; GFX12-NEXT: s_cvt_i32_f32 s0, s0
+; GFX12-NEXT: s_wait_alu depctr_sa_sdst(0)
+; GFX12-NEXT: s_min_i32 s0, s0, 0x7fff
+; GFX12-NEXT: s_wait_alu depctr_sa_sdst(0)
+; GFX12-NEXT: s_max_i32 s0, s0, 0xffff8000
+; GFX12-NEXT: s_wait_alu depctr_sa_sdst(0)
+; GFX12-NEXT: v_mov_b32_e32 v0, s0
+; GFX12-NEXT: s_setpc_b64 s[30:31]
%x = call i16 @llvm.fptosi.sat.i16.f32(float %f)
ret i16 %x
}
@@ -1845,10 +1830,10 @@ define i16 @test_signed_i16_f16(half %f) nounwind {
; GFX7-GI: ; %bb.0:
; GFX7-GI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v0, v0
-; GFX7-GI-NEXT: v_mov_b32_e32 v1, 0x7fff
-; GFX7-GI-NEXT: v_mov_b32_e32 v2, 0xffff8000
+; GFX7-GI-NEXT: s_movk_i32 s4, 0x7fff
+; GFX7-GI-NEXT: v_mov_b32_e32 v1, 0x8000
; GFX7-GI-NEXT: v_cvt_i32_f32_e32 v0, v0
-; GFX7-GI-NEXT: v_med3_i32 v0, v0, v2, v1
+; GFX7-GI-NEXT: v_med3_i32 v0, v0, v1, s4
; GFX7-GI-NEXT: s_setpc_b64 s[30:31]
;
; GFX9-LABEL: test_signed_i16_f16:
@@ -2254,11 +2239,10 @@ define i16 @test_s_signed_i16_f16(half inreg %f) nounwind {
; GFX7-GI: ; %bb.0:
; GFX7-GI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v0, s16
+; GFX7-GI-NEXT: s_movk_i32 s4, 0x7fff
+; GFX7-GI-NEXT: v_mov_b32_e32 v1, 0x8000
; GFX7-GI-NEXT: v_cvt_i32_f32_e32 v0, v0
-; GFX7-GI-NEXT: v_readfirstlane_b32 s4, v0
-; GFX7-GI-NEXT: s_min_i32 s4, s4, 0x7fff
-; GFX7-GI-NEXT: s_max_i32 s4, s4, 0xffff8000
-; GFX7-GI-NEXT: v_mov_b32_e32 v0, s4
+; GFX7-GI-NEXT: v_med3_i32 v0, v0, v1, s4
; GFX7-GI-NEXT: s_setpc_b64 s[30:31]
;
; GFX9-LABEL: test_s_signed_i16_f16:
diff --git a/llvm/test/CodeGen/AMDGPU/fptosi-sat-vector.ll b/llvm/test/CodeGen/AMDGPU/fptosi-sat-vector.ll
index a893711ce0942..89e09d80f1134 100644
--- a/llvm/test/CodeGen/AMDGPU/fptosi-sat-vector.ll
+++ b/llvm/test/CodeGen/AMDGPU/fptosi-sat-vector.ll
@@ -2873,26 +2873,26 @@ define <4 x i16> @test_signed_v4f16_v4i16(<4 x half> %f) {
; GFX7-GI-LABEL: test_signed_v4f16_v4i16:
; GFX7-GI: ; %bb.0:
; GFX7-GI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v2, v0
-; GFX7-GI-NEXT: v_lshrrev_b32_e32 v0, 16, v0
-; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v0, v0
+; GFX7-GI-NEXT: v_lshrrev_b32_e32 v2, 16, v0
+; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v2, v2
; GFX7-GI-NEXT: v_lshrrev_b32_e32 v3, 16, v1
+; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v0, v0
; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v3, v3
; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v1, v1
-; GFX7-GI-NEXT: v_cvt_i32_f32_e32 v0, v0
; GFX7-GI-NEXT: v_cvt_i32_f32_e32 v2, v2
+; GFX7-GI-NEXT: v_cvt_i32_f32_e32 v0, v0
; GFX7-GI-NEXT: v_cvt_i32_f32_e32 v3, v3
-; GFX7-GI-NEXT: v_mov_b32_e32 v4, 0x7fff
-; GFX7-GI-NEXT: v_mov_b32_e32 v5, 0xffff8000
+; GFX7-GI-NEXT: s_movk_i32 s4, 0x7fff
+; GFX7-GI-NEXT: v_mov_b32_e32 v4, 0x8000
; GFX7-GI-NEXT: v_cvt_i32_f32_e32 v1, v1
-; GFX7-GI-NEXT: v_med3_i32 v0, v0, v5, v4
-; GFX7-GI-NEXT: v_med3_i32 v2, v2, v5, v4
-; GFX7-GI-NEXT: v_and_b32_e32 v0, 0xffff, v0
-; GFX7-GI-NEXT: v_med3_i32 v3, v3, v5, v4
+; GFX7-GI-NEXT: v_med3_i32 v2, v2, v4, s4
+; GFX7-GI-NEXT: v_med3_i32 v0, v0, v4, s4
; GFX7-GI-NEXT: v_and_b32_e32 v2, 0xffff, v2
-; GFX7-GI-NEXT: v_lshlrev_b32_e32 v0, 16, v0
-; GFX7-GI-NEXT: v_med3_i32 v1, v1, v5, v4
-; GFX7-GI-NEXT: v_or_b32_e32 v0, v2, v0
+; GFX7-GI-NEXT: v_med3_i32 v3, v3, v4, s4
+; GFX7-GI-NEXT: v_and_b32_e32 v0, 0xffff, v0
+; GFX7-GI-NEXT: v_lshlrev_b32_e32 v2, 16, v2
+; GFX7-GI-NEXT: v_med3_i32 v1, v1, v4, s4
+; GFX7-GI-NEXT: v_or_b32_e32 v0, v0, v2
; GFX7-GI-NEXT: v_and_b32_e32 v2, 0xffff, v3
; GFX7-GI-NEXT: v_and_b32_e32 v1, 0xffff, v1
; GFX7-GI-NEXT: v_lshlrev_b32_e32 v2, 16, v2
@@ -3778,37 +3778,35 @@ define <4 x i16> @test_s_signed_v4f16_v4i16(<4 x half> inreg %f) {
; GFX7-GI: ; %bb.0:
; GFX7-GI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v0, s16
-; GFX7-GI-NEXT: s_lshr_b32 s4, s16, 16
-; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v1, s4
-; GFX7-GI-NEXT: s_lshr_b32 s4, s17, 16
+; GFX7-GI-NEXT: s_lshr_b32 s5, s16, 16
+; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v2, s5
+; GFX7-GI-NEXT: s_lshr_b32 s5, s17, 16
; GFX7-GI-NEXT: v_cvt_i32_f32_e32 v0, v0
-; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v2, s17
-; GFX7-GI-NEXT: v_cvt_i32_f32_e32 v1, v1
+; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v3, s17
+; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v4, s5
+; GFX7-GI-NEXT: s_movk_i32 s4, 0x7fff
+; GFX7-GI-NEXT: v_mov_b32_e32 v1, 0x8000
+; GFX7-GI-NEXT: v_med3_i32 v0, v0, v1, s4
+; GFX7-GI-NEXT: v_cvt_i32_f32_e32 v2, v2
; GFX7-GI-NEXT: v_readfirstlane_b32 s5, v0
-; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v0, s4
-; GFX7-GI-NEXT: v_readfirstlane_b32 s6, v1
-; GFX7-GI-NEXT: v_cvt_i32_f32_e32 v1, v2
-; GFX7-GI-NEXT: s_min_i32 s4, s6, 0x7fff
-; GFX7-GI-NEXT: v_cvt_i32_f32_e32 v0, v0
-; GFX7-GI-NEXT: s_min_i32 s5, s5, 0x7fff
-; GFX7-GI-NEXT: s_max_i32 s4, s4, 0xffff8000
-; GFX7-GI-NEXT: v_readfirstlane_b32 s6, v1
+; GFX7-GI-NEXT: v_cvt_i32_f32_e32 v0, v3
+; GFX7-GI-NEXT: v_cvt_i32_f32_e32 v3, v4
+; GFX7-GI-NEXT: v_med3_i32 v2, v2, v1, s4
+; GFX7-GI-NEXT: v_readfirstlane_b32 s6, v2
+; GFX7-GI-NEXT: v_med3_i32 v0, v0, v1, s4
; GFX7-GI-NEXT: v_readfirstlane_b32 s7, v0
-; GFX7-GI-NEXT: s_max_i32 s5, s5, 0xffff8000
-; GFX7-GI-NEXT: s_min_i32 s6, s6, 0x7fff
-; GFX7-GI-NEXT: s_min_i32 s7, s7, 0x7fff
-; GFX7-GI-NEXT: s_and_b32 s4, s4, 0xffff
-; GFX7-GI-NEXT: s_max_i32 s6, s6, 0xffff8000
-; GFX7-GI-NEXT: s_max_i32 s7, s7, 0xffff8000
-; GFX7-GI-NEXT: s_and_b32 s5, s5, 0xffff
-; GFX7-GI-NEXT: s_lshl_b32 s4, s4, 16
-; GFX7-GI-NEXT: s_or_b32 s4, s5, s4
-; GFX7-GI-NEXT: s_and_b32 s5, s6, 0xffff
-; GFX7-GI-NEXT: s_and_b32 s6, s7, 0xffff
+; GFX7-GI-NEXT: v_med3_i32 v0, v3, v1, s4
+; GFX7-GI-NEXT: v_readfirstlane_b32 s4, v0
+; GFX7-GI-NEXT: s_and_b32 s6, 0xffff, s6
+; GFX7-GI-NEXT: s_and_b32 s5, 0xffff, s5
; GFX7-GI-NEXT: s_lshl_b32 s6, s6, 16
+; GFX7-GI-NEXT: s_and_b32 s4, 0xffff, s4
; GFX7-GI-NEXT: s_or_b32 s5, s5, s6
-; GFX7-GI-NEXT: v_mov_b32_e32 v0, s4
-; GFX7-GI-NEXT: v_mov_b32_e32 v1, s5
+; GFX7-GI-NEXT: s_and_b32 s6, 0xffff, s7
+; GFX7-GI-NEXT: s_lshl_b32 s4, s4, 16
+; GFX7-GI-NEXT: s_or_b32 s4, s6, s4
+; GFX7-GI-NEXT: v_mov_b32_e32 v0, s5
+; GFX7-GI-NEXT: v_mov_b32_e32 v1, s4
; GFX7-GI-NEXT: s_setpc_b64 s[30:31]
;
; GFX9-LABEL: test_s_signed_v4f16_v4i16:
@@ -3896,12 +3894,12 @@ define <4 x i16> @test_s_signed_v4f16_v4i16(<4 x half> inreg %f) {
; GFX12-GI-NEXT: s_wait_bvhcnt 0x0
; GFX12-GI-NEXT: s_wait_kmcnt 0x0
; GFX12-GI-NEXT: s_lshr_b32 s2, s0, 16
-; GFX12-GI-NEXT: s_lshr_b32 s3, s1, 16
; GFX12-GI-NEXT: v_cvt_i16_f16_e32 v0.l, s0
+; GFX12-GI-NEXT: s_lshr_b32 s0, s1, 16
; GFX12-GI-NEXT: s_wait_alu depctr_sa_sdst(0)
; GFX12-GI-NEXT: v_cvt_i16_f16_e32 v1.l, s2
; GFX12-GI-NEXT: v_cvt_i16_f16_e32 v2.l, s1
-; GFX12-GI-NEXT: v_cvt_i16_f16_e32 v3.l, s3
+; GFX12-GI-NEXT: v_cvt_i16_f16_e32 v3.l, s0
; GFX12-GI-NEXT: v_readfirstlane_b32 s0, v0
; GFX12-GI-NEXT: v_readfirstlane_b32 s1, v1
; GFX12-GI-NEXT: v_readfirstlane_b32 s2, v2
@@ -4697,8 +4695,8 @@ define <8 x i16> @test_signed_v8f16_v8i16(<8 x half> %f) {
; GFX7-GI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX7-GI-NEXT: v_lshrrev_b32_e32 v4, 16, v0
; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v4, v4
-; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v0, v0
; GFX7-GI-NEXT: v_lshrrev_b32_e32 v5, 16, v1
+; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v0, v0
; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v5, v5
; GFX7-GI-NEXT: v_lshrrev_b32_e32 v6, 16, v2
; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v1, v1
@@ -4709,33 +4707,33 @@ define <8 x i16> @test_signed_v8f16_v8i16(<8 x half> %f) {
; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v2, v2
; GFX7-GI-NEXT: v_cvt_i32_f32_e32 v5, v5
; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v7, v7
-; GFX7-GI-NEXT: v_mov_b32_e32 v8, 0x7fff
-; GFX7-GI-NEXT: v_mov_b32_e32 v9, 0xffff8000
+; GFX7-GI-NEXT: s_movk_i32 s4, 0x7fff
+; GFX7-GI-NEXT: v_mov_b32_e32 v8, 0x8000
; GFX7-GI-NEXT: v_cvt_i32_f32_e32 v1, v1
; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v3, v3
-; GFX7-GI-NEXT: v_med3_i32 v4, v4, v9, v8
+; GFX7-GI-NEXT: v_med3_i32 v4, v4, v8, s4
; GFX7-GI-NEXT: v_cvt_i32_f32_e32 v6, v6
-; GFX7-GI-NEXT: v_med3_i32 v0, v0, v9, v8
+; GFX7-GI-NEXT: v_med3_i32 v0, v0, v8, s4
; GFX7-GI-NEXT: v_cvt_i32_f32_e32 v2, v2
; GFX7-GI-NEXT: v_and_b32_e32 v4, 0xffff, v4
-; GFX7-GI-NEXT: v_med3_i32 v5, v5, v9, v8
+; GFX7-GI-NEXT: v_med3_i32 v5, v5, v8, s4
; GFX7-GI-NEXT: v_cvt_i32_f32_e32 v7, v7
; GFX7-GI-NEXT: v_and_b32_e32 v0, 0xffff, v0
; GFX7-GI-NEXT: v_lshlrev_b32_e32 v4, 16, v4
-; GFX7-GI-NEXT: v_med3_i32 v1, v1, v9, v8
+; GFX7-GI-NEXT: v_med3_i32 v1, v1, v8, s4
; GFX7-GI-NEXT: v_cvt_i32_f32_e32 v3, v3
; GFX7-GI-NEXT: v_or_b32_e32 v0, v0, v4
; GFX7-GI-NEXT: v_and_b32_e32 v4, 0xffff, v5
-; GFX7-GI-NEXT: v_med3_i32 v6, v6, v9, v8
+; GFX7-GI-NEXT: v_med3_i32 v6, v6, v8, s4
; GFX7-GI-NEXT: v_and_b32_e32 v1, 0xffff, v1
; GFX7-GI-NEXT: v_lshlrev_b32_e32 v4, 16, v4
-; GFX7-GI-NEXT: v_med3_i32 v2, v2, v9, v8
+; GFX7-GI-NEXT: v_med3_i32 v2, v2, v8, s4
; GFX7-GI-NEXT: v_or_b32_e32 v1, v1, v4
; GFX7-GI-NEXT: v_and_b32_e32 v4, 0xffff, v6
-; GFX7-GI-NEXT: v_med3_i32 v7, v7, v9, v8
+; GFX7-GI-NEXT: v_med3_i32 v7, v7, v8, s4
; GFX7-GI-NEXT: v_and_b32_e32 v2, 0xffff, v2
; GFX7-GI-NEXT: v_lshlrev_b32_e32 v4, 16, v4
-; GFX7-GI-NEXT: v_med3_i32 v3, v3, v9, v8
+; GFX7-GI-NEXT: v_med3_i32 v3, v3, v8, s4
; GFX7-GI-NEXT: v_or_b32_e32 v2, v2, v4
; GFX7-GI-NEXT: v_and_b32_e32 v4, 0xffff, v7
; GFX7-GI-NEXT: v_and_b32_e32 v3, 0xffff, v3
@@ -6244,70 +6242,64 @@ define <8 x i16> @test_s_signed_v8f16_v8i16(<8 x half> inreg %f) {
; GFX7-GI-LABEL: test_s_signed_v8f16_v8i16:
; GFX7-GI: ; %bb.0:
; GFX7-GI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v0, s16
; GFX7-GI-NEXT: s_lshr_b32 s4, s16, 16
+; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v0, s16
; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v1, s4
-; GFX7-GI-NEXT: s_lshr_b32 s5, s17, 16
+; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v3, s17
+; GFX7-GI-NEXT: s_movk_i32 s4, 0x7fff
; GFX7-GI-NEXT: v_cvt_i32_f32_e32 v0, v0
-; GFX7-GI-NEXT: s_lshr_b32 s4, s18, 16
-; GFX7-GI-NEXT: s_lshr_b32 s6, s19, 16
-; GFX7-GI-NEXT: v_readfirstlane_b32 s7, v0
-; GFX7-GI-NEXT: v_cvt_i32_f32_e32 v0, v1
-; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v1, s17
-; GFX7-GI-NEXT: s_min_i32 s7, s7, 0x7fff
-; GFX7-GI-NEXT: s_max_i32 s7, s7, 0xffff8000
+; GFX7-GI-NEXT: v_cvt_i32_f32_e32 v1, v1
+; GFX7-GI-NEXT: v_mov_b32_e32 v2, 0x8000
+; GFX7-GI-NEXT: s_lshr_b32 s5, s17, 16
+; GFX7-GI-NEXT: v_med3_i32 v0, v0, v2, s4
; GFX7-GI-NEXT: v_readfirstlane_b32 s8, v0
-; GFX7-GI-NEXT: v_cvt_i32_f32_e32 v0, v1
+; GFX7-GI-NEXT: v_med3_i32 v0, v1, v2, s4
; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v1, s5
-; GFX7-GI-NEXT: s_min_i32 s5, s8, 0x7fff
-; GFX7-GI-NEXT: s_max_i32 s5, s5, 0xffff8000
-; GFX7-GI-NEXT: v_readfirstlane_b32 s8, v0
-; GFX7-GI-NEXT: v_cvt_i32_f32_e32 v0, v1
-; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v1, s18
-; GFX7-GI-NEXT: s_min_i32 s8, s8, 0x7fff
-; GFX7-GI-NEXT: s_and_b32 s5, s5, 0xffff
-; GFX7-GI-NEXT: v_readfirstlane_b32 s9, v0
-; GFX7-GI-NEXT: v_cvt_i32_f32_e32 v0, v1
-; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v1, s4
-; GFX7-GI-NEXT: s_min_i32 s4, s9, 0x7fff
-; GFX7-GI-NEXT: s_max_i32 s4, s4, 0xffff8000
-; GFX7-GI-NEXT: v_readfirstlane_b32 s9, v0
-; GFX7-GI-NEXT: v_cvt_i32_f32_e32 v0, v1
-; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v1, s19
-; GFX7-GI-NEXT: s_max_i32 s8, s8, 0xffff8000
-; GFX7-GI-NEXT: s_min_i32 s9, s9, 0x7fff
-; GFX7-GI-NEXT: v_readfirstlane_b32 s10, v0
-; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v0, s6
+; GFX7-GI-NEXT: v_cvt_i32_f32_e32 v3, v3
+; GFX7-GI-NEXT: v_readfirstlane_b32 s5, v0
+; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v0, s18
; GFX7-GI-NEXT: v_cvt_i32_f32_e32 v1, v1
-; GFX7-GI-NEXT: s_min_i32 s6, s10, 0x7fff
-; GFX7-GI-NEXT: s_max_i32 s6, s6, 0xffff8000
+; GFX7-GI-NEXT: s_lshr_b32 s6, s18, 16
+; GFX7-GI-NEXT: v_med3_i32 v3, v3, v2, s4
+; GFX7-GI-NEXT: v_readfirstlane_b32 s9, v3
+; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v3, s6
; GFX7-GI-NEXT: v_cvt_i32_f32_e32 v0, v0
-; GFX7-GI-NEXT: v_readfirstlane_b32 s10, v1
-; GFX7-GI-NEXT: s_and_b32 s7, s7, 0xffff
+; GFX7-GI-NEXT: v_med3_i32 v1, v1, v2, s4
+; GFX7-GI-NEXT: s_lshr_b32 s7, s19, 16
+; GFX7-GI-NEXT: v_readfirstlane_b32 s6, v1
+; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v1, s19
+; GFX7-GI-NEXT: v_cvt_i32_f32_e32 v3, v3
+; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v4, s7
+; GFX7-GI-NEXT: v_med3_i32 v0, v0, v2, s4
+; GFX7-GI-NEXT: v_readfirstlane_b32 s7, v0
+; GFX7-GI-NEXT: v_cvt_i32_f32_e32 v0, v1
+; GFX7-GI-NEXT: v_med3_i32 v1, v3, v2, s4
+; GFX7-GI-NEXT: v_cvt_i32_f32_e32 v3, v4
+; GFX7-GI-NEXT: s_and_b32 s5, 0xffff, s5
+; GFX7-GI-NEXT: v_med3_i32 v0, v0, v2, s4
+; GFX7-GI-NEXT: s_and_b32 s8, 0xffff, s8
; GFX7-GI-NEXT: s_lshl_b32 s5, s5, 16
+; GFX7-GI-NEXT: s_and_b32 s6, 0xffff, s6
+; GFX7-GI-NEXT: v_readfirstlane_b32 s10, v1
; GFX7-GI-NEXT: v_readfirstlane_b32 s11, v0
-; GFX7-GI-NEXT: s_min_i32 s11, s11, 0x7fff
-; GFX7-GI-NEXT: s_and_b32 s4, s4, 0xffff
-; GFX7-GI-NEXT: s_max_i32 s9, s9, 0xffff8000
-; GFX7-GI-NEXT: s_min_i32 s10, s10, 0x7fff
-; GFX7-GI-NEXT: s_max_i32 s11, s11, 0xffff8000
-; GFX7-GI-NEXT: s_or_b32 s5, s7, s5
-; GFX7-GI-NEXT: s_and_b32 s7, s8, 0xffff
-; GFX7-GI-NEXT: s_lshl_b32 s4, s4, 16
-; GFX7-GI-NEXT: s_and_b32 s6, s6, 0xffff
-; GFX7-GI-NEXT: s_max_i32 s10, s10, 0xffff8000
-; GFX7-GI-NEXT: s_or_b32 s4, s7, s4
-; GFX7-GI-NEXT: s_and_b32 s7, s9, 0xffff
+; GFX7-GI-NEXT: v_med3_i32 v0, v3, v2, s4
+; GFX7-GI-NEXT: s_or_b32 s5, s8, s5
+; GFX7-GI-NEXT: s_and_b32 s8, 0xffff, s9
; GFX7-GI-NEXT: s_lshl_b32 s6, s6, 16
-; GFX7-GI-NEXT: s_and_b32 s8, s11, 0xffff
-; GFX7-GI-NEXT: s_or_b32 s6, s7, s6
-; GFX7-GI-NEXT: s_and_b32 s7, s10, 0xffff
+; GFX7-GI-NEXT: v_readfirstlane_b32 s4, v0
+; GFX7-GI-NEXT: s_or_b32 s6, s8, s6
+; GFX7-GI-NEXT: s_and_b32 s8, 0xffff, s10
+; GFX7-GI-NEXT: s_and_b32 s7, 0xffff, s7
; GFX7-GI-NEXT: s_lshl_b32 s8, s8, 16
+; GFX7-GI-NEXT: s_and_b32 s4, 0xffff, s4
; GFX7-GI-NEXT: s_or_b32 s7, s7, s8
+; GFX7-GI-NEXT: s_and_b32 s8, 0xffff, s11
+; GFX7-GI-NEXT: s_lshl_b32 s4, s4, 16
+; GFX7-GI-NEXT: s_or_b32 s4, s8, s4
; GFX7-GI-NEXT: v_mov_b32_e32 v0, s5
-; GFX7-GI-NEXT: v_mov_b32_e32 v1, s4
-; GFX7-GI-NEXT: v_mov_b32_e32 v2, s6
-; GFX7-GI-NEXT: v_mov_b32_e32 v3, s7
+; GFX7-GI-NEXT: v_mov_b32_e32 v1, s6
+; GFX7-GI-NEXT: v_mov_b32_e32 v2, s7
+; GFX7-GI-NEXT: v_mov_b32_e32 v3, s4
; GFX7-GI-NEXT: s_setpc_b64 s[30:31]
;
; GFX9-LABEL: test_s_signed_v8f16_v8i16:
@@ -6439,36 +6431,37 @@ define <8 x i16> @test_s_signed_v8f16_v8i16(<8 x half> inreg %f) {
; GFX12-GI-NEXT: s_wait_samplecnt 0x0
; GFX12-GI-NEXT: s_wait_bvhcnt 0x0
; GFX12-GI-NEXT: s_wait_kmcnt 0x0
-; GFX12-GI-NEXT: s_lshr_b32 s4, s0, 16
; GFX12-GI-NEXT: v_cvt_i16_f16_e32 v0.l, s0
+; GFX12-GI-NEXT: s_lshr_b32 s4, s0, 16
+; GFX12-GI-NEXT: v_cvt_i16_f16_e32 v2.l, s1
+; GFX12-GI-NEXT: s_lshr_b32 s1, s1, 16
; GFX12-GI-NEXT: s_wait_alu depctr_sa_sdst(0)
; GFX12-GI-NEXT: v_cvt_i16_f16_e32 v1.l, s4
+; GFX12-GI-NEXT: v_readfirstlane_b32 s0, v0
+; GFX12-GI-NEXT: v_cvt_i16_f16_e32 v0.l, s1
+; GFX12-GI-NEXT: s_lshr_b32 s1, s2, 16
+; GFX12-GI-NEXT: v_readfirstlane_b32 s5, v2
+; GFX12-GI-NEXT: s_wait_alu depctr_sa_sdst(0)
; GFX12-GI-NEXT: v_cvt_i16_f16_e32 v2.l, s1
-; GFX12-GI-NEXT: s_lshr_b32 s5, s1, 16
-; GFX12-GI-NEXT: s_lshr_b32 s0, s2, 16
; GFX12-GI-NEXT: s_lshr_b32 s1, s3, 16
-; GFX12-GI-NEXT: v_readfirstlane_b32 s4, v0
-; GFX12-GI-NEXT: v_readfirstlane_b32 s6, v1
-; GFX12-GI-NEXT: v_readfirstlane_b32 s7, v2
-; GFX12-GI-NEXT: s_wait_alu depctr_sa_sdst(0)
-; GFX12-GI-NEXT: v_cvt_i16_f16_e32 v0.l, s5
+; GFX12-GI-NEXT: v_readfirstlane_b32 s4, v1
; GFX12-GI-NEXT: v_cvt_i16_f16_e32 v1.l, s2
-; GFX12-GI-NEXT: v_cvt_i16_f16_e32 v2.l, s0
; GFX12-GI-NEXT: v_cvt_i16_f16_e32 v3.l, s3
+; GFX12-GI-NEXT: s_wait_alu depctr_sa_sdst(0)
; GFX12-GI-NEXT: v_cvt_i16_f16_e32 v4.l, s1
-; GFX12-GI-NEXT: v_readfirstlane_b32 s0, v0
-; GFX12-GI-NEXT: v_readfirstlane_b32 s1, v1
-; GFX12-GI-NEXT: v_readfirstlane_b32 s2, v2
-; GFX12-GI-NEXT: v_readfirstlane_b32 s3, v3
-; GFX12-GI-NEXT: v_readfirstlane_b32 s5, v4
-; GFX12-GI-NEXT: s_pack_ll_b32_b16 s4, s4, s6
-; GFX12-GI-NEXT: s_pack_ll_b32_b16 s0, s7, s0
-; GFX12-GI-NEXT: s_pack_ll_b32_b16 s1, s1, s2
+; GFX12-GI-NEXT: v_readfirstlane_b32 s1, v0
+; GFX12-GI-NEXT: v_readfirstlane_b32 s3, v2
+; GFX12-GI-NEXT: v_readfirstlane_b32 s2, v1
+; GFX12-GI-NEXT: v_readfirstlane_b32 s6, v3
+; GFX12-GI-NEXT: v_readfirstlane_b32 s7, v4
+; GFX12-GI-NEXT: s_pack_ll_b32_b16 s0, s0, s4
+; GFX12-GI-NEXT: s_pack_ll_b32_b16 s1, s5, s1
+; GFX12-GI-NEXT: s_pack_ll_b32_b16 s2, s2, s3
; GFX12-GI-NEXT: s_wait_alu depctr_sa_sdst(0)
-; GFX12-GI-NEXT: v_dual_mov_b32 v0, s4 :: v_dual_mov_b32 v1, s0
-; GFX12-GI-NEXT: s_pack_ll_b32_b16 s2, s3, s5
+; GFX12-GI-NEXT: v_dual_mov_b32 v0, s0 :: v_dual_mov_b32 v1, s1
+; GFX12-GI-NEXT: s_pack_ll_b32_b16 s3, s6, s7
; GFX12-GI-NEXT: s_wait_alu depctr_sa_sdst(0)
-; GFX12-GI-NEXT: v_dual_mov_b32 v2, s1 :: v_dual_mov_b32 v3, s2
+; GFX12-GI-NEXT: v_dual_mov_b32 v2, s2 :: v_dual_mov_b32 v3, s3
; GFX12-GI-NEXT: s_setpc_b64 s[30:31]
%x = call <8 x i16> @llvm.fptosi.sat.v8f16.v8i16(<8 x half> %f)
ret <8 x i16> %x
@@ -6689,6 +6682,185 @@ define <8 x i64> @test_s_signed_v8f16_v8i64(<8 x half> inreg %f) {
ret <8 x i64> %x
}
+;
+; Float to signed 16-bit
+;
+
+define <4 x i16> @test_signed_v4f32_v4i16(<4 x float> %f) {
+; GFX7-ISEL-LABEL: test_signed_v4f32_v4i16:
+; GFX7-ISEL: ; %bb.0:
+; GFX7-ISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7-ISEL-NEXT: v_cvt_i32_f32_e32 v1, v1
+; GFX7-ISEL-NEXT: v_cvt_i32_f32_e32 v0, v0
+; GFX7-ISEL-NEXT: v_cvt_i32_f32_e32 v3, v3
+; GFX7-ISEL-NEXT: v_cvt_i32_f32_e32 v2, v2
+; GFX7-ISEL-NEXT: s_movk_i32 s4, 0x8000
+; GFX7-ISEL-NEXT: v_mov_b32_e32 v4, 0x7fff
+; GFX7-ISEL-NEXT: v_med3_i32 v1, v1, s4, v4
+; GFX7-ISEL-NEXT: v_med3_i32 v0, v0, s4, v4
+; GFX7-ISEL-NEXT: v_med3_i32 v3, v3, s4, v4
+; GFX7-ISEL-NEXT: v_med3_i32 v2, v2, s4, v4
+; GFX7-ISEL-NEXT: v_lshlrev_b32_e32 v1, 16, v1
+; GFX7-ISEL-NEXT: v_and_b32_e32 v0, 0xffff, v0
+; GFX7-ISEL-NEXT: v_lshlrev_b32_e32 v3, 16, v3
+; GFX7-ISEL-NEXT: v_or_b32_e32 v0, v0, v1
+; GFX7-ISEL-NEXT: v_and_b32_e32 v1, 0xffff, v2
+; GFX7-ISEL-NEXT: v_or_b32_e32 v1, v1, v3
+; GFX7-ISEL-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX7-GI-LABEL: test_signed_v4f32_v4i16:
+; GFX7-GI: ; %bb.0:
+; GFX7-GI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7-GI-NEXT: v_cvt_i32_f32_e32 v1, v1
+; GFX7-GI-NEXT: v_cvt_i32_f32_e32 v0, v0
+; GFX7-GI-NEXT: v_cvt_i32_f32_e32 v2, v2
+; GFX7-GI-NEXT: v_cvt_i32_f32_e32 v3, v3
+; GFX7-GI-NEXT: s_movk_i32 s4, 0x7fff
+; GFX7-GI-NEXT: v_mov_b32_e32 v4, 0x8000
+; GFX7-GI-NEXT: v_med3_i32 v1, v1, v4, s4
+; GFX7-GI-NEXT: v_med3_i32 v0, v0, v4, s4
+; GFX7-GI-NEXT: v_and_b32_e32 v1, 0xffff, v1
+; GFX7-GI-NEXT: v_med3_i32 v2, v2, v4, s4
+; GFX7-GI-NEXT: v_med3_i32 v3, v3, v4, s4
+; GFX7-GI-NEXT: v_and_b32_e32 v0, 0xffff, v0
+; GFX7-GI-NEXT: v_lshlrev_b32_e32 v1, 16, v1
+; GFX7-GI-NEXT: v_or_b32_e32 v0, v0, v1
+; GFX7-GI-NEXT: v_and_b32_e32 v1, 0xffff, v2
+; GFX7-GI-NEXT: v_and_b32_e32 v2, 0xffff, v3
+; GFX7-GI-NEXT: v_lshlrev_b32_e32 v2, 16, v2
+; GFX7-GI-NEXT: v_or_b32_e32 v1, v1, v2
+; GFX7-GI-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: test_signed_v4f32_v4i16:
+; GFX9: ; %bb.0:
+; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT: v_cvt_i32_f32_e32 v2, v2
+; GFX9-NEXT: v_cvt_i32_f32_e32 v3, v3
+; GFX9-NEXT: v_cvt_i32_f32_e32 v0, v0
+; GFX9-NEXT: v_cvt_i32_f32_e32 v1, v1
+; GFX9-NEXT: s_movk_i32 s4, 0x7fff
+; GFX9-NEXT: v_mov_b32_e32 v4, 0x8000
+; GFX9-NEXT: v_med3_i32 v2, v2, v4, s4
+; GFX9-NEXT: v_med3_i32 v3, v3, v4, s4
+; GFX9-NEXT: v_med3_i32 v0, v0, v4, s4
+; GFX9-NEXT: v_med3_i32 v1, v1, v4, s4
+; GFX9-NEXT: s_mov_b32 s4, 0x5040100
+; GFX9-NEXT: v_perm_b32 v0, v1, v0, s4
+; GFX9-NEXT: v_perm_b32 v1, v3, v2, s4
+; GFX9-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: test_signed_v4f32_v4i16:
+; GFX11: ; %bb.0:
+; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT: v_cvt_pk_i16_f32 v0, v0, v1
+; GFX11-NEXT: v_cvt_pk_i16_f32 v1, v2, v3
+; GFX11-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX12-LABEL: test_signed_v4f32_v4i16:
+; GFX12: ; %bb.0:
+; GFX12-NEXT: s_wait_loadcnt_dscnt 0x0
+; GFX12-NEXT: s_wait_expcnt 0x0
+; GFX12-NEXT: s_wait_samplecnt 0x0
+; GFX12-NEXT: s_wait_bvhcnt 0x0
+; GFX12-NEXT: s_wait_kmcnt 0x0
+; GFX12-NEXT: v_cvt_pk_i16_f32 v0, v0, v1
+; GFX12-NEXT: v_cvt_pk_i16_f32 v1, v2, v3
+; GFX12-NEXT: s_setpc_b64 s[30:31]
+ %x = call <4 x i16> @llvm.fptosi.sat.v4f32.v4i16(<4 x float> %f)
+ ret <4 x i16> %x
+}
+
+define <4 x i16> @test_s_signed_v4f32_v4i16(<4 x float> inreg %f) {
+; GFX7-ISEL-LABEL: test_s_signed_v4f32_v4i16:
+; GFX7-ISEL: ; %bb.0:
+; GFX7-ISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7-ISEL-NEXT: v_cvt_i32_f32_e32 v0, s19
+; GFX7-ISEL-NEXT: s_movk_i32 s4, 0x8000
+; GFX7-ISEL-NEXT: v_mov_b32_e32 v1, 0x7fff
+; GFX7-ISEL-NEXT: v_cvt_i32_f32_e32 v2, s18
+; GFX7-ISEL-NEXT: v_med3_i32 v0, v0, s4, v1
+; GFX7-ISEL-NEXT: v_cvt_i32_f32_e32 v3, s17
+; GFX7-ISEL-NEXT: v_lshlrev_b32_e32 v4, 16, v0
+; GFX7-ISEL-NEXT: v_cvt_i32_f32_e32 v0, s16
+; GFX7-ISEL-NEXT: v_med3_i32 v2, v2, s4, v1
+; GFX7-ISEL-NEXT: v_med3_i32 v3, v3, s4, v1
+; GFX7-ISEL-NEXT: v_lshlrev_b32_e32 v3, 16, v3
+; GFX7-ISEL-NEXT: v_med3_i32 v0, v0, s4, v1
+; GFX7-ISEL-NEXT: v_and_b32_e32 v0, 0xffff, v0
+; GFX7-ISEL-NEXT: v_and_b32_e32 v1, 0xffff, v2
+; GFX7-ISEL-NEXT: v_or_b32_e32 v0, v0, v3
+; GFX7-ISEL-NEXT: v_or_b32_e32 v1, v1, v4
+; GFX7-ISEL-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX7-GI-LABEL: test_s_signed_v4f32_v4i16:
+; GFX7-GI: ; %bb.0:
+; GFX7-GI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7-GI-NEXT: v_cvt_i32_f32_e32 v0, s16
+; GFX7-GI-NEXT: s_movk_i32 s4, 0x7fff
+; GFX7-GI-NEXT: v_mov_b32_e32 v1, 0x8000
+; GFX7-GI-NEXT: v_cvt_i32_f32_e32 v2, s17
+; GFX7-GI-NEXT: v_med3_i32 v0, v0, v1, s4
+; GFX7-GI-NEXT: v_readfirstlane_b32 s5, v0
+; GFX7-GI-NEXT: v_cvt_i32_f32_e32 v0, s18
+; GFX7-GI-NEXT: v_cvt_i32_f32_e32 v3, s19
+; GFX7-GI-NEXT: v_med3_i32 v2, v2, v1, s4
+; GFX7-GI-NEXT: v_readfirstlane_b32 s6, v2
+; GFX7-GI-NEXT: v_med3_i32 v0, v0, v1, s4
+; GFX7-GI-NEXT: v_readfirstlane_b32 s7, v0
+; GFX7-GI-NEXT: v_med3_i32 v0, v3, v1, s4
+; GFX7-GI-NEXT: v_readfirstlane_b32 s4, v0
+; GFX7-GI-NEXT: s_and_b32 s6, 0xffff, s6
+; GFX7-GI-NEXT: s_and_b32 s5, 0xffff, s5
+; GFX7-GI-NEXT: s_lshl_b32 s6, s6, 16
+; GFX7-GI-NEXT: s_and_b32 s4, 0xffff, s4
+; GFX7-GI-NEXT: s_or_b32 s5, s5, s6
+; GFX7-GI-NEXT: s_and_b32 s6, 0xffff, s7
+; GFX7-GI-NEXT: s_lshl_b32 s4, s4, 16
+; GFX7-GI-NEXT: s_or_b32 s4, s6, s4
+; GFX7-GI-NEXT: v_mov_b32_e32 v0, s5
+; GFX7-GI-NEXT: v_mov_b32_e32 v1, s4
+; GFX7-GI-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: test_s_signed_v4f32_v4i16:
+; GFX9: ; %bb.0:
+; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT: v_cvt_i32_f32_e32 v0, s19
+; GFX9-NEXT: v_cvt_i32_f32_e32 v2, s18
+; GFX9-NEXT: v_cvt_i32_f32_e32 v3, s17
+; GFX9-NEXT: v_cvt_i32_f32_e32 v4, s16
+; GFX9-NEXT: s_movk_i32 s4, 0x7fff
+; GFX9-NEXT: v_mov_b32_e32 v1, 0x8000
+; GFX9-NEXT: v_med3_i32 v5, v0, v1, s4
+; GFX9-NEXT: v_med3_i32 v2, v2, v1, s4
+; GFX9-NEXT: v_med3_i32 v0, v3, v1, s4
+; GFX9-NEXT: v_med3_i32 v1, v4, v1, s4
+; GFX9-NEXT: v_and_b32_e32 v1, 0xffff, v1
+; GFX9-NEXT: v_lshl_or_b32 v0, v0, 16, v1
+; GFX9-NEXT: v_and_b32_e32 v1, 0xffff, v2
+; GFX9-NEXT: v_lshl_or_b32 v1, v5, 16, v1
+; GFX9-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: test_s_signed_v4f32_v4i16:
+; GFX11: ; %bb.0:
+; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT: v_cvt_pk_i16_f32 v0, s0, s1
+; GFX11-NEXT: v_cvt_pk_i16_f32 v1, s2, s3
+; GFX11-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX12-LABEL: test_s_signed_v4f32_v4i16:
+; GFX12: ; %bb.0:
+; GFX12-NEXT: s_wait_loadcnt_dscnt 0x0
+; GFX12-NEXT: s_wait_expcnt 0x0
+; GFX12-NEXT: s_wait_samplecnt 0x0
+; GFX12-NEXT: s_wait_bvhcnt 0x0
+; GFX12-NEXT: s_wait_kmcnt 0x0
+; GFX12-NEXT: v_cvt_pk_i16_f32 v0, s0, s1
+; GFX12-NEXT: v_cvt_pk_i16_f32 v1, s2, s3
+; GFX12-NEXT: s_setpc_b64 s[30:31]
+ %x = call <4 x i16> @llvm.fptosi.sat.v4f32.v4i16(<4 x float> %f)
+ ret <4 x i16> %x
+}
+
;
; Float to signed 8-bit
;
diff --git a/llvm/test/CodeGen/AMDGPU/fptoui-sat-scalar.ll b/llvm/test/CodeGen/AMDGPU/fptoui-sat-scalar.ll
index 2b02c54f780ac..6a4c3d2d4cc51 100644
--- a/llvm/test/CodeGen/AMDGPU/fptoui-sat-scalar.ll
+++ b/llvm/test/CodeGen/AMDGPU/fptoui-sat-scalar.ll
@@ -379,21 +379,12 @@ define i8 @test_s_unsigned_i8_f32(float inreg %f) nounwind {
}
define i16 @test_s_unsigned_i16_f32(float inreg %f) nounwind {
-; GFX7-ISEL-LABEL: test_s_unsigned_i16_f32:
-; GFX7-ISEL: ; %bb.0:
-; GFX7-ISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX7-ISEL-NEXT: v_cvt_u32_f32_e32 v0, s16
-; GFX7-ISEL-NEXT: v_min_u32_e32 v0, 0xffff, v0
-; GFX7-ISEL-NEXT: s_setpc_b64 s[30:31]
-;
-; GFX7-GI-LABEL: test_s_unsigned_i16_f32:
-; GFX7-GI: ; %bb.0:
-; GFX7-GI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX7-GI-NEXT: v_cvt_u32_f32_e32 v0, s16
-; GFX7-GI-NEXT: v_readfirstlane_b32 s4, v0
-; GFX7-GI-NEXT: s_min_u32 s4, s4, 0xffff
-; GFX7-GI-NEXT: v_mov_b32_e32 v0, s4
-; GFX7-GI-NEXT: s_setpc_b64 s[30:31]
+; GFX7-LABEL: test_s_unsigned_i16_f32:
+; GFX7: ; %bb.0:
+; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7-NEXT: v_cvt_u32_f32_e32 v0, s16
+; GFX7-NEXT: v_min_u32_e32 v0, 0xffff, v0
+; GFX7-NEXT: s_setpc_b64 s[30:31]
;
; GFX9-LABEL: test_s_unsigned_i16_f32:
; GFX9: ; %bb.0:
@@ -1755,23 +1746,13 @@ define i8 @test_s_unsigned_i8_f16(half inreg %f) nounwind {
}
define i16 @test_s_unsigned_i16_f16(half inreg %f) nounwind {
-; GFX7-ISEL-LABEL: test_s_unsigned_i16_f16:
-; GFX7-ISEL: ; %bb.0:
-; GFX7-ISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX7-ISEL-NEXT: v_cvt_f32_f16_e32 v0, s16
-; GFX7-ISEL-NEXT: v_cvt_u32_f32_e32 v0, v0
-; GFX7-ISEL-NEXT: v_min_u32_e32 v0, 0xffff, v0
-; GFX7-ISEL-NEXT: s_setpc_b64 s[30:31]
-;
-; GFX7-GI-LABEL: test_s_unsigned_i16_f16:
-; GFX7-GI: ; %bb.0:
-; GFX7-GI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v0, s16
-; GFX7-GI-NEXT: v_cvt_u32_f32_e32 v0, v0
-; GFX7-GI-NEXT: v_readfirstlane_b32 s4, v0
-; GFX7-GI-NEXT: s_min_u32 s4, s4, 0xffff
-; GFX7-GI-NEXT: v_mov_b32_e32 v0, s4
-; GFX7-GI-NEXT: s_setpc_b64 s[30:31]
+; GFX7-LABEL: test_s_unsigned_i16_f16:
+; GFX7: ; %bb.0:
+; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7-NEXT: v_cvt_f32_f16_e32 v0, s16
+; GFX7-NEXT: v_cvt_u32_f32_e32 v0, v0
+; GFX7-NEXT: v_min_u32_e32 v0, 0xffff, v0
+; GFX7-NEXT: s_setpc_b64 s[30:31]
;
; GFX9-LABEL: test_s_unsigned_i16_f16:
; GFX9: ; %bb.0:
diff --git a/llvm/test/CodeGen/AMDGPU/fptoui-sat-vector.ll b/llvm/test/CodeGen/AMDGPU/fptoui-sat-vector.ll
index 14094c50e2290..94f4da379a038 100644
--- a/llvm/test/CodeGen/AMDGPU/fptoui-sat-vector.ll
+++ b/llvm/test/CodeGen/AMDGPU/fptoui-sat-vector.ll
@@ -2647,8 +2647,8 @@ define <4 x i16> @test_unsigned_v4f16_v4i16(<4 x half> %f) {
; GFX7-GI: ; %bb.0:
; GFX7-GI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX7-GI-NEXT: v_lshrrev_b32_e32 v2, 16, v0
-; GFX7-GI-NEXT: v_lshrrev_b32_e32 v3, 16, v1
; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v2, v2
+; GFX7-GI-NEXT: v_lshrrev_b32_e32 v3, 16, v1
; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v0, v0
; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v3, v3
; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v1, v1
@@ -2658,11 +2658,15 @@ define <4 x i16> @test_unsigned_v4f16_v4i16(<4 x half> %f) {
; GFX7-GI-NEXT: v_cvt_u32_f32_e32 v1, v1
; GFX7-GI-NEXT: v_min_u32_e32 v2, 0xffff, v2
; GFX7-GI-NEXT: v_min_u32_e32 v0, 0xffff, v0
+; GFX7-GI-NEXT: v_and_b32_e32 v2, 0xffff, v2
; GFX7-GI-NEXT: v_min_u32_e32 v3, 0xffff, v3
+; GFX7-GI-NEXT: v_and_b32_e32 v0, 0xffff, v0
; GFX7-GI-NEXT: v_lshlrev_b32_e32 v2, 16, v2
; GFX7-GI-NEXT: v_min_u32_e32 v1, 0xffff, v1
; GFX7-GI-NEXT: v_or_b32_e32 v0, v0, v2
-; GFX7-GI-NEXT: v_lshlrev_b32_e32 v2, 16, v3
+; GFX7-GI-NEXT: v_and_b32_e32 v2, 0xffff, v3
+; GFX7-GI-NEXT: v_and_b32_e32 v1, 0xffff, v1
+; GFX7-GI-NEXT: v_lshlrev_b32_e32 v2, 16, v2
; GFX7-GI-NEXT: v_or_b32_e32 v1, v1, v2
; GFX7-GI-NEXT: s_setpc_b64 s[30:31]
;
@@ -3485,22 +3489,26 @@ define <4 x i16> @test_s_unsigned_v4f16_v4i16(<4 x half> inreg %f) {
; GFX7-GI-NEXT: s_lshr_b32 s4, s17, 16
; GFX7-GI-NEXT: v_cvt_u32_f32_e32 v0, v0
; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v2, s17
+; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v3, s4
; GFX7-GI-NEXT: v_cvt_u32_f32_e32 v1, v1
-; GFX7-GI-NEXT: v_readfirstlane_b32 s5, v0
-; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v0, s4
-; GFX7-GI-NEXT: v_cvt_u32_f32_e32 v2, v2
-; GFX7-GI-NEXT: s_min_u32 s4, s5, 0xffff
+; GFX7-GI-NEXT: v_min_u32_e32 v0, 0xffff, v0
+; GFX7-GI-NEXT: v_readfirstlane_b32 s4, v0
+; GFX7-GI-NEXT: v_cvt_u32_f32_e32 v0, v2
+; GFX7-GI-NEXT: v_cvt_u32_f32_e32 v2, v3
+; GFX7-GI-NEXT: v_min_u32_e32 v1, 0xffff, v1
; GFX7-GI-NEXT: v_readfirstlane_b32 s5, v1
-; GFX7-GI-NEXT: v_cvt_u32_f32_e32 v0, v0
-; GFX7-GI-NEXT: s_min_u32 s5, s5, 0xffff
-; GFX7-GI-NEXT: v_readfirstlane_b32 s6, v2
-; GFX7-GI-NEXT: s_lshl_b32 s5, s5, 16
+; GFX7-GI-NEXT: v_min_u32_e32 v0, 0xffff, v0
+; GFX7-GI-NEXT: v_readfirstlane_b32 s6, v0
+; GFX7-GI-NEXT: v_min_u32_e32 v0, 0xffff, v2
+; GFX7-GI-NEXT: s_and_b32 s5, 0xffff, s5
; GFX7-GI-NEXT: v_readfirstlane_b32 s7, v0
-; GFX7-GI-NEXT: s_min_u32 s7, s7, 0xffff
-; GFX7-GI-NEXT: s_min_u32 s6, s6, 0xffff
+; GFX7-GI-NEXT: s_and_b32 s4, 0xffff, s4
+; GFX7-GI-NEXT: s_lshl_b32 s5, s5, 16
; GFX7-GI-NEXT: s_or_b32 s4, s4, s5
-; GFX7-GI-NEXT: s_lshl_b32 s5, s7, 16
-; GFX7-GI-NEXT: s_or_b32 s5, s6, s5
+; GFX7-GI-NEXT: s_and_b32 s5, 0xffff, s6
+; GFX7-GI-NEXT: s_and_b32 s6, 0xffff, s7
+; GFX7-GI-NEXT: s_lshl_b32 s6, s6, 16
+; GFX7-GI-NEXT: s_or_b32 s5, s5, s6
; GFX7-GI-NEXT: v_mov_b32_e32 v0, s4
; GFX7-GI-NEXT: v_mov_b32_e32 v1, s5
; GFX7-GI-NEXT: s_setpc_b64 s[30:31]
@@ -3590,12 +3598,12 @@ define <4 x i16> @test_s_unsigned_v4f16_v4i16(<4 x half> inreg %f) {
; GFX12-GI-NEXT: s_wait_bvhcnt 0x0
; GFX12-GI-NEXT: s_wait_kmcnt 0x0
; GFX12-GI-NEXT: s_lshr_b32 s2, s0, 16
-; GFX12-GI-NEXT: s_lshr_b32 s3, s1, 16
; GFX12-GI-NEXT: v_cvt_u16_f16_e32 v0.l, s0
+; GFX12-GI-NEXT: s_lshr_b32 s0, s1, 16
; GFX12-GI-NEXT: s_wait_alu depctr_sa_sdst(0)
; GFX12-GI-NEXT: v_cvt_u16_f16_e32 v1.l, s2
; GFX12-GI-NEXT: v_cvt_u16_f16_e32 v2.l, s1
-; GFX12-GI-NEXT: v_cvt_u16_f16_e32 v3.l, s3
+; GFX12-GI-NEXT: v_cvt_u16_f16_e32 v3.l, s0
; GFX12-GI-NEXT: v_readfirstlane_b32 s0, v0
; GFX12-GI-NEXT: v_readfirstlane_b32 s1, v1
; GFX12-GI-NEXT: v_readfirstlane_b32 s2, v2
@@ -4341,40 +4349,48 @@ define <8 x i16> @test_unsigned_v8f16_v8i16(<8 x half> %f) {
; GFX7-GI: ; %bb.0:
; GFX7-GI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX7-GI-NEXT: v_lshrrev_b32_e32 v4, 16, v0
-; GFX7-GI-NEXT: v_lshrrev_b32_e32 v5, 16, v1
; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v4, v4
-; GFX7-GI-NEXT: v_lshrrev_b32_e32 v6, 16, v2
+; GFX7-GI-NEXT: v_lshrrev_b32_e32 v5, 16, v1
; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v0, v0
; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v5, v5
-; GFX7-GI-NEXT: v_lshrrev_b32_e32 v7, 16, v3
+; GFX7-GI-NEXT: v_lshrrev_b32_e32 v6, 16, v2
; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v1, v1
-; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v6, v6
-; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v2, v2
-; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v7, v7
; GFX7-GI-NEXT: v_cvt_u32_f32_e32 v4, v4
-; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v3, v3
+; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v6, v6
+; GFX7-GI-NEXT: v_lshrrev_b32_e32 v7, 16, v3
; GFX7-GI-NEXT: v_cvt_u32_f32_e32 v0, v0
+; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v2, v2
; GFX7-GI-NEXT: v_cvt_u32_f32_e32 v5, v5
+; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v7, v7
; GFX7-GI-NEXT: v_cvt_u32_f32_e32 v1, v1
-; GFX7-GI-NEXT: v_cvt_u32_f32_e32 v6, v6
-; GFX7-GI-NEXT: v_cvt_u32_f32_e32 v2, v2
-; GFX7-GI-NEXT: v_cvt_u32_f32_e32 v7, v7
+; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v3, v3
; GFX7-GI-NEXT: v_min_u32_e32 v4, 0xffff, v4
-; GFX7-GI-NEXT: v_cvt_u32_f32_e32 v3, v3
+; GFX7-GI-NEXT: v_cvt_u32_f32_e32 v6, v6
; GFX7-GI-NEXT: v_min_u32_e32 v0, 0xffff, v0
+; GFX7-GI-NEXT: v_cvt_u32_f32_e32 v2, v2
+; GFX7-GI-NEXT: v_and_b32_e32 v4, 0xffff, v4
; GFX7-GI-NEXT: v_min_u32_e32 v5, 0xffff, v5
+; GFX7-GI-NEXT: v_cvt_u32_f32_e32 v7, v7
+; GFX7-GI-NEXT: v_and_b32_e32 v0, 0xffff, v0
; GFX7-GI-NEXT: v_lshlrev_b32_e32 v4, 16, v4
; GFX7-GI-NEXT: v_min_u32_e32 v1, 0xffff, v1
-; GFX7-GI-NEXT: v_min_u32_e32 v6, 0xffff, v6
+; GFX7-GI-NEXT: v_cvt_u32_f32_e32 v3, v3
; GFX7-GI-NEXT: v_or_b32_e32 v0, v0, v4
-; GFX7-GI-NEXT: v_lshlrev_b32_e32 v4, 16, v5
+; GFX7-GI-NEXT: v_and_b32_e32 v4, 0xffff, v5
+; GFX7-GI-NEXT: v_min_u32_e32 v6, 0xffff, v6
+; GFX7-GI-NEXT: v_and_b32_e32 v1, 0xffff, v1
+; GFX7-GI-NEXT: v_lshlrev_b32_e32 v4, 16, v4
; GFX7-GI-NEXT: v_min_u32_e32 v2, 0xffff, v2
-; GFX7-GI-NEXT: v_min_u32_e32 v7, 0xffff, v7
; GFX7-GI-NEXT: v_or_b32_e32 v1, v1, v4
-; GFX7-GI-NEXT: v_lshlrev_b32_e32 v4, 16, v6
+; GFX7-GI-NEXT: v_and_b32_e32 v4, 0xffff, v6
+; GFX7-GI-NEXT: v_min_u32_e32 v7, 0xffff, v7
+; GFX7-GI-NEXT: v_and_b32_e32 v2, 0xffff, v2
+; GFX7-GI-NEXT: v_lshlrev_b32_e32 v4, 16, v4
; GFX7-GI-NEXT: v_min_u32_e32 v3, 0xffff, v3
; GFX7-GI-NEXT: v_or_b32_e32 v2, v2, v4
-; GFX7-GI-NEXT: v_lshlrev_b32_e32 v4, 16, v7
+; GFX7-GI-NEXT: v_and_b32_e32 v4, 0xffff, v7
+; GFX7-GI-NEXT: v_and_b32_e32 v3, 0xffff, v3
+; GFX7-GI-NEXT: v_lshlrev_b32_e32 v4, 16, v4
; GFX7-GI-NEXT: v_or_b32_e32 v3, v3, v4
; GFX7-GI-NEXT: s_setpc_b64 s[30:31]
;
@@ -5754,50 +5770,58 @@ define <8 x i16> @test_s_unsigned_v8f16_v8i16(<8 x half> inreg %f) {
; GFX7-GI-LABEL: test_s_unsigned_v8f16_v8i16:
; GFX7-GI: ; %bb.0:
; GFX7-GI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v0, s16
; GFX7-GI-NEXT: s_lshr_b32 s4, s16, 16
; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v1, s4
-; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v0, s16
+; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v2, s17
+; GFX7-GI-NEXT: v_cvt_u32_f32_e32 v0, v0
; GFX7-GI-NEXT: s_lshr_b32 s5, s17, 16
-; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v2, s18
; GFX7-GI-NEXT: v_cvt_u32_f32_e32 v1, v1
-; GFX7-GI-NEXT: v_cvt_u32_f32_e32 v0, v0
-; GFX7-GI-NEXT: s_lshr_b32 s4, s18, 16
-; GFX7-GI-NEXT: s_lshr_b32 s6, s19, 16
-; GFX7-GI-NEXT: v_readfirstlane_b32 s8, v1
-; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v1, s5
+; GFX7-GI-NEXT: v_cvt_u32_f32_e32 v2, v2
+; GFX7-GI-NEXT: v_min_u32_e32 v0, 0xffff, v0
; GFX7-GI-NEXT: v_readfirstlane_b32 s7, v0
-; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v0, s17
-; GFX7-GI-NEXT: s_min_u32 s5, s8, 0xffff
+; GFX7-GI-NEXT: v_min_u32_e32 v0, 0xffff, v1
+; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v1, s5
+; GFX7-GI-NEXT: v_readfirstlane_b32 s5, v0
+; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v0, s18
+; GFX7-GI-NEXT: s_lshr_b32 s4, s18, 16
; GFX7-GI-NEXT: v_cvt_u32_f32_e32 v1, v1
-; GFX7-GI-NEXT: s_min_u32 s7, s7, 0xffff
+; GFX7-GI-NEXT: v_min_u32_e32 v2, 0xffff, v2
+; GFX7-GI-NEXT: v_readfirstlane_b32 s8, v2
+; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v2, s4
; GFX7-GI-NEXT: v_cvt_u32_f32_e32 v0, v0
+; GFX7-GI-NEXT: v_min_u32_e32 v1, 0xffff, v1
+; GFX7-GI-NEXT: s_lshr_b32 s6, s19, 16
+; GFX7-GI-NEXT: v_readfirstlane_b32 s4, v1
+; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v1, s19
+; GFX7-GI-NEXT: v_cvt_u32_f32_e32 v2, v2
+; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v3, s6
+; GFX7-GI-NEXT: v_min_u32_e32 v0, 0xffff, v0
+; GFX7-GI-NEXT: v_readfirstlane_b32 s6, v0
+; GFX7-GI-NEXT: v_cvt_u32_f32_e32 v0, v1
+; GFX7-GI-NEXT: v_min_u32_e32 v1, 0xffff, v2
+; GFX7-GI-NEXT: v_cvt_u32_f32_e32 v2, v3
+; GFX7-GI-NEXT: s_and_b32 s5, 0xffff, s5
+; GFX7-GI-NEXT: v_min_u32_e32 v0, 0xffff, v0
+; GFX7-GI-NEXT: s_and_b32 s7, 0xffff, s7
; GFX7-GI-NEXT: s_lshl_b32 s5, s5, 16
+; GFX7-GI-NEXT: s_and_b32 s4, 0xffff, s4
; GFX7-GI-NEXT: v_readfirstlane_b32 s9, v1
-; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v1, s4
-; GFX7-GI-NEXT: v_readfirstlane_b32 s8, v0
-; GFX7-GI-NEXT: v_cvt_u32_f32_e32 v0, v2
-; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v2, s6
-; GFX7-GI-NEXT: v_cvt_u32_f32_e32 v1, v1
-; GFX7-GI-NEXT: s_min_u32 s4, s9, 0xffff
-; GFX7-GI-NEXT: v_readfirstlane_b32 s9, v0
-; GFX7-GI-NEXT: v_cvt_f32_f16_e32 v0, s19
-; GFX7-GI-NEXT: s_min_u32 s6, s9, 0xffff
-; GFX7-GI-NEXT: v_readfirstlane_b32 s9, v1
-; GFX7-GI-NEXT: v_cvt_u32_f32_e32 v1, v2
-; GFX7-GI-NEXT: v_cvt_u32_f32_e32 v0, v0
-; GFX7-GI-NEXT: s_min_u32 s9, s9, 0xffff
-; GFX7-GI-NEXT: s_or_b32 s5, s7, s5
-; GFX7-GI-NEXT: v_readfirstlane_b32 s11, v1
; GFX7-GI-NEXT: v_readfirstlane_b32 s10, v0
-; GFX7-GI-NEXT: s_min_u32 s11, s11, 0xffff
-; GFX7-GI-NEXT: s_lshl_b32 s7, s9, 16
-; GFX7-GI-NEXT: s_min_u32 s8, s8, 0xffff
-; GFX7-GI-NEXT: s_min_u32 s10, s10, 0xffff
+; GFX7-GI-NEXT: v_min_u32_e32 v0, 0xffff, v2
+; GFX7-GI-NEXT: s_or_b32 s5, s7, s5
+; GFX7-GI-NEXT: s_and_b32 s7, 0xffff, s8
; GFX7-GI-NEXT: s_lshl_b32 s4, s4, 16
+; GFX7-GI-NEXT: v_readfirstlane_b32 s11, v0
+; GFX7-GI-NEXT: s_or_b32 s4, s7, s4
+; GFX7-GI-NEXT: s_and_b32 s7, 0xffff, s9
+; GFX7-GI-NEXT: s_and_b32 s6, 0xffff, s6
+; GFX7-GI-NEXT: s_lshl_b32 s7, s7, 16
+; GFX7-GI-NEXT: s_and_b32 s8, 0xffff, s11
; GFX7-GI-NEXT: s_or_b32 s6, s6, s7
-; GFX7-GI-NEXT: s_lshl_b32 s7, s11, 16
-; GFX7-GI-NEXT: s_or_b32 s4, s8, s4
-; GFX7-GI-NEXT: s_or_b32 s7, s10, s7
+; GFX7-GI-NEXT: s_and_b32 s7, 0xffff, s10
+; GFX7-GI-NEXT: s_lshl_b32 s8, s8, 16
+; GFX7-GI-NEXT: s_or_b32 s7, s7, s8
; GFX7-GI-NEXT: v_mov_b32_e32 v0, s5
; GFX7-GI-NEXT: v_mov_b32_e32 v1, s4
; GFX7-GI-NEXT: v_mov_b32_e32 v2, s6
@@ -5933,36 +5957,37 @@ define <8 x i16> @test_s_unsigned_v8f16_v8i16(<8 x half> inreg %f) {
; GFX12-GI-NEXT: s_wait_samplecnt 0x0
; GFX12-GI-NEXT: s_wait_bvhcnt 0x0
; GFX12-GI-NEXT: s_wait_kmcnt 0x0
-; GFX12-GI-NEXT: s_lshr_b32 s4, s0, 16
; GFX12-GI-NEXT: v_cvt_u16_f16_e32 v0.l, s0
+; GFX12-GI-NEXT: s_lshr_b32 s4, s0, 16
+; GFX12-GI-NEXT: v_cvt_u16_f16_e32 v2.l, s1
+; GFX12-GI-NEXT: s_lshr_b32 s1, s1, 16
; GFX12-GI-NEXT: s_wait_alu depctr_sa_sdst(0)
; GFX12-GI-NEXT: v_cvt_u16_f16_e32 v1.l, s4
+; GFX12-GI-NEXT: v_readfirstlane_b32 s0, v0
+; GFX12-GI-NEXT: v_cvt_u16_f16_e32 v0.l, s1
+; GFX12-GI-NEXT: s_lshr_b32 s1, s2, 16
+; GFX12-GI-NEXT: v_readfirstlane_b32 s5, v2
+; GFX12-GI-NEXT: s_wait_alu depctr_sa_sdst(0)
; GFX12-GI-NEXT: v_cvt_u16_f16_e32 v2.l, s1
-; GFX12-GI-NEXT: s_lshr_b32 s5, s1, 16
-; GFX12-GI-NEXT: s_lshr_b32 s0, s2, 16
; GFX12-GI-NEXT: s_lshr_b32 s1, s3, 16
-; GFX12-GI-NEXT: v_readfirstlane_b32 s4, v0
-; GFX12-GI-NEXT: v_readfirstlane_b32 s6, v1
-; GFX12-GI-NEXT: v_readfirstlane_b32 s7, v2
-; GFX12-GI-NEXT: s_wait_alu depctr_sa_sdst(0)
-; GFX12-GI-NEXT: v_cvt_u16_f16_e32 v0.l, s5
+; GFX12-GI-NEXT: v_readfirstlane_b32 s4, v1
; GFX12-GI-NEXT: v_cvt_u16_f16_e32 v1.l, s2
-; GFX12-GI-NEXT: v_cvt_u16_f16_e32 v2.l, s0
; GFX12-GI-NEXT: v_cvt_u16_f16_e32 v3.l, s3
+; GFX12-GI-NEXT: s_wait_alu depctr_sa_sdst(0)
; GFX12-GI-NEXT: v_cvt_u16_f16_e32 v4.l, s1
-; GFX12-GI-NEXT: v_readfirstlane_b32 s0, v0
-; GFX12-GI-NEXT: v_readfirstlane_b32 s1, v1
-; GFX12-GI-NEXT: v_readfirstlane_b32 s2, v2
-; GFX12-GI-NEXT: v_readfirstlane_b32 s3, v3
-; GFX12-GI-NEXT: v_readfirstlane_b32 s5, v4
-; GFX12-GI-NEXT: s_pack_ll_b32_b16 s4, s4, s6
-; GFX12-GI-NEXT: s_pack_ll_b32_b16 s0, s7, s0
-; GFX12-GI-NEXT: s_pack_ll_b32_b16 s1, s1, s2
+; GFX12-GI-NEXT: v_readfirstlane_b32 s1, v0
+; GFX12-GI-NEXT: v_readfirstlane_b32 s3, v2
+; GFX12-GI-NEXT: v_readfirstlane_b32 s2, v1
+; GFX12-GI-NEXT: v_readfirstlane_b32 s6, v3
+; GFX12-GI-NEXT: v_readfirstlane_b32 s7, v4
+; GFX12-GI-NEXT: s_pack_ll_b32_b16 s0, s0, s4
+; GFX12-GI-NEXT: s_pack_ll_b32_b16 s1, s5, s1
+; GFX12-GI-NEXT: s_pack_ll_b32_b16 s2, s2, s3
; GFX12-GI-NEXT: s_wait_alu depctr_sa_sdst(0)
-; GFX12-GI-NEXT: v_dual_mov_b32 v0, s4 :: v_dual_mov_b32 v1, s0
-; GFX12-GI-NEXT: s_pack_ll_b32_b16 s2, s3, s5
+; GFX12-GI-NEXT: v_dual_mov_b32 v0, s0 :: v_dual_mov_b32 v1, s1
+; GFX12-GI-NEXT: s_pack_ll_b32_b16 s3, s6, s7
; GFX12-GI-NEXT: s_wait_alu depctr_sa_sdst(0)
-; GFX12-GI-NEXT: v_dual_mov_b32 v2, s1 :: v_dual_mov_b32 v3, s2
+; GFX12-GI-NEXT: v_dual_mov_b32 v2, s2 :: v_dual_mov_b32 v3, s3
; GFX12-GI-NEXT: s_setpc_b64 s[30:31]
%x = call <8 x i16> @llvm.fptoui.sat.v8f16.v8i16(<8 x half> %f)
ret <8 x i16> %x
@@ -6174,6 +6199,169 @@ define <8 x i64> @test_s_unsigned_v8f16_v8i64(<8 x half> inreg %f) {
ret <8 x i64> %x
}
+;
+; Float to unsigned 16-bit
+;
+
+define <4 x i16> @test_unsigned_v4f32_v4i16(<4 x float> %f) {
+; GFX7-ISEL-LABEL: test_unsigned_v4f32_v4i16:
+; GFX7-ISEL: ; %bb.0:
+; GFX7-ISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7-ISEL-NEXT: v_cvt_u32_f32_e32 v3, v3
+; GFX7-ISEL-NEXT: v_cvt_u32_f32_e32 v1, v1
+; GFX7-ISEL-NEXT: v_cvt_u32_f32_e32 v2, v2
+; GFX7-ISEL-NEXT: v_cvt_u32_f32_e32 v0, v0
+; GFX7-ISEL-NEXT: v_min_u32_e32 v3, 0xffff, v3
+; GFX7-ISEL-NEXT: v_min_u32_e32 v1, 0xffff, v1
+; GFX7-ISEL-NEXT: v_min_u32_e32 v2, 0xffff, v2
+; GFX7-ISEL-NEXT: v_lshlrev_b32_e32 v3, 16, v3
+; GFX7-ISEL-NEXT: v_min_u32_e32 v0, 0xffff, v0
+; GFX7-ISEL-NEXT: v_lshlrev_b32_e32 v1, 16, v1
+; GFX7-ISEL-NEXT: v_or_b32_e32 v0, v0, v1
+; GFX7-ISEL-NEXT: v_or_b32_e32 v1, v2, v3
+; GFX7-ISEL-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX7-GI-LABEL: test_unsigned_v4f32_v4i16:
+; GFX7-GI: ; %bb.0:
+; GFX7-GI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7-GI-NEXT: v_cvt_u32_f32_e32 v1, v1
+; GFX7-GI-NEXT: v_cvt_u32_f32_e32 v0, v0
+; GFX7-GI-NEXT: v_cvt_u32_f32_e32 v2, v2
+; GFX7-GI-NEXT: v_cvt_u32_f32_e32 v3, v3
+; GFX7-GI-NEXT: v_min_u32_e32 v1, 0xffff, v1
+; GFX7-GI-NEXT: v_min_u32_e32 v0, 0xffff, v0
+; GFX7-GI-NEXT: v_and_b32_e32 v1, 0xffff, v1
+; GFX7-GI-NEXT: v_min_u32_e32 v2, 0xffff, v2
+; GFX7-GI-NEXT: v_min_u32_e32 v3, 0xffff, v3
+; GFX7-GI-NEXT: v_and_b32_e32 v0, 0xffff, v0
+; GFX7-GI-NEXT: v_lshlrev_b32_e32 v1, 16, v1
+; GFX7-GI-NEXT: v_or_b32_e32 v0, v0, v1
+; GFX7-GI-NEXT: v_and_b32_e32 v1, 0xffff, v2
+; GFX7-GI-NEXT: v_and_b32_e32 v2, 0xffff, v3
+; GFX7-GI-NEXT: v_lshlrev_b32_e32 v2, 16, v2
+; GFX7-GI-NEXT: v_or_b32_e32 v1, v1, v2
+; GFX7-GI-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: test_unsigned_v4f32_v4i16:
+; GFX9: ; %bb.0:
+; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT: v_cvt_u32_f32_e32 v2, v2
+; GFX9-NEXT: v_cvt_u32_f32_e32 v3, v3
+; GFX9-NEXT: v_cvt_u32_f32_e32 v0, v0
+; GFX9-NEXT: v_cvt_u32_f32_e32 v1, v1
+; GFX9-NEXT: v_min_u32_e32 v2, 0xffff, v2
+; GFX9-NEXT: v_min_u32_e32 v3, 0xffff, v3
+; GFX9-NEXT: v_min_u32_e32 v0, 0xffff, v0
+; GFX9-NEXT: v_min_u32_e32 v1, 0xffff, v1
+; GFX9-NEXT: s_mov_b32 s4, 0x5040100
+; GFX9-NEXT: v_perm_b32 v0, v1, v0, s4
+; GFX9-NEXT: v_perm_b32 v1, v3, v2, s4
+; GFX9-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: test_unsigned_v4f32_v4i16:
+; GFX11: ; %bb.0:
+; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT: v_cvt_pk_u16_f32 v0, v0, v1
+; GFX11-NEXT: v_cvt_pk_u16_f32 v1, v2, v3
+; GFX11-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX12-LABEL: test_unsigned_v4f32_v4i16:
+; GFX12: ; %bb.0:
+; GFX12-NEXT: s_wait_loadcnt_dscnt 0x0
+; GFX12-NEXT: s_wait_expcnt 0x0
+; GFX12-NEXT: s_wait_samplecnt 0x0
+; GFX12-NEXT: s_wait_bvhcnt 0x0
+; GFX12-NEXT: s_wait_kmcnt 0x0
+; GFX12-NEXT: v_cvt_pk_u16_f32 v0, v0, v1
+; GFX12-NEXT: v_cvt_pk_u16_f32 v1, v2, v3
+; GFX12-NEXT: s_setpc_b64 s[30:31]
+ %x = call <4 x i16> @llvm.fptoui.sat.v4f32.v4i16(<4 x float> %f)
+ ret <4 x i16> %x
+}
+
+define <4 x i16> @test_s_unsigned_v4f32_v4i16(<4 x float> inreg %f) {
+; GFX7-ISEL-LABEL: test_s_unsigned_v4f32_v4i16:
+; GFX7-ISEL: ; %bb.0:
+; GFX7-ISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7-ISEL-NEXT: v_cvt_u32_f32_e32 v0, s18
+; GFX7-ISEL-NEXT: v_cvt_u32_f32_e32 v1, s19
+; GFX7-ISEL-NEXT: v_cvt_u32_f32_e32 v3, s17
+; GFX7-ISEL-NEXT: v_min_u32_e32 v2, 0xffff, v0
+; GFX7-ISEL-NEXT: v_cvt_u32_f32_e32 v0, s16
+; GFX7-ISEL-NEXT: v_min_u32_e32 v1, 0xffff, v1
+; GFX7-ISEL-NEXT: v_min_u32_e32 v3, 0xffff, v3
+; GFX7-ISEL-NEXT: v_lshlrev_b32_e32 v1, 16, v1
+; GFX7-ISEL-NEXT: v_min_u32_e32 v0, 0xffff, v0
+; GFX7-ISEL-NEXT: v_lshlrev_b32_e32 v3, 16, v3
+; GFX7-ISEL-NEXT: v_or_b32_e32 v0, v0, v3
+; GFX7-ISEL-NEXT: v_or_b32_e32 v1, v2, v1
+; GFX7-ISEL-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX7-GI-LABEL: test_s_unsigned_v4f32_v4i16:
+; GFX7-GI: ; %bb.0:
+; GFX7-GI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7-GI-NEXT: v_cvt_u32_f32_e32 v0, s16
+; GFX7-GI-NEXT: v_cvt_u32_f32_e32 v1, s17
+; GFX7-GI-NEXT: v_cvt_u32_f32_e32 v2, s19
+; GFX7-GI-NEXT: v_min_u32_e32 v0, 0xffff, v0
+; GFX7-GI-NEXT: v_readfirstlane_b32 s4, v0
+; GFX7-GI-NEXT: v_cvt_u32_f32_e32 v0, s18
+; GFX7-GI-NEXT: v_min_u32_e32 v1, 0xffff, v1
+; GFX7-GI-NEXT: v_readfirstlane_b32 s5, v1
+; GFX7-GI-NEXT: s_and_b32 s5, 0xffff, s5
+; GFX7-GI-NEXT: v_min_u32_e32 v0, 0xffff, v0
+; GFX7-GI-NEXT: v_readfirstlane_b32 s6, v0
+; GFX7-GI-NEXT: v_min_u32_e32 v0, 0xffff, v2
+; GFX7-GI-NEXT: v_readfirstlane_b32 s7, v0
+; GFX7-GI-NEXT: s_and_b32 s4, 0xffff, s4
+; GFX7-GI-NEXT: s_lshl_b32 s5, s5, 16
+; GFX7-GI-NEXT: s_or_b32 s4, s4, s5
+; GFX7-GI-NEXT: s_and_b32 s5, 0xffff, s6
+; GFX7-GI-NEXT: s_and_b32 s6, 0xffff, s7
+; GFX7-GI-NEXT: s_lshl_b32 s6, s6, 16
+; GFX7-GI-NEXT: s_or_b32 s5, s5, s6
+; GFX7-GI-NEXT: v_mov_b32_e32 v0, s4
+; GFX7-GI-NEXT: v_mov_b32_e32 v1, s5
+; GFX7-GI-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: test_s_unsigned_v4f32_v4i16:
+; GFX9: ; %bb.0:
+; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT: v_cvt_u32_f32_e32 v0, s19
+; GFX9-NEXT: v_cvt_u32_f32_e32 v1, s18
+; GFX9-NEXT: v_cvt_u32_f32_e32 v2, s17
+; GFX9-NEXT: v_cvt_u32_f32_e32 v3, s16
+; GFX9-NEXT: v_min_u32_e32 v4, 0xffff, v0
+; GFX9-NEXT: v_min_u32_e32 v1, 0xffff, v1
+; GFX9-NEXT: v_min_u32_e32 v0, 0xffff, v2
+; GFX9-NEXT: v_min_u32_e32 v2, 0xffff, v3
+; GFX9-NEXT: v_and_b32_e32 v2, 0xffff, v2
+; GFX9-NEXT: v_and_b32_e32 v1, 0xffff, v1
+; GFX9-NEXT: v_lshl_or_b32 v0, v0, 16, v2
+; GFX9-NEXT: v_lshl_or_b32 v1, v4, 16, v1
+; GFX9-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: test_s_unsigned_v4f32_v4i16:
+; GFX11: ; %bb.0:
+; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT: v_cvt_pk_u16_f32 v0, s0, s1
+; GFX11-NEXT: v_cvt_pk_u16_f32 v1, s2, s3
+; GFX11-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX12-LABEL: test_s_unsigned_v4f32_v4i16:
+; GFX12: ; %bb.0:
+; GFX12-NEXT: s_wait_loadcnt_dscnt 0x0
+; GFX12-NEXT: s_wait_expcnt 0x0
+; GFX12-NEXT: s_wait_samplecnt 0x0
+; GFX12-NEXT: s_wait_bvhcnt 0x0
+; GFX12-NEXT: s_wait_kmcnt 0x0
+; GFX12-NEXT: v_cvt_pk_u16_f32 v0, s0, s1
+; GFX12-NEXT: v_cvt_pk_u16_f32 v1, s2, s3
+; GFX12-NEXT: s_setpc_b64 s[30:31]
+ %x = call <4 x i16> @llvm.fptoui.sat.v4f32.v4i16(<4 x float> %f)
+ ret <4 x i16> %x
+}
+
;
; Float to unsigned 8-bit
;
>From 062b9c2dc75eeebedc073df3cd338b973a83b571 Mon Sep 17 00:00:00 2001
From: Igor Wodiany <igor.wodiany at amd.com>
Date: Fri, 12 Jun 2026 11:31:21 +0100
Subject: [PATCH 2/2] address comments
---
llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp | 5 +--
llvm/lib/Target/AMDGPU/VOP3PInstructions.td | 29 +++++++++------
llvm/test/CodeGen/AMDGPU/fptosi-sat-scalar.ll | 16 +++------
llvm/test/CodeGen/AMDGPU/fptoui-sat-scalar.ll | 35 +++++++++++--------
4 files changed, 44 insertions(+), 41 deletions(-)
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
index 9a64e1e6365ac..fe774bce512d5 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
@@ -3946,10 +3946,7 @@ SDValue AMDGPUTargetLowering::LowerFP_TO_INT_SAT(const SDValue Op,
(SrcVT == MVT::f32 || SrcVT == MVT::f64))
return Op;
- if (DstVT == MVT::i16 && SatWidth == DstWidth && SrcVT == MVT::f16)
- return Op;
-
- if (DstVT == MVT::i16 && SatWidth == 16 && SrcVT == MVT::f32)
+ if (DstVT == MVT::i16 && SatWidth == DstWidth && (SrcVT == MVT::f16 || SrcVT == MVT::f32))
return Op;
// Perform all saturation at selected width (i16 or i32) and truncate
diff --git a/llvm/lib/Target/AMDGPU/VOP3PInstructions.td b/llvm/lib/Target/AMDGPU/VOP3PInstructions.td
index 5718eb503d5c8..c6bb93889d8ab 100644
--- a/llvm/lib/Target/AMDGPU/VOP3PInstructions.td
+++ b/llvm/lib/Target/AMDGPU/VOP3PInstructions.td
@@ -3144,25 +3144,30 @@ defm V_DOT8_I32_I4 : VOP3P_Real_gfx10 <0x18>;
// GFX11+ Patterns
//===----------------------------------------------------------------------===//
+multiclass FPToIntSatI16Pat<dag lhs, dag rhs> {
+ let True16Predicate = UseRealTrue16Insts in
+ def : GCNPat<lhs, (EXTRACT_SUBREG rhs, lo16)>;
+ let True16Predicate = NotUseRealTrue16Insts in
+ def : GCNPat<lhs, rhs>;
+}
+
// Packed f32 -> i16 saturated conversion.
multiclass CvtPkF32ToI16Pat<SDPatternOperator dagOp, Instruction inst> {
+ // Needed for SDAG as it uses build_vector.
def : GCNPat<(v2i16 (build_vector
(i16 (dagOp (f32 (VOP3Mods f32:$src0, i32:$src0_modifiers)), i16)),
(i16 (dagOp (f32 (VOP3Mods f32:$src1, i32:$src1_modifiers)), i16)))),
(inst $src0_modifiers, $src0, $src1_modifiers, $src1)>;
+ // Needed for GISel as ut legalizes V2S32 for both divergent and uniform cases.
def : GCNPat<(v2i16 (dagOp (v2f32 VReg_64:$src), i16)),
(inst 0, (EXTRACT_SUBREG VReg_64:$src, sub0),
0, (EXTRACT_SUBREG VReg_64:$src, sub1))>;
def : GCNPat<(v2i16 (dagOp (v2f32 SReg_64:$src), i16)),
(inst 0, (EXTRACT_SUBREG SReg_64:$src, sub0),
0, (EXTRACT_SUBREG SReg_64:$src, sub1))>;
-}
-
-multiclass FPToIntSatI16Pat<dag lhs, dag rhs> {
- let True16Predicate = UseRealTrue16Insts in
- def : GCNPat<lhs, (EXTRACT_SUBREG rhs, lo16)>;
- let True16Predicate = NotUseRealTrue16Insts in
- def : GCNPat<lhs, rhs>;
+ // Single value conversion: use a packed instruction with a dummy second input.
+ defm : FPToIntSatI16Pat<(i16 (dagOp (f32 (VOP3Mods f32:$src0, i32:$src0_modifiers)), i16)),
+ (inst $src0_modifiers, $src0, 0, (f32 (IMPLICIT_DEF)))>;
}
multiclass FPToSSatI16Pat<dag lhs, int hi, int lo> {
@@ -3176,12 +3181,14 @@ multiclass FPToUSatI16Pat<dag lhs, int hi> {
}
let SubtargetPredicate = isGFX11Plus in {
- // f32 -> i16 saturated conversion.
+ // f32 -> i16 saturated conversion (vector and scalar types).
defm : CvtPkF32ToI16Pat<fp_to_sint_sat, V_CVT_PK_I16_F32_e64>;
defm : CvtPkF32ToI16Pat<fp_to_uint_sat, V_CVT_PK_U16_F32_e64>;
}
-// Fallback for f32 -> i16 saturated conversion. Required because
+// Fallback for f32 -> i16 saturated conversion on pre-GFX11. Required because
// f32 -> i16 has to be legal so that the packed pattern above can match.
-defm : FPToSSatI16Pat<(i16 (fp_to_sint_sat (f32 (VOP3Mods f32:$src0, i32:$src0_modifiers)), i16)), 0x7fff, 0x8000>;
-defm : FPToUSatI16Pat<(i16 (fp_to_uint_sat (f32 (VOP3Mods f32:$src0, i32:$src0_modifiers)), i16)), 0xffff>;
+let SubtargetPredicate = isGFX6GFX7GFX8GFX9GFX10 in {
+ defm : FPToSSatI16Pat<(i16 (fp_to_sint_sat (f32 (VOP3Mods f32:$src0, i32:$src0_modifiers)), i16)), 0x7fff, 0x8000>;
+ defm : FPToUSatI16Pat<(i16 (fp_to_uint_sat (f32 (VOP3Mods f32:$src0, i32:$src0_modifiers)), i16)), 0xffff>;
+}
diff --git a/llvm/test/CodeGen/AMDGPU/fptosi-sat-scalar.ll b/llvm/test/CodeGen/AMDGPU/fptosi-sat-scalar.ll
index c75f36e7df7d4..4c6a54c734e85 100644
--- a/llvm/test/CodeGen/AMDGPU/fptosi-sat-scalar.ll
+++ b/llvm/test/CodeGen/AMDGPU/fptosi-sat-scalar.ll
@@ -149,9 +149,7 @@ define i16 @test_signed_i16_f32(float %f) nounwind {
; GFX11-LABEL: test_signed_i16_f32:
; GFX11: ; %bb.0:
; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11-NEXT: v_cvt_i32_f32_e32 v0, v0
-; GFX11-NEXT: v_mov_b32_e32 v1, 0x8000
-; GFX11-NEXT: v_med3_i32 v0, v0, v1, 0x7fff
+; GFX11-NEXT: v_cvt_pk_i16_f32 v0, v0, s0
; GFX11-NEXT: s_setpc_b64 s[30:31]
;
; GFX12-ISEL-LABEL: test_signed_i16_f32:
@@ -161,9 +159,7 @@ define i16 @test_signed_i16_f32(float %f) nounwind {
; GFX12-ISEL-NEXT: s_wait_samplecnt 0x0
; GFX12-ISEL-NEXT: s_wait_bvhcnt 0x0
; GFX12-ISEL-NEXT: s_wait_kmcnt 0x0
-; GFX12-ISEL-NEXT: v_cvt_i32_f32_e32 v0, v0
-; GFX12-ISEL-NEXT: v_mov_b32_e32 v1, 0x8000
-; GFX12-ISEL-NEXT: v_med3_i32 v0, v0, v1, 0x7fff
+; GFX12-ISEL-NEXT: v_cvt_pk_i16_f32 v0, v0, s0
; GFX12-ISEL-NEXT: s_setpc_b64 s[30:31]
;
; GFX12-GI-LABEL: test_signed_i16_f32:
@@ -173,9 +169,7 @@ define i16 @test_signed_i16_f32(float %f) nounwind {
; GFX12-GI-NEXT: s_wait_samplecnt 0x0
; GFX12-GI-NEXT: s_wait_bvhcnt 0x0
; GFX12-GI-NEXT: s_wait_kmcnt 0x0
-; GFX12-GI-NEXT: v_mov_b32_e32 v1, 0x8000
-; GFX12-GI-NEXT: v_cvt_i32_f32_e32 v0, v0
-; GFX12-GI-NEXT: v_med3_i32 v0, v0, v1, 0x7fff
+; GFX12-GI-NEXT: v_cvt_pk_i16_f32 v0, v0, v0
; GFX12-GI-NEXT: s_setpc_b64 s[30:31]
%x = call i16 @llvm.fptosi.sat.i16.f32(float %f)
ret i16 %x
@@ -564,9 +558,7 @@ define i16 @test_s_signed_i16_f32(float inreg %f) nounwind {
; GFX11-LABEL: test_s_signed_i16_f32:
; GFX11: ; %bb.0:
; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11-NEXT: v_cvt_i32_f32_e32 v0, s0
-; GFX11-NEXT: v_mov_b32_e32 v1, 0x8000
-; GFX11-NEXT: v_med3_i32 v0, v0, v1, 0x7fff
+; GFX11-NEXT: v_cvt_pk_i16_f32 v0, s0, s0
; GFX11-NEXT: s_setpc_b64 s[30:31]
;
; GFX12-LABEL: test_s_signed_i16_f32:
diff --git a/llvm/test/CodeGen/AMDGPU/fptoui-sat-scalar.ll b/llvm/test/CodeGen/AMDGPU/fptoui-sat-scalar.ll
index 6a4c3d2d4cc51..f7a98d7642b5e 100644
--- a/llvm/test/CodeGen/AMDGPU/fptoui-sat-scalar.ll
+++ b/llvm/test/CodeGen/AMDGPU/fptoui-sat-scalar.ll
@@ -108,20 +108,28 @@ define i16 @test_unsigned_i16_f32(float %f) nounwind {
; GFX11-LABEL: test_unsigned_i16_f32:
; GFX11: ; %bb.0:
; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11-NEXT: v_cvt_u32_f32_e32 v0, v0
-; GFX11-NEXT: v_min_u32_e32 v0, 0xffff, v0
+; GFX11-NEXT: v_cvt_pk_u16_f32 v0, v0, s0
; GFX11-NEXT: s_setpc_b64 s[30:31]
;
-; GFX12-LABEL: test_unsigned_i16_f32:
-; GFX12: ; %bb.0:
-; GFX12-NEXT: s_wait_loadcnt_dscnt 0x0
-; GFX12-NEXT: s_wait_expcnt 0x0
-; GFX12-NEXT: s_wait_samplecnt 0x0
-; GFX12-NEXT: s_wait_bvhcnt 0x0
-; GFX12-NEXT: s_wait_kmcnt 0x0
-; GFX12-NEXT: v_cvt_u32_f32_e32 v0, v0
-; GFX12-NEXT: v_min_u32_e32 v0, 0xffff, v0
-; GFX12-NEXT: s_setpc_b64 s[30:31]
+; GFX12-ISEL-LABEL: test_unsigned_i16_f32:
+; GFX12-ISEL: ; %bb.0:
+; GFX12-ISEL-NEXT: s_wait_loadcnt_dscnt 0x0
+; GFX12-ISEL-NEXT: s_wait_expcnt 0x0
+; GFX12-ISEL-NEXT: s_wait_samplecnt 0x0
+; GFX12-ISEL-NEXT: s_wait_bvhcnt 0x0
+; GFX12-ISEL-NEXT: s_wait_kmcnt 0x0
+; GFX12-ISEL-NEXT: v_cvt_pk_u16_f32 v0, v0, s0
+; GFX12-ISEL-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX12-GI-LABEL: test_unsigned_i16_f32:
+; GFX12-GI: ; %bb.0:
+; GFX12-GI-NEXT: s_wait_loadcnt_dscnt 0x0
+; GFX12-GI-NEXT: s_wait_expcnt 0x0
+; GFX12-GI-NEXT: s_wait_samplecnt 0x0
+; GFX12-GI-NEXT: s_wait_bvhcnt 0x0
+; GFX12-GI-NEXT: s_wait_kmcnt 0x0
+; GFX12-GI-NEXT: v_cvt_pk_u16_f32 v0, v0, v0
+; GFX12-GI-NEXT: s_setpc_b64 s[30:31]
%x = call i16 @llvm.fptoui.sat.i16.f32(float %f)
ret i16 %x
}
@@ -396,8 +404,7 @@ define i16 @test_s_unsigned_i16_f32(float inreg %f) nounwind {
; GFX11-LABEL: test_s_unsigned_i16_f32:
; GFX11: ; %bb.0:
; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11-NEXT: v_cvt_u32_f32_e32 v0, s0
-; GFX11-NEXT: v_min_u32_e32 v0, 0xffff, v0
+; GFX11-NEXT: v_cvt_pk_u16_f32 v0, s0, s0
; GFX11-NEXT: s_setpc_b64 s[30:31]
;
; GFX12-LABEL: test_s_unsigned_i16_f32:
More information about the llvm-commits
mailing list