Commit a08acce8 by Richard Henderson Committed by Richard Henderson

aarch64: Add movprfx patterns alternatives

    * config/aarch64/aarch64-protos.h, config/aarch64/aarch64.c
    (aarch64_sve_prepare_conditional_op): Remove.
    * config/aarch64/aarch64-sve.md (cond_<SVE_INT_BINARY><SVE_I>):
    Allow aarch64_simd_reg_or_zero as select operand; remove
    the aarch64_sve_prepare_conditional_op call.
    (cond_<SVE_INT_BINARY_SD><SVE_SDI>): Likewise.
    (cond_<SVE_COND_FP_BINARY><SVE_F>): Likewise.
    (*cond_<SVE_INT_BINARY><SVE_I>_z): New pattern.
    (*cond_<SVE_INT_BINARY_SD><SVE_SDI>_z): New pattern.
    (*cond_<SVE_COND_FP_BINARY><SVE_F>_z): New pattern.
    (*cond_<SVE_INT_BINARY><SVE_I>_any): New pattern.
    (*cond_<SVE_INT_BINARY_SD><SVE_SDI>_any): New pattern.
    (*cond_<SVE_COND_FP_BINARY><SVE_F>_any): New pattern
    and a splitters to match all of the *_any patterns.
    * config/aarch64/predicates.md (aarch64_sve_any_binary_operator): New.

    * config/aarch64/iterators.md (SVE_INT_BINARY_REV): Remove.
    (SVE_COND_FP_BINARY_REV): Remove.
    (sve_int_op_rev, sve_fp_op_rev): New.
    * config/aarch64/aarch64-sve.md (*cond_<SVE_INT_BINARY><SVE_I>_0): New.
    (*cond_<SVE_INT_BINARY_SD><SVE_SDI>_0): New.
    (*cond_<SVE_COND_FP_BINARY><SVE_F>_0): New.
    (*cond_<SVE_INT_BINARY><SVE_I>_2): Rename, add movprfx alternative.
    (*cond_<SVE_INT_BINARY_SD><SVE_SDI>_2): Similarly.
    (*cond_<SVE_COND_FP_BINARY><SVE_F>_2): Similarly.
    (*cond_<SVE_INT_BINARY><SVE_I>_3): Similarly; use sve_int_op_rev.
    (*cond_<SVE_INT_BINARY_SD><SVE_SDI>_3): Similarly.
    (*cond_<SVE_COND_FP_BINARY><SVE_F>_3): Similarly; use sve_fp_op_rev.

    * config/aarch64/aarch64-sve.md (cond_<SVE_COND_FP_BINARY><SVE_F>):
    Remove match_dup 1 from the inner unspec.
    (*cond_<SVE_COND_FP_BINARY><SVE_F>): Likewise.

    * config/aarch64/aarch64.md (movprfx): New attr.
    (length): Default movprfx to 8.
    * config/aarch64/aarch64-sve.md (*mul<SVE_I>3): Add movprfx alt.
    (*madd<SVE_I>, *msub<SVE_I): Likewise.
    (*<su>mul<SVE_I>3_highpart): Likewise.
    (*<SVE_INT_BINARY_SD><SVE_SDI>3): Likewise.
    (*v<ASHIFT><SVE_I>3): Likewise.
    (*<su><MAXMIN><SVE_I>3): Likewise.
    (*<su><MAXMIN><SVE_F>3): Likewise.
    (*fma<SVE_F>4, *fnma<SVE_F>4): Likewise.
    (*fms<SVE_F>4, *fnms<SVE_F>4): Likewise.
    (*div<SVE_F>4): Likewise.

