From: Pan Li <[email protected]>
According to the RVV 1.0 spec, the widening ops like vzext.vf2
could have the source registers overlap on constraint, aka:
`
The destination EEW is greater than the source EEW, the source
EMUL is at least 1, and the overlap is in the highest-
numbered part of the destination register group.
`
This PATCH could like to re-enable it start from vzext.vf2 for
lmul m2.
gcc/ChangeLog:
* config/riscv/constraints.md (TARGET_VECTOR ? V_REGS : NO_REGS):
Add reg constraint wo21 and wo22.
* config/riscv/riscv-protos.h (widening_valid_reg_group_p): Add
new func decl to predicate valid overlap or not.
* config/riscv/riscv-v.cc (widening_valid_reg_group_p): Add new
func impl to predicate valid overlap or not.
* config/riscv/riscv.md (none,wo21): Add new attr for reg
overlap insns.
* config/riscv/vector.md: Add 2 new alternative for m2 reg
overlap for v[sz]ext.vf2.
Signed-off-by: Pan Li <[email protected]>
---
gcc/config/riscv/constraints.md | 34 +++++++++++++++++++++++++++++++++
gcc/config/riscv/riscv-protos.h | 1 +
gcc/config/riscv/riscv-v.cc | 18 +++++++++++++++++
gcc/config/riscv/riscv.md | 3 +++
gcc/config/riscv/vector.md | 24 ++++++++++++++---------
5 files changed, 71 insertions(+), 9 deletions(-)
diff --git a/gcc/config/riscv/constraints.md b/gcc/config/riscv/constraints.md
index 673b05954e1..82680d85121 100644
--- a/gcc/config/riscv/constraints.md
+++ b/gcc/config/riscv/constraints.md
@@ -344,3 +344,37 @@ (define_constraint "ads_Bext"
"Sequence bit extract."
(and (match_code "const_int")
(match_test "(ival & (ival + 1)) == 0")))
+
+;; The RVV widening constraints for register overlap, aka dest EEW > src EEW.
+;; Quote from RVV spec 1.0:
+;;
+;; The destination EEW is greater than the source EEW, the source EMUL is at
+;; least 1, and the overlap is in the highest-numbered part of the destination
+;; register group (e.g., when LMUL=8, vzext.vf4 v0, v6 is legal, but a source
+;; of v0, v2, or v4 is not).
+;;
+;; Take vzext.vfN for example, only below cases are valid.
+;; Source EMUL = LMUL * (Source EEW / SEW) = LMUL * SEW / (N * SEW) = LMUL / N
+;;
+;; +-----------+------------+------------+----------+
+;; | | LMUL = 8 | LMUL = 4 | LMUL = 2 |
+;; +-----------+------------+------------+----------+
+;; | vzext.vf2 | EMUL = 4 | EMUL = 2 | EMUL = 1 |
+;; +-----------+------------+------------+----------+
+;; | | v0-7, v4-7 | v0-3, v2-3 | v0-1, v1 |
+;; +-----------+------------+------------+----------+
+;; | vzext.vf4 | EMUL = 2 | EMUL = 1 | |
+;; +-----------+------------+------------+----------+
+;; | | v0-7, v6-7 | v0-3, v3 | |
+;; +-----------+------------+------------+----------+
+;; | vzext.vf8 | EMUL = 1 | | |
+;; +-----------+------------+------------+----------+
+;; | | v0-7, v7 | | |
+;; +-----------+------------+------------+----------+
+;;
+(define_register_constraint "wo21" "TARGET_VECTOR ? V_REGS : NO_REGS"
+ "A constraint matches the reg group overlap with highest 1 num in 2 regs."
+ "(regno % 2) == 1")
+(define_register_constraint "wo22" "TARGET_VECTOR ? V_REGS : NO_REGS"
+ "A constraint matches the reg group overlap in 2 regs."
+ "(regno % 2) == 0")
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index 0734c31ec56..ef8d12f1559 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -791,6 +791,7 @@ bool gather_scatter_valid_offset_p (machine_mode);
HOST_WIDE_INT estimated_poly_value (poly_int64, unsigned int);
bool whole_reg_to_reg_move_p (rtx *, machine_mode, int);
bool splat_to_scalar_move_p (rtx *);
+bool widening_valid_reg_group_p (rtx_insn *, rtx);
rtx get_fp_rounding_coefficient (machine_mode);
}
diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
index 29dc3ebccd6..60431d08135 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -6455,4 +6455,22 @@ splat_to_scalar_move_p (rtx *ops)
&& known_ge (GET_MODE_SIZE (Pmode), GET_MODE_SIZE (GET_MODE (ops[3])));
}
+bool
+widening_valid_reg_group_p (rtx_insn *insn, rtx op_0)
+{
+ attr_reg_group_overlap overlap = get_attr_reg_group_overlap (insn);
+
+ switch (overlap)
+ {
+ case REG_GROUP_OVERLAP_NONE:
+ return true;
+ case REG_GROUP_OVERLAP_WO21:
+ return riscv_get_v_regno_alignment (GET_MODE (op_0)) == 2;
+ default:
+ break;
+ }
+
+ return false;
+}
+
} // namespace riscv_vector
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 3fe0ad0ccdf..53790d1c9c4 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -593,6 +593,9 @@ (define_attr "spec_restriction_disabled" "no,yes"
]
(const_string "no")))
+(define_attr "reg_group_overlap" "none,wo21"
+ (const_string "none"))
+
;; Attribute to control enable or disable instructions.
(define_attr "enabled" "no,yes"
(cond [
diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index 219ecdac68b..8f53745a2dc 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -4035,23 +4035,29 @@ (define_insn "@pred_<optab><mode>"
;; Vector Double-Widening Sign-extend and Zero-extend.
(define_insn "@pred_<optab><mode>_vf2"
- [(set (match_operand:VWEXTI 0 "register_operand" "=&vr,&vr")
+ [(set (match_operand:VWEXTI 0 "register_operand" "=wo22, wo22,
?&vr, ?&vr")
(if_then_else:VWEXTI
(unspec:<VM>
- [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1,vmWc1")
- (match_operand 4 "vector_length_operand" " rvl, rvl")
- (match_operand 5 "const_int_operand" " i, i")
- (match_operand 6 "const_int_operand" " i, i")
- (match_operand 7 "const_int_operand" " i, i")
+ [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1, vmWc1,
vmWc1, vmWc1")
+ (match_operand 4 "vector_length_operand" " rvl, rvl,
rvl, rvl")
+ (match_operand 5 "const_int_operand" " i, i,
i, i")
+ (match_operand 6 "const_int_operand" " i, i,
i, i")
+ (match_operand 7 "const_int_operand" " i, i,
i, i")
(reg:SI VL_REGNUM)
(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
(any_extend:VWEXTI
- (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand" " vr, vr"))
- (match_operand:VWEXTI 2 "vector_merge_operand" " vu,
0")))]
+ (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand" " wo21, wo21,
vr, vr"))
+ (match_operand:VWEXTI 2 "vector_merge_operand" " vu, 0,
vu, 0")))]
"TARGET_VECTOR && !TARGET_XTHEADVECTOR"
"v<sz>ext.vf2\t%0,%3%p1"
[(set_attr "type" "vext")
- (set_attr "mode" "<MODE>")])
+ (set_attr "mode" "<MODE>")
+ (set_attr "reg_group_overlap" "wo21,wo21,none,none")
+ (set (attr "enabled")
+ (if_then_else
+ (match_test "riscv_vector::widening_valid_reg_group_p (insn,
operands[0])")
+ (const_string "yes")
+ (const_string "no")))])
;; Vector Quad-Widening Sign-extend and Zero-extend.
(define_insn "@pred_<optab><mode>_vf4"
--
2.43.0