From e42fdcb41fdcfe7bf302b40f20afb4e9cda5602d Mon Sep 17 00:00:00 2001 From: Luke Lau Date: Tue, 11 Feb 2025 01:11:44 +0800 Subject: [PATCH] [RISCV] Match widening fp instructions with same fpext used in multiple operands (#125803) Because the fpext has a single use constraint on it we can't match cases where it's used for both operands. Introduce a new PatFrag that allows multiple uses on a single user and use it for the binary patterns, and some ternary patterns. (For some of the ternary patterns there is a fneg that counts as a separate user, we still need to handle these) --- .../Target/RISCV/RISCVInstrInfoVSDPatterns.td | 26 +++++++++---------- .../Target/RISCV/RISCVInstrInfoVVLPatterns.td | 5 ++++ llvm/test/CodeGen/RISCV/rvv/vfwadd-sdnode.ll | 12 +++++++++ llvm/test/CodeGen/RISCV/rvv/vfwmacc-sdnode.ll | 25 ++++++++++++++++++ llvm/test/CodeGen/RISCV/rvv/vfwmul-sdnode.ll | 12 +++++++++ llvm/test/CodeGen/RISCV/rvv/vfwsub-sdnode.ll | 12 +++++++++ 6 files changed, 79 insertions(+), 13 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td b/llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td index 8f77b2ce34d1..c588e047c2ac 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td @@ -536,19 +536,19 @@ multiclass VPatWidenBinaryFPSDNode_VV_VF { defvar wti = vtiToWti.Wti; let Predicates = !listconcat(GetVTypePredicates.Predicates, GetVTypePredicates.Predicates) in { - def : Pat<(op (wti.Vector (riscv_fpextend_vl_oneuse + def : Pat<(op (wti.Vector (riscv_fpextend_vl_sameuser (vti.Vector vti.RegClass:$rs2), (vti.Mask true_mask), (XLenVT srcvalue))), - (wti.Vector (riscv_fpextend_vl_oneuse + (wti.Vector (riscv_fpextend_vl_sameuser (vti.Vector vti.RegClass:$rs1), (vti.Mask true_mask), (XLenVT srcvalue)))), (!cast(instruction_name#"_VV_"#vti.LMul.MX) (wti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs2, vti.RegClass:$rs1, vti.AVL, vti.Log2SEW, TA_MA)>; - def : Pat<(op (wti.Vector (riscv_fpextend_vl_oneuse + def : Pat<(op (wti.Vector (riscv_fpextend_vl_sameuser (vti.Vector vti.RegClass:$rs2), (vti.Mask true_mask), (XLenVT srcvalue))), - (wti.Vector (riscv_fpextend_vl_oneuse + (wti.Vector (riscv_fpextend_vl_sameuser (vti.Vector (SplatFPOp vti.ScalarRegClass:$rs1)), (vti.Mask true_mask), (XLenVT srcvalue)))), (!cast(instruction_name#"_V"#vti.ScalarSuffix#"_"#vti.LMul.MX) @@ -571,10 +571,10 @@ multiclass VPatWidenBinaryFPSDNode_VV_VF_RM defvar wti = vtiToWti.Wti; let Predicates = !listconcat(GetVTypePredicates.Predicates, GetVTypePredicates.Predicates) in { - def : Pat<(op (wti.Vector (riscv_fpextend_vl_oneuse + def : Pat<(op (wti.Vector (riscv_fpextend_vl_sameuser (vti.Vector vti.RegClass:$rs2), (vti.Mask true_mask), (XLenVT srcvalue))), - (wti.Vector (riscv_fpextend_vl_oneuse + (wti.Vector (riscv_fpextend_vl_sameuser (vti.Vector vti.RegClass:$rs1), (vti.Mask true_mask), (XLenVT srcvalue)))), (!cast(instruction_name#"_VV_"#vti.LMul.MX#"_E"#vti.SEW) @@ -584,10 +584,10 @@ multiclass VPatWidenBinaryFPSDNode_VV_VF_RM // RISCVInsertReadWriteCSR FRM_DYN, vti.AVL, vti.Log2SEW, TA_MA)>; - def : Pat<(op (wti.Vector (riscv_fpextend_vl_oneuse + def : Pat<(op (wti.Vector (riscv_fpextend_vl_sameuser (vti.Vector vti.RegClass:$rs2), (vti.Mask true_mask), (XLenVT srcvalue))), - (wti.Vector (riscv_fpextend_vl_oneuse + (wti.Vector (riscv_fpextend_vl_sameuser (vti.Vector (SplatFPOp (vti.Scalar vti.ScalarRegClass:$rs1))), (vti.Mask true_mask), (XLenVT srcvalue)))), (!cast(instruction_name#"_V"#vti.ScalarSuffix#"_"#vti.LMul.MX#"_E"#vti.SEW) @@ -669,10 +669,10 @@ multiclass VPatWidenFPMulAccSDNode_VV_VF_RM { defvar suffix = vti.LMul.MX # "_E" # vti.SEW; let Predicates = !listconcat(GetVTypePredicates.Predicates, GetVTypePredicates.Predicates) in { - def : Pat<(fma (wti.Vector (riscv_fpextend_vl_oneuse + def : Pat<(fma (wti.Vector (riscv_fpextend_vl_sameuser (vti.Vector vti.RegClass:$rs1), (vti.Mask true_mask), (XLenVT srcvalue))), - (riscv_fpextend_vl_oneuse (vti.Vector vti.RegClass:$rs2), - (vti.Mask true_mask), (XLenVT srcvalue)), + (riscv_fpextend_vl_sameuser (vti.Vector vti.RegClass:$rs2), + (vti.Mask true_mask), (XLenVT srcvalue)), (fneg wti.RegClass:$rd)), (!cast(instruction_name#"_VV_"#suffix) wti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2, diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td b/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td index 333ae5253468..f63c1560f625 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td @@ -554,6 +554,11 @@ def riscv_fpextend_vl_oneuse : PatFrag<(ops node:$A, node:$B, node:$C), return N->hasOneUse(); }]>; +def riscv_fpextend_vl_sameuser : PatFrag<(ops node:$A, node:$B, node:$C), + (riscv_fpextend_vl node:$A, node:$B, node:$C), [{ + return !N->use_empty() && all_equal(N->users()); +}]>; + def riscv_vfmadd_vl_oneuse : PatFrag<(ops node:$A, node:$B, node:$C, node:$D, node:$E), (riscv_vfmadd_vl node:$A, node:$B, diff --git a/llvm/test/CodeGen/RISCV/rvv/vfwadd-sdnode.ll b/llvm/test/CodeGen/RISCV/rvv/vfwadd-sdnode.ll index 68014ff4206f..f7d287a088cc 100644 --- a/llvm/test/CodeGen/RISCV/rvv/vfwadd-sdnode.ll +++ b/llvm/test/CodeGen/RISCV/rvv/vfwadd-sdnode.ll @@ -323,3 +323,15 @@ define @vfwadd_wf_nxv8f64_2( %va, flo %vd = fadd %va, %splat ret %vd } + +define @vfwadd_vv_nxv1f64_same_op( %va) { +; CHECK-LABEL: vfwadd_vv_nxv1f64_same_op: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32, mf2, ta, ma +; CHECK-NEXT: vfwadd.vv v9, v8, v8 +; CHECK-NEXT: vmv1r.v v8, v9 +; CHECK-NEXT: ret + %vb = fpext %va to + %vc = fadd %vb, %vb + ret %vc +} diff --git a/llvm/test/CodeGen/RISCV/rvv/vfwmacc-sdnode.ll b/llvm/test/CodeGen/RISCV/rvv/vfwmacc-sdnode.ll index f69b2346226e..63113b878098 100644 --- a/llvm/test/CodeGen/RISCV/rvv/vfwmacc-sdnode.ll +++ b/llvm/test/CodeGen/RISCV/rvv/vfwmacc-sdnode.ll @@ -1764,3 +1764,28 @@ define @vfwnmsac_fv_nxv8f64( %va, @llvm.fma.v8f64( %vd, %vf, %va) ret %vg } + +define @vfwma_vv_nxv1f64_same_op( %va, %vb) { +; CHECK-LABEL: vfwma_vv_nxv1f64_same_op: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32, mf2, ta, ma +; CHECK-NEXT: vfwmacc.vv v9, v8, v8 +; CHECK-NEXT: vmv1r.v v8, v9 +; CHECK-NEXT: ret + %vc = fpext %va to + %vd = call @llvm.fma( %vc, %vc, %vb) + ret %vd +} + +define @vfwmsac_vv_nxv1f64_same_op( %va, %vb) { +; CHECK-LABEL: vfwmsac_vv_nxv1f64_same_op: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32, mf2, ta, ma +; CHECK-NEXT: vfwmsac.vv v9, v8, v8 +; CHECK-NEXT: vmv1r.v v8, v9 +; CHECK-NEXT: ret + %vc = fpext %va to + %vd = fneg %vb + %ve = call @llvm.fma( %vc, %vc, %vd) + ret %ve +} diff --git a/llvm/test/CodeGen/RISCV/rvv/vfwmul-sdnode.ll b/llvm/test/CodeGen/RISCV/rvv/vfwmul-sdnode.ll index f00ff4b6d2ce..8cc8c5cffca6 100644 --- a/llvm/test/CodeGen/RISCV/rvv/vfwmul-sdnode.ll +++ b/llvm/test/CodeGen/RISCV/rvv/vfwmul-sdnode.ll @@ -175,3 +175,15 @@ define @vfwmul_vf_nxv8f64_2( %va, floa %ve = fmul %vc, %splat ret %ve } + +define @vfwmul_vv_nxv1f64_same_op( %va) { +; CHECK-LABEL: vfwmul_vv_nxv1f64_same_op: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32, mf2, ta, ma +; CHECK-NEXT: vfwmul.vv v9, v8, v8 +; CHECK-NEXT: vmv1r.v v8, v9 +; CHECK-NEXT: ret + %vb = fpext %va to + %vc = fmul %vb, %vb + ret %vc +} diff --git a/llvm/test/CodeGen/RISCV/rvv/vfwsub-sdnode.ll b/llvm/test/CodeGen/RISCV/rvv/vfwsub-sdnode.ll index b9f66d5d3082..d0cb64d98666 100644 --- a/llvm/test/CodeGen/RISCV/rvv/vfwsub-sdnode.ll +++ b/llvm/test/CodeGen/RISCV/rvv/vfwsub-sdnode.ll @@ -323,3 +323,15 @@ define @vfwsub_wf_nxv8f64_2( %va, flo %vd = fsub %va, %splat ret %vd } + +define @vfwsub_vv_nxv1f64_same_op( %va) { +; CHECK-LABEL: vfwsub_vv_nxv1f64_same_op: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32, mf2, ta, ma +; CHECK-NEXT: vfwsub.vv v9, v8, v8 +; CHECK-NEXT: vmv1r.v v8, v9 +; CHECK-NEXT: ret + %vb = fpext %va to + %vc = fsub %vb, %vb + ret %vc +}