From-SVN: r262312
parent 1234faf4
2018-07-02 Richard Henderson <richard.henderson@linaro.org>
* config/aarch64/aarch64-protos.h, config/aarch64/aarch64.c
(aarch64_sve_prepare_conditional_op): Remove.
* config/aarch64/aarch64-sve.md (cond_<SVE_INT_BINARY><SVE_I>):
Allow aarch64_simd_reg_or_zero as select operand; remove
the aarch64_sve_prepare_conditional_op call.
(cond_<SVE_INT_BINARY_SD><SVE_SDI>): Likewise.
(cond_<SVE_COND_FP_BINARY><SVE_F>): Likewise.
(*cond_<SVE_INT_BINARY><SVE_I>_z): New pattern.
(*cond_<SVE_INT_BINARY_SD><SVE_SDI>_z): New pattern.
(*cond_<SVE_COND_FP_BINARY><SVE_F>_z): New pattern.
(*cond_<SVE_INT_BINARY><SVE_I>_any): New pattern.
(*cond_<SVE_INT_BINARY_SD><SVE_SDI>_any): New pattern.
(*cond_<SVE_COND_FP_BINARY><SVE_F>_any): New pattern
and a splitters to match all of the *_any patterns.
* config/aarch64/predicates.md (aarch64_sve_any_binary_operator): New.
* config/aarch64/iterators.md (SVE_INT_BINARY_REV): Remove.
(SVE_COND_FP_BINARY_REV): Remove.
(sve_int_op_rev, sve_fp_op_rev): New.
* config/aarch64/aarch64-sve.md (*cond_<SVE_INT_BINARY><SVE_I>_0): New.
(*cond_<SVE_INT_BINARY_SD><SVE_SDI>_0): New.
(*cond_<SVE_COND_FP_BINARY><SVE_F>_0): New.
(*cond_<SVE_INT_BINARY><SVE_I>_2): Rename, add movprfx alternative.
(*cond_<SVE_INT_BINARY_SD><SVE_SDI>_2): Similarly.
(*cond_<SVE_COND_FP_BINARY><SVE_F>_2): Similarly.
(*cond_<SVE_INT_BINARY><SVE_I>_3): Similarly; use sve_int_op_rev.
(*cond_<SVE_INT_BINARY_SD><SVE_SDI>_3): Similarly.
(*cond_<SVE_COND_FP_BINARY><SVE_F>_3): Similarly; use sve_fp_op_rev.
* config/aarch64/aarch64-sve.md (cond_<SVE_COND_FP_BINARY><SVE_F>):
Remove match_dup 1 from the inner unspec.
(*cond_<SVE_COND_FP_BINARY><SVE_F>): Likewise.
* config/aarch64/aarch64.md (movprfx): New attr.
(length): Default movprfx to 8.
* config/aarch64/aarch64-sve.md (*mul<SVE_I>3): Add movprfx alt.
(*madd<SVE_I>, *msub<SVE_I): Likewise.
(*<su>mul<SVE_I>3_highpart): Likewise.
(*<SVE_INT_BINARY_SD><SVE_SDI>3): Likewise.
(*v<ASHIFT><SVE_I>3): Likewise.
(*<su><MAXMIN><SVE_I>3): Likewise.
(*<su><MAXMIN><SVE_F>3): Likewise.
(*fma<SVE_F>4, *fnma<SVE_F>4): Likewise.
(*fms<SVE_F>4, *fnms<SVE_F>4): Likewise.
(*div<SVE_F>4): Likewise.
2018-07-02 Richard Sandiford <richard.sandiford@arm.com> 2018-07-02 Richard Sandiford <richard.sandiford@arm.com>
* tree-vect-patterns.c (vect_recog_widen_shift_pattern): Fix typo * tree-vect-patterns.c (vect_recog_widen_shift_pattern): Fix typo
......
...@@ -513,7 +513,6 @@ bool aarch64_gen_adjusted_ldpstp (rtx *, bool, scalar_mode, RTX_CODE); ...@@ -513,7 +513,6 @@ bool aarch64_gen_adjusted_ldpstp (rtx *, bool, scalar_mode, RTX_CODE);
void aarch64_expand_sve_vec_cmp_int (rtx, rtx_code, rtx, rtx); void aarch64_expand_sve_vec_cmp_int (rtx, rtx_code, rtx, rtx);
bool aarch64_expand_sve_vec_cmp_float (rtx, rtx_code, rtx, rtx, bool); bool aarch64_expand_sve_vec_cmp_float (rtx, rtx_code, rtx, rtx, bool);
void aarch64_expand_sve_vcond (machine_mode, machine_mode, rtx *); void aarch64_expand_sve_vcond (machine_mode, machine_mode, rtx *);
void aarch64_sve_prepare_conditional_op (rtx *, unsigned int, bool);
#endif /* RTX_CODE */ #endif /* RTX_CODE */
void aarch64_init_builtins (void); void aarch64_init_builtins (void);
......
...@@ -16058,54 +16058,6 @@ aarch64_expand_sve_vcond (machine_mode data_mode, machine_mode cmp_mode, ...@@ -16058,54 +16058,6 @@ aarch64_expand_sve_vcond (machine_mode data_mode, machine_mode cmp_mode,
emit_set_insn (ops[0], gen_rtx_UNSPEC (data_mode, vec, UNSPEC_SEL)); emit_set_insn (ops[0], gen_rtx_UNSPEC (data_mode, vec, UNSPEC_SEL));
} }
/* Prepare a cond_<optab><mode> operation that has the operands
given by OPERANDS, where:
- operand 0 is the destination
- operand 1 is a predicate
- operands 2 to NOPS - 2 are the operands to an operation that is
performed for active lanes
- operand NOPS - 1 specifies the values to use for inactive lanes.
COMMUTATIVE_P is true if operands 2 and 3 are commutative. In that case,
no pattern is provided for a tie between operands 3 and NOPS - 1. */
void
aarch64_sve_prepare_conditional_op (rtx *operands, unsigned int nops,
bool commutative_p)
{
/* We can do the operation directly if the "else" value matches one
of the other inputs. */
for (unsigned int i = 2; i < nops - 1; ++i)
if (rtx_equal_p (operands[i], operands[nops - 1]))
{
if (i == 3 && commutative_p)
std::swap (operands[2], operands[3]);
return;
}
/* If the "else" value is different from the other operands, we have
the choice of doing a SEL on the output or a SEL on an input.
Neither choice is better in all cases, but one advantage of
selecting the input is that it can avoid a move when the output
needs to be distinct from the inputs. E.g. if operand N maps to
register N, selecting the output would give:
MOVPRFX Z0.S, Z2.S
ADD Z0.S, P1/M, Z0.S, Z3.S
SEL Z0.S, P1, Z0.S, Z4.S
whereas selecting the input avoids the MOVPRFX:
SEL Z0.S, P1, Z2.S, Z4.S
ADD Z0.S, P1/M, Z0.S, Z3.S. */
machine_mode mode = GET_MODE (operands[0]);
rtx temp = gen_reg_rtx (mode);
rtvec vec = gen_rtvec (3, operands[1], operands[2], operands[nops - 1]);
emit_set_insn (temp, gen_rtx_UNSPEC (mode, vec, UNSPEC_SEL));
operands[2] = operands[nops - 1] = temp;
}
/* Implement TARGET_MODES_TIEABLE_P. In principle we should always return /* Implement TARGET_MODES_TIEABLE_P. In principle we should always return
true. However due to issues with register allocation it is preferable true. However due to issues with register allocation it is preferable
to avoid tieing integer scalar and FP scalar modes. Executing integer to avoid tieing integer scalar and FP scalar modes. Executing integer
......
...@@ -251,9 +251,6 @@ ...@@ -251,9 +251,6 @@
;; will be disabled when !TARGET_SVE. ;; will be disabled when !TARGET_SVE.
(define_attr "sve" "no,yes" (const_string "no")) (define_attr "sve" "no,yes" (const_string "no"))
(define_attr "length" ""
(const_int 4))
;; Attribute that controls whether an alternative is enabled or not. ;; Attribute that controls whether an alternative is enabled or not.
;; Currently it is only used to disable alternatives which touch fp or simd ;; Currently it is only used to disable alternatives which touch fp or simd
;; registers when -mgeneral-regs-only is specified. ;; registers when -mgeneral-regs-only is specified.
...@@ -277,6 +274,14 @@ ...@@ -277,6 +274,14 @@
;; 1 :=: yes ;; 1 :=: yes
(define_attr "far_branch" "" (const_int 0)) (define_attr "far_branch" "" (const_int 0))
;; Attribute that specifies whether the alternative uses MOVPRFX.
(define_attr "movprfx" "no,yes" (const_string "no"))
(define_attr "length" ""
(cond [(eq_attr "movprfx" "yes")
(const_int 8)
] (const_int 4)))
;; Strictly for compatibility with AArch32 in pipeline models, since AArch64 has ;; Strictly for compatibility with AArch32 in pipeline models, since AArch64 has
;; no predicated insns. ;; no predicated insns.
(define_attr "predicated" "yes,no" (const_string "no")) (define_attr "predicated" "yes,no" (const_string "no"))
......
...@@ -1207,11 +1207,11 @@ ...@@ -1207,11 +1207,11 @@
;; SVE floating-point unary operations. ;; SVE floating-point unary operations.
(define_code_iterator SVE_FP_UNARY [neg abs sqrt]) (define_code_iterator SVE_FP_UNARY [neg abs sqrt])
;; SVE integer binary operations.
(define_code_iterator SVE_INT_BINARY [plus minus mult smax umax smin umin (define_code_iterator SVE_INT_BINARY [plus minus mult smax umax smin umin
and ior xor]) and ior xor])
(define_code_iterator SVE_INT_BINARY_REV [minus]) ;; SVE integer binary division operations.
(define_code_iterator SVE_INT_BINARY_SD [div udiv]) (define_code_iterator SVE_INT_BINARY_SD [div udiv])
;; SVE integer comparisons. ;; SVE integer comparisons.
...@@ -1402,6 +1402,19 @@ ...@@ -1402,6 +1402,19 @@
(not "not") (not "not")
(popcount "cnt")]) (popcount "cnt")])
(define_code_attr sve_int_op_rev [(plus "add")
(minus "subr")
(mult "mul")
(div "sdivr")
(udiv "udivr")
(smin "smin")
(smax "smax")
(umin "umin")
(umax "umax")
(and "and")
(ior "orr")
(xor "eor")])
;; The floating-point SVE instruction that implements an rtx code. ;; The floating-point SVE instruction that implements an rtx code.
(define_code_attr sve_fp_op [(plus "fadd") (define_code_attr sve_fp_op [(plus "fadd")
(neg "fneg") (neg "fneg")
...@@ -1550,8 +1563,6 @@ ...@@ -1550,8 +1563,6 @@
UNSPEC_COND_MUL UNSPEC_COND_DIV UNSPEC_COND_MUL UNSPEC_COND_DIV
UNSPEC_COND_MAX UNSPEC_COND_MIN]) UNSPEC_COND_MAX UNSPEC_COND_MIN])
(define_int_iterator SVE_COND_FP_BINARY_REV [UNSPEC_COND_SUB UNSPEC_COND_DIV])
(define_int_iterator SVE_COND_FP_CMP [UNSPEC_COND_LT UNSPEC_COND_LE (define_int_iterator SVE_COND_FP_CMP [UNSPEC_COND_LT UNSPEC_COND_LE
UNSPEC_COND_EQ UNSPEC_COND_NE UNSPEC_COND_EQ UNSPEC_COND_NE
UNSPEC_COND_GE UNSPEC_COND_GT]) UNSPEC_COND_GE UNSPEC_COND_GT])
...@@ -1802,6 +1813,13 @@ ...@@ -1802,6 +1813,13 @@
(UNSPEC_COND_MAX "fmaxnm") (UNSPEC_COND_MAX "fmaxnm")
(UNSPEC_COND_MIN "fminnm")]) (UNSPEC_COND_MIN "fminnm")])
(define_int_attr sve_fp_op_rev [(UNSPEC_COND_ADD "fadd")
(UNSPEC_COND_SUB "fsubr")
(UNSPEC_COND_MUL "fmul")
(UNSPEC_COND_DIV "fdivr")
(UNSPEC_COND_MAX "fmaxnm")
(UNSPEC_COND_MIN "fminnm")])
(define_int_attr commutative [(UNSPEC_COND_ADD "true") (define_int_attr commutative [(UNSPEC_COND_ADD "true")
(UNSPEC_COND_SUB "false") (UNSPEC_COND_SUB "false")
(UNSPEC_COND_MUL "true") (UNSPEC_COND_MUL "true")
......
...@@ -625,3 +625,6 @@ ...@@ -625,3 +625,6 @@
;; A special predicate that doesn't match a particular mode. ;; A special predicate that doesn't match a particular mode.
(define_special_predicate "aarch64_any_register_operand" (define_special_predicate "aarch64_any_register_operand"
(match_code "reg")) (match_code "reg"))
(define_predicate "aarch64_sve_any_binary_operator"
(match_code "plus,minus,mult,div,udiv,smax,umax,smin,umin,and,ior,xor"))
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment