[1/5] RISC-V: Remove float vector eqne pattern
Checks
Commit Message
We can unify eqne and other comparison operations.
Tested on RV32 and RV64
gcc/ChangeLog:
* config/riscv/riscv-vector-builtins-bases.cc: Remove eqne cond
* config/riscv/vector.md (@pred_eqne<mode>_scalar): Remove patterns
(*pred_eqne<mode>_scalar_merge_tie_mask): Ditto
(*pred_eqne<mode>_scalar): Ditto
(*pred_eqne<mode>_scalar_narrow): Ditto
Signed-off-by: demin.han <demin.han@starfivetech.com>
---
.../riscv/riscv-vector-builtins-bases.cc | 4 -
gcc/config/riscv/vector.md | 86 -------------------
2 files changed, 90 deletions(-)
Comments
Hello, han. Thanks for trying to optimize the codes.
But I believe those vector-scalar patterns (eq/ne) you remove in this patch are necessary.
This is the story:
1. For commutative RTL code in GCC like plus, eq, ne, ... etc,
we known in semantic Both (eq: (reg) (vec_duplicate ... ) and (eq: (vec_duplicate ... ) (reg)) are right.
However, GCC prefer this order as I remembered - (eq: (vec_duplicate ... ) (reg)).
2. Before this patch, the order of the comparison as follows (take eq and lt as an example):
1). (eq: (vec_duplicate ... ) (reg)) --> commutative
2). (lt: (reg) (vec_duplicate ... ) --> non-commutative
These patterns order are different.
So, you see we have dedicated patterns (seems duplicate patterns) for vector-scalar eq/ne, whereas, we unify eq/ne into other comparisons for vector-vector instructions.
If we unify eq/ne into other comparisons for vector-scalar instructions (like your patch does), we will end up have:
(eq: (reg) (vec_duplicate ... ) [after this patch] instead of (eq: (vec_duplicate ... ) (reg)) [Before this patch].
So, I think this patch may not be right.
I may be wrong, Robin/Jerff/kito feel free to correct me if I am wrong.
------------------ Original ------------------
From: "demin.han"<demin.han@starfivetech.com>;
Date: Fri, Mar 1, 2024 02:27 PM
To: "gcc-patches"<gcc-patches@gcc.gnu.org>;
Cc: "juzhe.zhong"<juzhe.zhong@rivai.ai>; "kito.cheng"<kito.cheng@gmail.com>; "Li, Pan2"<pan2.li@intel.com>; "jeffreyalaw"<jeffreyalaw@gmail.com>;
Subject: [PATCH 1/5] RISC-V: Remove float vector eqne pattern
We can unify eqne and other comparison operations.
Tested on RV32 and RV64
gcc/ChangeLog:
* config/riscv/riscv-vector-builtins-bases.cc: Remove eqne cond
* config/riscv/vector.md (@pred_eqne<mode>_scalar): Remove patterns
(*pred_eqne<mode>_scalar_merge_tie_mask): Ditto
(*pred_eqne<mode>_scalar): Ditto
(*pred_eqne<mode>_scalar_narrow): Ditto
Signed-off-by: demin.han <demin.han@starfivetech.com>
---
.../riscv/riscv-vector-builtins-bases.cc | 4 -
gcc/config/riscv/vector.md | 86 -------------------
2 files changed, 90 deletions(-)
diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.cc b/gcc/config/riscv/riscv-vector-builtins-bases.cc
index b6f6e4ff37e..d414721ede8 100644
--- a/gcc/config/riscv/riscv-vector-builtins-bases.cc
+++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc
@@ -1420,10 +1420,6 @@ public:
switch (e.op_info->op)
{
case OP_TYPE_vf: {
- if (CODE == EQ || CODE == NE)
- return e.use_compare_insn (CODE, code_for_pred_eqne_scalar (
- e.vector_mode ()));
- else
return e.use_compare_insn (CODE, code_for_pred_cmp_scalar (
e.vector_mode ()));
}
diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index ab6e099852d..9210d7c28ad 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -7520,92 +7520,6 @@ (define_insn "*pred_cmp<mode>_scalar_narrow"
(set_attr "mode" "<MODE>")
(set_attr "spec_restriction" "none,thv,thv,none,none")])
-(define_expand "@pred_eqne<mode>_scalar"
- [(set (match_operand:<VM> 0 "register_operand")
- (if_then_else:<VM>
- (unspec:<VM>
- [(match_operand:<VM> 1 "vector_mask_operand")
- (match_operand 6 "vector_length_operand")
- (match_operand 7 "const_int_operand")
- (match_operand 8 "const_int_operand")
- (reg:SI VL_REGNUM)
- (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
- (match_operator:<VM> 3 "equality_operator"
- [(vec_duplicate:V_VLSF
- (match_operand:<VEL> 5 "register_operand"))
- (match_operand:V_VLSF 4 "register_operand")])
- (match_operand:<VM> 2 "vector_merge_operand")))]
- "TARGET_VECTOR"
- {})
-
-(define_insn "*pred_eqne<mode>_scalar_merge_tie_mask"
- [(set (match_operand:<VM> 0 "register_operand" "=vm")
- (if_then_else:<VM>
- (unspec:<VM>
- [(match_operand:<VM> 1 "register_operand" " 0")
- (match_operand 5 "vector_length_operand" " rK")
- (match_operand 6 "const_int_operand" " i")
- (match_operand 7 "const_int_operand" " i")
- (reg:SI VL_REGNUM)
- (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
- (match_operator:<VM> 2 "equality_operator"
- [(vec_duplicate:V_VLSF
- (match_operand:<VEL> 4 "register_operand" " f"))
- (match_operand:V_VLSF 3 "register_operand" " vr")])
- (match_dup 1)))]
- "TARGET_VECTOR"
- "vmf%B2.vf\t%0,%3,%4,v0.t"
- [(set_attr "type" "vfcmp")
- (set_attr "mode" "<MODE>")
- (set_attr "merge_op_idx" "1")
- (set_attr "vl_op_idx" "5")
- (set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[6])"))
- (set (attr "avl_type_idx") (const_int 7))])
-
-;; We don't use early-clobber for LMUL <= 1 to get better codegen.
-(define_insn "*pred_eqne<mode>_scalar"
- [(set (match_operand:<VM> 0 "register_operand" "=vr, vr, &vr, &vr")
- (if_then_else:<VM>
- (unspec:<VM>
- [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1,vmWc1,vmWc1,vmWc1")
- (match_operand 6 "vector_length_operand" " rK, rK, rK, rK")
- (match_operand 7 "const_int_operand" " i, i, i, i")
- (match_operand 8 "const_int_operand" " i, i, i, i")
- (reg:SI VL_REGNUM)
- (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
- (match_operator:<VM> 3 "equality_operator"
- [(vec_duplicate:V_VLSF
- (match_operand:<VEL> 5 "register_operand" " f, f, f, f"))
- (match_operand:V_VLSF 4 "register_operand" " vr, vr, vr, vr")])
- (match_operand:<VM> 2 "vector_merge_operand" " vu, 0, vu, 0")))]
- "TARGET_VECTOR && riscv_vector::cmp_lmul_le_one (<MODE>mode)"
- "vmf%B3.vf\t%0,%4,%5%p1"
- [(set_attr "type" "vfcmp")
- (set_attr "mode" "<MODE>")
- (set_attr "spec_restriction" "thv,thv,rvv,rvv")])
-
-;; We use early-clobber for source LMUL > dest LMUL.
-(define_insn "*pred_eqne<mode>_scalar_narrow"
- [(set (match_operand:<VM> 0 "register_operand" "=vm, vr, vr, &vr, &vr")
- (if_then_else:<VM>
- (unspec:<VM>
- [(match_operand:<VM> 1 "vector_mask_operand" " 0,vmWc1,vmWc1,vmWc1,vmWc1")
- (match_operand 6 "vector_length_operand" " rK, rK, rK, rK, rK")
- (match_operand 7 "const_int_operand" " i, i, i, i, i")
- (match_operand 8 "const_int_operand" " i, i, i, i, i")
- (reg:SI VL_REGNUM)
- (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
- (match_operator:<VM> 3 "equality_operator"
- [(vec_duplicate:V_VLSF
- (match_operand:<VEL> 5 "register_operand" " f, f, f, f, f"))
- (match_operand:V_VLSF 4 "register_operand" " vr, 0, 0, vr, vr")])
- (match_operand:<VM> 2 "vector_merge_operand" " vu, vu, 0, vu, 0")))]
- "TARGET_VECTOR && riscv_vector::cmp_lmul_gt_one (<MODE>mode)"
- "vmf%B3.vf\t%0,%4,%5%p1"
- [(set_attr "type" "vfcmp")
- (set_attr "mode" "<MODE>")
- (set_attr "spec_restriction" "none,thv,thv,none,none")])
-
;; -------------------------------------------------------------------------------
;; ---- Predicated floating-point merge
;; -------------------------------------------------------------------------------
--
2.43.2
Hi juzhe,
I also thought it’s related to commutive firstly.
Following things make me to do the removal:
1. No tests fails in regression
2. When I write if (a == 2) and if (2 == a), the results are same
3. The vec_duplicate operand is the 5th operand in both cmp and eqne patterns. I think they are equal.
From: 钟居哲 <juzhe.zhong@rivai.ai>
Sent: 2024年3月1日 15:24
To: Demin Han <demin.han@starfivetech.com>; gcc-patches <gcc-patches@gcc.gnu.org>
Cc: kito.cheng <kito.cheng@gmail.com>; Li, Pan2 <pan2.li@intel.com>; jeffreyalaw <jeffreyalaw@gmail.com>; Robin Dapp <rdapp.gcc@gmail.com>
Subject: Re:[PATCH 1/5] RISC-V: Remove float vector eqne pattern
Hello, han. Thanks for trying to optimize the codes.
But I believe those vector-scalar patterns (eq/ne) you remove in this patch are necessary.
This is the story:
1. For commutative RTL code in GCC like plus, eq, ne, ... etc,
we known in semantic Both (eq: (reg) (vec_duplicate ... ) and (eq: (vec_duplicate ... ) (reg)) are right.
However, GCC prefer this order as I remembered - (eq: (vec_duplicate ... ) (reg)).
2. Before this patch, the order of the comparison as follows (take eq and lt as an example):
1). (eq: (vec_duplicate ... ) (reg)) --> commutative
2). (lt: (reg) (vec_duplicate ... ) --> non-commutative
These patterns order are different.
So, you see we have dedicated patterns (seems duplicate patterns) for vector-scalar eq/ne, whereas, we unify eq/ne into other comparisons for vector-vector instructions.
If we unify eq/ne into other comparisons for vector-scalar instructions (like your patch does), we will end up have:
(eq: (reg) (vec_duplicate ... ) [after this patch] instead of (eq: (vec_duplicate ... ) (reg)) [Before this patch].
So, I think this patch may not be right.
I may be wrong, Robin/Jerff/kito feel free to correct me if I am wrong.
------------------ Original ------------------
From: "demin.han"<demin.han@starfivetech.com<mailto:demin.han@starfivetech.com>>;
Date: Fri, Mar 1, 2024 02:27 PM
To: "gcc-patches"<gcc-patches@gcc.gnu.org<mailto:gcc-patches@gcc.gnu.org>>;
Cc: "juzhe.zhong"<juzhe.zhong@rivai.ai<mailto:juzhe.zhong@rivai.ai>>; "kito.cheng"<kito.cheng@gmail.com<mailto:kito.cheng@gmail.com>>; "Li, Pan2"<pan2.li@intel.com<mailto:pan2.li@intel.com>>; "jeffreyalaw"<jeffreyalaw@gmail.com<mailto:jeffreyalaw@gmail.com>>;
Subject: [PATCH 1/5] RISC-V: Remove float vector eqne pattern
We can unify eqne and other comparison operations.
Tested on RV32 and RV64
gcc/ChangeLog:
* config/riscv/riscv-vector-builtins-bases.cc: Remove eqne cond
* config/riscv/vector.md (@pred_eqne<mode>_scalar): Remove patterns
(*pred_eqne<mode>_scalar_merge_tie_mask): Ditto
(*pred_eqne<mode>_scalar): Ditto
(*pred_eqne<mode>_scalar_narrow): Ditto
Signed-off-by: demin.han <demin.han@starfivetech.com<mailto:demin.han@starfivetech.com>>
---
.../riscv/riscv-vector-builtins-bases.cc | 4 -
gcc/config/riscv/vector.md | 86 -------------------
2 files changed, 90 deletions(-)
diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.cc b/gcc/config/riscv/riscv-vector-builtins-bases.cc
index b6f6e4ff37e..d414721ede8 100644
--- a/gcc/config/riscv/riscv-vector-builtins-bases.cc
+++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc
@@ -1420,10 +1420,6 @@ public:
switch (e.op_info->op)
{
case OP_TYPE_vf: {
- if (CODE == EQ || CODE == NE)
- return e.use_compare_insn (CODE, code_for_pred_eqne_scalar (
- e.vector_mode ()));
- else
return e.use_compare_insn (CODE, code_for_pred_cmp_scalar (
e.vector_mode ()));
}
diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index ab6e099852d..9210d7c28ad 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -7520,92 +7520,6 @@ (define_insn "*pred_cmp<mode>_scalar_narrow"
(set_attr "mode" "<MODE>")
(set_attr "spec_restriction" "none,thv,thv,none,none")])
-(define_expand "@pred_eqne<mode>_scalar"
- [(set (match_operand:<VM> 0 "register_operand")
- (if_then_else:<VM>
- (unspec:<VM>
- [(match_operand:<VM> 1 "vector_mask_operand")
- (match_operand 6 "vector_length_operand")
- (match_operand 7 "const_int_operand")
- (match_operand 8 "const_int_operand")
- (reg:SI VL_REGNUM)
- (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
- (match_operator:<VM> 3 "equality_operator"
- [(vec_duplicate:V_VLSF
- (match_operand:<VEL> 5 "register_operand"))
- (match_operand:V_VLSF 4 "register_operand")])
- (match_operand:<VM> 2 "vector_merge_operand")))]
- "TARGET_VECTOR"
- {})
-
-(define_insn "*pred_eqne<mode>_scalar_merge_tie_mask"
- [(set (match_operand:<VM> 0 "register_operand" "=vm")
- (if_then_else:<VM>
- (unspec:<VM>
- [(match_operand:<VM> 1 "register_operand" " 0")
- (match_operand 5 "vector_length_operand" " rK")
- (match_operand 6 "const_int_operand" " i")
- (match_operand 7 "const_int_operand" " i")
- (reg:SI VL_REGNUM)
- (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
- (match_operator:<VM> 2 "equality_operator"
- [(vec_duplicate:V_VLSF
- (match_operand:<VEL> 4 "register_operand" " f"))
- (match_operand:V_VLSF 3 "register_operand" " vr")])
- (match_dup 1)))]
- "TARGET_VECTOR"
- "vmf%B2.vf\t%0,%3,%4,v0.t"
- [(set_attr "type" "vfcmp")
- (set_attr "mode" "<MODE>")
- (set_attr "merge_op_idx" "1")
- (set_attr "vl_op_idx" "5")
- (set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[6])"))
- (set (attr "avl_type_idx") (const_int 7))])
-
-;; We don't use early-clobber for LMUL <= 1 to get better codegen.
-(define_insn "*pred_eqne<mode>_scalar"
- [(set (match_operand:<VM> 0 "register_operand" "=vr, vr, &vr, &vr")
- (if_then_else:<VM>
- (unspec:<VM>
- [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1,vmWc1,vmWc1,vmWc1")
- (match_operand 6 "vector_length_operand" " rK, rK, rK, rK")
- (match_operand 7 "const_int_operand" " i, i, i, i")
- (match_operand 8 "const_int_operand" " i, i, i, i")
- (reg:SI VL_REGNUM)
- (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
- (match_operator:<VM> 3 "equality_operator"
- [(vec_duplicate:V_VLSF
- (match_operand:<VEL> 5 "register_operand" " f, f, f, f"))
- (match_operand:V_VLSF 4 "register_operand" " vr, vr, vr, vr")])
- (match_operand:<VM> 2 "vector_merge_operand" " vu, 0, vu, 0")))]
- "TARGET_VECTOR && riscv_vector::cmp_lmul_le_one (<MODE>mode)"
- "vmf%B3.vf\t%0,%4,%5%p1"
- [(set_attr "type" "vfcmp")
- (set_attr "mode" "<MODE>")
- (set_attr "spec_restriction" "thv,thv,rvv,rvv")])
-
-;; We use early-clobber for source LMUL > dest LMUL.
-(define_insn "*pred_eqne<mode>_scalar_narrow"
- [(set (match_operand:<VM> 0 "register_operand" "=vm, vr, vr, &vr, &vr")
- (if_then_else:<VM>
- (unspec:<VM>
- [(match_operand:<VM> 1 "vector_mask_operand" " 0,vmWc1,vmWc1,vmWc1,vmWc1")
- (match_operand 6 "vector_length_operand" " rK, rK, rK, rK, rK")
- (match_operand 7 "const_int_operand" " i, i, i, i, i")
- (match_operand 8 "const_int_operand" " i, i, i, i, i")
- (reg:SI VL_REGNUM)
- (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
- (match_operator:<VM> 3 "equality_operator"
- [(vec_duplicate:V_VLSF
- (match_operand:<VEL> 5 "register_operand" " f, f, f, f, f"))
- (match_operand:V_VLSF 4 "register_operand" " vr, 0, 0, vr, vr")])
- (match_operand:<VM> 2 "vector_merge_operand" " vu, vu, 0, vu, 0")))]
- "TARGET_VECTOR && riscv_vector::cmp_lmul_gt_one (<MODE>mode)"
- "vmf%B3.vf\t%0,%4,%5%p1"
- [(set_attr "type" "vfcmp")
- (set_attr "mode" "<MODE>")
- (set_attr "spec_restriction" "none,thv,thv,none,none")])
-
;; -------------------------------------------------------------------------------
;; ---- Predicated floating-point merge
;; -------------------------------------------------------------------------------
--
2.43.2
> 2. When I write if (a == 2) and if (2 == a), the results are
> same
>
> 3. The vec_duplicate operand is the 5th operand in both cmp and
> eqne patterns. I think they are equal.
A comparison with a constant is always canonicalized to have the
constant second, that's why you won't see a difference.
A vector constant follows the same rule because
swap_commutative_operands_p will place it second.
I'm not sure whether we need the vec_duplicate first, honestly.
I don't remember a canonicalization rule that puts it there.
We do have something for constants and vec_merge. As long as
things come from expand I think a constant will always be
second and this patch removes the patterns where the duplicate
is first.
Generally with fast math we could invert the condition so
a comparison should be "commutative". With NaNs I think we
also allow it if the unordered comparisons are supported.
But I'm not even certain that we try something like that with
vectors. On the other hand - as there is no canonical order
nothing would prevent it from being first in the future?
Will need to think about it some more (and try with NaNs) but
we could give try removing the patterns with GCC15 I suppose.
The rest should still be handled in a more generic fashion.
Regards
Robin
@@ -1420,10 +1420,6 @@ public:
switch (e.op_info->op)
{
case OP_TYPE_vf: {
- if (CODE == EQ || CODE == NE)
- return e.use_compare_insn (CODE, code_for_pred_eqne_scalar (
- e.vector_mode ()));
- else
return e.use_compare_insn (CODE, code_for_pred_cmp_scalar (
e.vector_mode ()));
}
@@ -7520,92 +7520,6 @@ (define_insn "*pred_cmp<mode>_scalar_narrow"
(set_attr "mode" "<MODE>")
(set_attr "spec_restriction" "none,thv,thv,none,none")])
-(define_expand "@pred_eqne<mode>_scalar"
- [(set (match_operand:<VM> 0 "register_operand")
- (if_then_else:<VM>
- (unspec:<VM>
- [(match_operand:<VM> 1 "vector_mask_operand")
- (match_operand 6 "vector_length_operand")
- (match_operand 7 "const_int_operand")
- (match_operand 8 "const_int_operand")
- (reg:SI VL_REGNUM)
- (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
- (match_operator:<VM> 3 "equality_operator"
- [(vec_duplicate:V_VLSF
- (match_operand:<VEL> 5 "register_operand"))
- (match_operand:V_VLSF 4 "register_operand")])
- (match_operand:<VM> 2 "vector_merge_operand")))]
- "TARGET_VECTOR"
- {})
-
-(define_insn "*pred_eqne<mode>_scalar_merge_tie_mask"
- [(set (match_operand:<VM> 0 "register_operand" "=vm")
- (if_then_else:<VM>
- (unspec:<VM>
- [(match_operand:<VM> 1 "register_operand" " 0")
- (match_operand 5 "vector_length_operand" " rK")
- (match_operand 6 "const_int_operand" " i")
- (match_operand 7 "const_int_operand" " i")
- (reg:SI VL_REGNUM)
- (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
- (match_operator:<VM> 2 "equality_operator"
- [(vec_duplicate:V_VLSF
- (match_operand:<VEL> 4 "register_operand" " f"))
- (match_operand:V_VLSF 3 "register_operand" " vr")])
- (match_dup 1)))]
- "TARGET_VECTOR"
- "vmf%B2.vf\t%0,%3,%4,v0.t"
- [(set_attr "type" "vfcmp")
- (set_attr "mode" "<MODE>")
- (set_attr "merge_op_idx" "1")
- (set_attr "vl_op_idx" "5")
- (set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[6])"))
- (set (attr "avl_type_idx") (const_int 7))])
-
-;; We don't use early-clobber for LMUL <= 1 to get better codegen.
-(define_insn "*pred_eqne<mode>_scalar"
- [(set (match_operand:<VM> 0 "register_operand" "=vr, vr, &vr, &vr")
- (if_then_else:<VM>
- (unspec:<VM>
- [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1,vmWc1,vmWc1,vmWc1")
- (match_operand 6 "vector_length_operand" " rK, rK, rK, rK")
- (match_operand 7 "const_int_operand" " i, i, i, i")
- (match_operand 8 "const_int_operand" " i, i, i, i")
- (reg:SI VL_REGNUM)
- (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
- (match_operator:<VM> 3 "equality_operator"
- [(vec_duplicate:V_VLSF
- (match_operand:<VEL> 5 "register_operand" " f, f, f, f"))
- (match_operand:V_VLSF 4 "register_operand" " vr, vr, vr, vr")])
- (match_operand:<VM> 2 "vector_merge_operand" " vu, 0, vu, 0")))]
- "TARGET_VECTOR && riscv_vector::cmp_lmul_le_one (<MODE>mode)"
- "vmf%B3.vf\t%0,%4,%5%p1"
- [(set_attr "type" "vfcmp")
- (set_attr "mode" "<MODE>")
- (set_attr "spec_restriction" "thv,thv,rvv,rvv")])
-
-;; We use early-clobber for source LMUL > dest LMUL.
-(define_insn "*pred_eqne<mode>_scalar_narrow"
- [(set (match_operand:<VM> 0 "register_operand" "=vm, vr, vr, &vr, &vr")
- (if_then_else:<VM>
- (unspec:<VM>
- [(match_operand:<VM> 1 "vector_mask_operand" " 0,vmWc1,vmWc1,vmWc1,vmWc1")
- (match_operand 6 "vector_length_operand" " rK, rK, rK, rK, rK")
- (match_operand 7 "const_int_operand" " i, i, i, i, i")
- (match_operand 8 "const_int_operand" " i, i, i, i, i")
- (reg:SI VL_REGNUM)
- (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
- (match_operator:<VM> 3 "equality_operator"
- [(vec_duplicate:V_VLSF
- (match_operand:<VEL> 5 "register_operand" " f, f, f, f, f"))
- (match_operand:V_VLSF 4 "register_operand" " vr, 0, 0, vr, vr")])
- (match_operand:<VM> 2 "vector_merge_operand" " vu, vu, 0, vu, 0")))]
- "TARGET_VECTOR && riscv_vector::cmp_lmul_gt_one (<MODE>mode)"
- "vmf%B3.vf\t%0,%4,%5%p1"
- [(set_attr "type" "vfcmp")
- (set_attr "mode" "<MODE>")
- (set_attr "spec_restriction" "none,thv,thv,none,none")])
-
;; -------------------------------------------------------------------------------
;; ---- Predicated floating-point merge
;; -------------------------------------------------------------------------------