[llvm] [RISCV][ISel] Remove redundant min/max in saturating truncation (PR #75145)

via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 11 23:43:38 PST 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-risc-v

Author: Chia (sun-jacobi)

<details>
<summary>Changes</summary>

This patch is aiming at fixing a missed-optimization case similar to #<!-- -->68466 on X86.

## Source Code
```
define void @<!-- -->trunc_maxmin_id_i8i16(ptr %x, ptr %y) {
  %1 = load <8 x i16>, ptr %x, align 16
  %2 = tail call <8 x i16> @<!-- -->llvm.smax.v8i16(<8 x i16> %1, <8 x i16> <i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128>)
  %3 = tail call <8 x i16> @<!-- -->llvm.smin.v8i16(<8 x i16> %2, <8 x i16> <i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127>)
  %4 = trunc <8 x i16> %3 to <8 x i8>
  store <8 x i8> %4, ptr %y, align 8
  ret void
}
```
## Before this patch: 
```
trunc_maxmin_id_i8i16:                  # @<!-- -->trunc_maxmin_id_i8i16
        vsetivli        zero, 8, e16, m1, ta, ma
        vle16.v v8, (a0)
        li      a0, -128
        vmax.vx v8, v8, a0
        li      a0, 127
        vmin.vx v8, v8, a0
        vsetvli zero, zero, e8, mf2, ta, ma
        vnsrl.wi        v8, v8, 0
        vse8.v  v8, (a1)
        ret
```

## After this patch: 
```
trunc_maxmin_id_i8i16:                  # @<!-- -->trunc_maxmin_id_i8i16
	vsetivli	zero, 8, e8, mf2, ta, ma
	vle16.v	v8, (a0)
	vnsrl.wi	v8, v8, 0
	vse8.v	v8, (a1)
	ret
```

This issue is also inspired by #<!-- -->73424, but not using `vnclip`



---
Full diff: https://github.com/llvm/llvm-project/pull/75145.diff


1 Files Affected:

- (modified) llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td (+54) 


``````````diff
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td b/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td
index dc6b57fad3210..91eb9d775682c 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td
@@ -1618,6 +1618,60 @@ multiclass VPatBinaryFPWVL_VV_VF_WV_WF_RM<SDNode vop, SDNode vop_w, string instr
   }
 }
 
+
+multiclass VPatTruncSplatMaxMinIdentityBase<VTypeInfo vti, VTypeInfo wti,
+  SDPatternOperator vop1, int vid1, SDPatternOperator vop2, int vid2> {
+  let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates,
+                               GetVTypePredicates<wti>.Predicates) in
+  def : Pat<(vti.Vector (riscv_trunc_vector_vl
+    (wti.Vector (vop1
+        (wti.Vector (vop2
+            (wti.Vector wti.RegClass:$rs1),
+            (wti.Vector (riscv_vmv_v_x_vl (wti.Vector undef), vid2, (XLenVT srcvalue))),
+            (wti.Vector undef),(wti.Mask V0), VLOpFrag)),
+        (wti.Vector (riscv_vmv_v_x_vl (wti.Vector undef), vid1, (XLenVT srcvalue))),
+        (wti.Vector undef), (wti.Mask V0), VLOpFrag)),
+    (vti.Mask V0), VLOpFrag)),
+    (!cast<Instruction>("PseudoVNSRL_WI_"#vti.LMul.MX#"_MASK")
+      (vti.Vector (IMPLICIT_DEF)), wti.RegClass:$rs1, 0,
+      (vti.Mask V0), GPR:$vl, vti.Log2SEW, TA_MA)>;
+}
+
+multiclass VPatTruncSplatMinIdentityBase<VTypeInfo vti, VTypeInfo wti,
+  SDPatternOperator vop, int vid> {
+  let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates,
+                               GetVTypePredicates<wti>.Predicates) in
+  def : Pat<(vti.Vector (riscv_trunc_vector_vl
+    (wti.Vector (vop
+      (wti.Vector wti.RegClass:$rs1),
+      (wti.Vector (riscv_vmv_v_x_vl (wti.Vector undef), vid, (XLenVT srcvalue))),
+      (wti.Vector undef), (wti.Mask V0), VLOpFrag)),
+    (vti.Mask V0), VLOpFrag)),
+    (!cast<Instruction>("PseudoVNSRL_WI_"#vti.LMul.MX#"_MASK")
+      (vti.Vector (IMPLICIT_DEF)), wti.RegClass:$rs1, 0,
+      (vti.Mask V0), GPR:$vl, vti.Log2SEW, TA_MA)>;
+}
+
+
+multiclass VPatTruncSplatMaxMinIdentity<VTypeInfo vti, VTypeInfo wti> {
+  defvar sew = vti.SEW;
+  defvar umin_id = !sub(!shl(1, sew), 1);
+  defvar umax_id = 0;
+  defvar smin_id = !sub(!shl(1, !sub(sew, 1)), 1);
+  defvar smax_id = !sub(0, !shl(1, !sub(sew, 1)));
+
+  defm : VPatTruncSplatMaxMinIdentityBase<vti, wti, riscv_umax_vl, umax_id, riscv_umin_vl, umin_id>;
+  defm : VPatTruncSplatMaxMinIdentityBase<vti, wti, riscv_umin_vl, umin_id, riscv_umax_vl, umax_id>;
+  defm : VPatTruncSplatMaxMinIdentityBase<vti, wti, riscv_smin_vl, smin_id, riscv_smax_vl, smax_id>;
+  defm : VPatTruncSplatMaxMinIdentityBase<vti, wti, riscv_smax_vl, smax_id, riscv_smin_vl, smin_id>;
+
+  defm : VPatTruncSplatMinIdentityBase<vti, wti, riscv_umin_vl, umin_id>;
+
+}
+
+foreach vtiToWti = AllWidenableIntVectors in
+  defm : VPatTruncSplatMaxMinIdentity<vtiToWti.Vti, vtiToWti.Wti>;
+
 multiclass VPatNarrowShiftSplatExt_WX<SDNode op, PatFrags extop, string instruction_name> {
   foreach vtiToWti = AllWidenableIntVectors in {
     defvar vti = vtiToWti.Vti;

``````````

</details>


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


More information about the llvm-commits mailing list