-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[RISCV] Match widening fp instructions with same fpext used in multiple operands #125803
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…le operands 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)
@llvm/pr-subscribers-backend-risc-v Author: Luke Lau (lukel97) ChangesBecause 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) Full diff: https://github.com/llvm/llvm-project/pull/125803.diff 6 Files Affected:
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td b/llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td
index 8f77b2ce34d1f1..72f91f71e78537 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td
@@ -536,19 +536,19 @@ multiclass VPatWidenBinaryFPSDNode_VV_VF<SDNode op, string instruction_name> {
defvar wti = vtiToWti.Wti;
let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates,
GetVTypePredicates<wti>.Predicates) in {
- def : Pat<(op (wti.Vector (riscv_fpextend_vl_oneuse
+ def : Pat<(op (wti.Vector (riscv_fpextend_vl_oneuser
(vti.Vector vti.RegClass:$rs2),
(vti.Mask true_mask), (XLenVT srcvalue))),
- (wti.Vector (riscv_fpextend_vl_oneuse
+ (wti.Vector (riscv_fpextend_vl_oneuser
(vti.Vector vti.RegClass:$rs1),
(vti.Mask true_mask), (XLenVT srcvalue)))),
(!cast<Instruction>(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_oneuser
(vti.Vector vti.RegClass:$rs2),
(vti.Mask true_mask), (XLenVT srcvalue))),
- (wti.Vector (riscv_fpextend_vl_oneuse
+ (wti.Vector (riscv_fpextend_vl_oneuser
(vti.Vector (SplatFPOp vti.ScalarRegClass:$rs1)),
(vti.Mask true_mask), (XLenVT srcvalue)))),
(!cast<Instruction>(instruction_name#"_V"#vti.ScalarSuffix#"_"#vti.LMul.MX)
@@ -571,10 +571,10 @@ multiclass VPatWidenBinaryFPSDNode_VV_VF_RM<SDNode op, string instruction_name>
defvar wti = vtiToWti.Wti;
let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates,
GetVTypePredicates<wti>.Predicates) in {
- def : Pat<(op (wti.Vector (riscv_fpextend_vl_oneuse
+ def : Pat<(op (wti.Vector (riscv_fpextend_vl_oneuser
(vti.Vector vti.RegClass:$rs2),
(vti.Mask true_mask), (XLenVT srcvalue))),
- (wti.Vector (riscv_fpextend_vl_oneuse
+ (wti.Vector (riscv_fpextend_vl_oneuser
(vti.Vector vti.RegClass:$rs1),
(vti.Mask true_mask), (XLenVT srcvalue)))),
(!cast<Instruction>(instruction_name#"_VV_"#vti.LMul.MX#"_E"#vti.SEW)
@@ -584,10 +584,10 @@ multiclass VPatWidenBinaryFPSDNode_VV_VF_RM<SDNode op, string instruction_name>
// 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_oneuser
(vti.Vector vti.RegClass:$rs2),
(vti.Mask true_mask), (XLenVT srcvalue))),
- (wti.Vector (riscv_fpextend_vl_oneuse
+ (wti.Vector (riscv_fpextend_vl_oneuser
(vti.Vector (SplatFPOp (vti.Scalar vti.ScalarRegClass:$rs1))),
(vti.Mask true_mask), (XLenVT srcvalue)))),
(!cast<Instruction>(instruction_name#"_V"#vti.ScalarSuffix#"_"#vti.LMul.MX#"_E"#vti.SEW)
@@ -669,10 +669,10 @@ multiclass VPatWidenFPMulAccSDNode_VV_VF_RM<string instruction_name,
!if(!eq(vti.Scalar, bf16),
[HasStdExtZvfbfwma],
[])) in {
- def : Pat<(fma (wti.Vector (riscv_fpextend_vl_oneuse
+ def : Pat<(fma (wti.Vector (riscv_fpextend_vl_oneuser
(vti.Vector vti.RegClass:$rs1),
(vti.Mask true_mask), (XLenVT srcvalue))),
- (wti.Vector (riscv_fpextend_vl_oneuse
+ (wti.Vector (riscv_fpextend_vl_oneuser
(vti.Vector vti.RegClass:$rs2),
(vti.Mask true_mask), (XLenVT srcvalue))),
(wti.Vector wti.RegClass:$rd)),
@@ -749,11 +749,11 @@ multiclass VPatWidenFPMulSacSDNode_VV_VF_RM<string instruction_name> {
defvar suffix = vti.LMul.MX # "_E" # vti.SEW;
let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates,
GetVTypePredicates<wti>.Predicates) in {
- def : Pat<(fma (wti.Vector (riscv_fpextend_vl_oneuse
+ def : Pat<(fma (wti.Vector (riscv_fpextend_vl_oneuser
(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_oneuser (vti.Vector vti.RegClass:$rs2),
+ (vti.Mask true_mask), (XLenVT srcvalue)),
(fneg wti.RegClass:$rd)),
(!cast<Instruction>(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 333ae52534681a..0e6f807ae26af5 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_oneuser : 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 68014ff4206f8a..f7d287a088cc3e 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vfwadd-sdnode.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/vfwadd-sdnode.ll
@@ -323,3 +323,15 @@ define <vscale x 8 x double> @vfwadd_wf_nxv8f64_2(<vscale x 8 x double> %va, flo
%vd = fadd <vscale x 8 x double> %va, %splat
ret <vscale x 8 x double> %vd
}
+
+define <vscale x 1 x double> @vfwadd_vv_nxv1f64_same_op(<vscale x 1 x float> %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 <vscale x 1 x float> %va to <vscale x 1 x double>
+ %vc = fadd <vscale x 1 x double> %vb, %vb
+ ret <vscale x 1 x double> %vc
+}
diff --git a/llvm/test/CodeGen/RISCV/rvv/vfwmacc-sdnode.ll b/llvm/test/CodeGen/RISCV/rvv/vfwmacc-sdnode.ll
index f69b2346226ee9..63113b87809894 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vfwmacc-sdnode.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/vfwmacc-sdnode.ll
@@ -1764,3 +1764,28 @@ define <vscale x 8 x double> @vfwnmsac_fv_nxv8f64(<vscale x 8 x double> %va, <vs
%vg = call <vscale x 8 x double> @llvm.fma.v8f64(<vscale x 8 x double> %vd, <vscale x 8 x double> %vf, <vscale x 8 x double> %va)
ret <vscale x 8 x double> %vg
}
+
+define <vscale x 1 x double> @vfwma_vv_nxv1f64_same_op(<vscale x 1 x float> %va, <vscale x 1 x double> %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 <vscale x 1 x float> %va to <vscale x 1 x double>
+ %vd = call <vscale x 1 x double> @llvm.fma(<vscale x 1 x double> %vc, <vscale x 1 x double> %vc, <vscale x 1 x double> %vb)
+ ret <vscale x 1 x double> %vd
+}
+
+define <vscale x 1 x double> @vfwmsac_vv_nxv1f64_same_op(<vscale x 1 x float> %va, <vscale x 1 x double> %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 <vscale x 1 x float> %va to <vscale x 1 x double>
+ %vd = fneg <vscale x 1 x double> %vb
+ %ve = call <vscale x 1 x double> @llvm.fma(<vscale x 1 x double> %vc, <vscale x 1 x double> %vc, <vscale x 1 x double> %vd)
+ ret <vscale x 1 x double> %ve
+}
diff --git a/llvm/test/CodeGen/RISCV/rvv/vfwmul-sdnode.ll b/llvm/test/CodeGen/RISCV/rvv/vfwmul-sdnode.ll
index f00ff4b6d2cec2..8cc8c5cffca6b2 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vfwmul-sdnode.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/vfwmul-sdnode.ll
@@ -175,3 +175,15 @@ define <vscale x 8 x double> @vfwmul_vf_nxv8f64_2(<vscale x 8 x float> %va, floa
%ve = fmul <vscale x 8 x double> %vc, %splat
ret <vscale x 8 x double> %ve
}
+
+define <vscale x 1 x double> @vfwmul_vv_nxv1f64_same_op(<vscale x 1 x float> %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 <vscale x 1 x float> %va to <vscale x 1 x double>
+ %vc = fmul <vscale x 1 x double> %vb, %vb
+ ret <vscale x 1 x double> %vc
+}
diff --git a/llvm/test/CodeGen/RISCV/rvv/vfwsub-sdnode.ll b/llvm/test/CodeGen/RISCV/rvv/vfwsub-sdnode.ll
index b9f66d5d30825d..d0cb64d9866618 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vfwsub-sdnode.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/vfwsub-sdnode.ll
@@ -323,3 +323,15 @@ define <vscale x 8 x double> @vfwsub_wf_nxv8f64_2(<vscale x 8 x double> %va, flo
%vd = fsub <vscale x 8 x double> %va, %splat
ret <vscale x 8 x double> %vd
}
+
+define <vscale x 1 x double> @vfwsub_vv_nxv1f64_same_op(<vscale x 1 x float> %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 <vscale x 1 x float> %va to <vscale x 1 x double>
+ %vc = fsub <vscale x 1 x double> %vb, %vb
+ ret <vscale x 1 x double> %vc
+}
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
…le operands (llvm#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)
…le operands (llvm#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)
…le operands (llvm#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)
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)