[llvm] [AMDGPU] Use `v_cvt_pk_*` instructions for i16_f32 saturated conversions (PR #202680)

Jay Foad via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 11 08:12:40 PDT 2026


================
@@ -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
----------------
jayfoad wrote:

Is V_CVT_F16_F32 followed by V_CVT_I16_F16 a neater way to implement this?

An on GFX11+ can you implement it by still using V_CVT_PK_I16_F32 but with one of the inputs being a dummy, and extracting only the relevant half of the result?

https://github.com/llvm/llvm-project/pull/202680


More information about the llvm-commits mailing list