[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