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

Igor Wodiany via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 10 02:54:45 PDT 2026


================
@@ -3139,3 +3139,97 @@ 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, SDPatternOperator giOp,
+                            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 (build_vector
+                  (i16 (giOp (f32 (VOP3Mods f32:$src0, i32:$src0_modifiers)))),
+                  (i16 (giOp (f32 (VOP3Mods f32:$src1, i32:$src1_modifiers)))))),
+               (inst $src0_modifiers, $src0, $src1_modifiers, $src1)>;
+}
+
+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),
+                      (S_MOV_B32 (i32 lo)), (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.
+  // FIXME: GISel diverges from SelectionDAG when the v2i16 build_vector is
+  // fed by *uniform* f32 values on subtargets with HasSALUFloat. The
+  // regbank rule routes the f32 -> i16 conversion to the SALU, preventing
+  // this packed pattern from matching. SDAG always matches the packed form.
+  // At the same time we need the regbank rules for SALUFloat to keep
+  // "*-scalar.ll" tests from regressing.
+  defm : CvtPkF32ToI16Pat<fp_to_sint_sat, fp_to_sint_sat_gi, V_CVT_PK_I16_F32_e64>;
----------------
IgWod wrote:

Please see #202908.

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


More information about the llvm-commits mailing list