diff options
author | Richard Sandiford <richard.sandiford@arm.com> | 2019-08-15 08:37:14 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2019-08-15 08:37:14 +0000 |
commit | 06b3ba23eb6ff965a92cd99d2835d4c29316a447 (patch) | |
tree | 318b8d020e52354c789c169d538ca72cfdc781a6 /gcc/config | |
parent | 2ae21bd133c357fcd7b6e06dc7d7d9e0660abe2c (diff) | |
download | gcc-06b3ba23eb6ff965a92cd99d2835d4c29316a447.zip gcc-06b3ba23eb6ff965a92cd99d2835d4c29316a447.tar.gz gcc-06b3ba23eb6ff965a92cd99d2835d4c29316a447.tar.bz2 |
[AArch64] Add MOVPRFX alternatives for SVE EXT patterns
We use EXT both to implement vec_extract for large indices and as a
permute. In both cases we can use MOVPRFX to handle the case in which
the first input and output can't be tied.
2019-08-15 Richard Sandiford <richard.sandiford@arm.com>
gcc/
* config/aarch64/aarch64-sve.md (*vec_extract<mode><Vel>_ext)
(*aarch64_sve_ext<mode>): Add MOVPRFX alternatives.
gcc/testsuite/
* gcc.target/aarch64/sve/ext_2.c: Expect a MOVPRFX.
* gcc.target/aarch64/sve/ext_3.c: New test.
From-SVN: r274515
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/aarch64/aarch64-sve.md | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/gcc/config/aarch64/aarch64-sve.md b/gcc/config/aarch64/aarch64-sve.md index fa7f899..9007a79 100644 --- a/gcc/config/aarch64/aarch64-sve.md +++ b/gcc/config/aarch64/aarch64-sve.md @@ -1356,16 +1356,19 @@ ;; Extract an element outside the range of DUP. This pattern requires the ;; source and destination to be the same. (define_insn "*vec_extract<mode><Vel>_ext" - [(set (match_operand:<VEL> 0 "register_operand" "=w") + [(set (match_operand:<VEL> 0 "register_operand" "=w, ?&w") (vec_select:<VEL> - (match_operand:SVE_ALL 1 "register_operand" "0") + (match_operand:SVE_ALL 1 "register_operand" "0, w") (parallel [(match_operand:SI 2 "const_int_operand")])))] "TARGET_SVE && INTVAL (operands[2]) * GET_MODE_SIZE (<VEL>mode) >= 64" { operands[0] = gen_rtx_REG (<MODE>mode, REGNO (operands[0])); operands[2] = GEN_INT (INTVAL (operands[2]) * GET_MODE_SIZE (<VEL>mode)); - return "ext\t%0.b, %0.b, %0.b, #%2"; + return (which_alternative == 0 + ? "ext\t%0.b, %0.b, %0.b, #%2" + : "movprfx\t%0, %1\;ext\t%0.b, %0.b, %1.b, #%2"); } + [(set_attr "movprfx" "*,yes")] ) ;; ------------------------------------------------------------------------- @@ -4700,17 +4703,20 @@ ;; Concatenate two vectors and extract a subvector. Note that the ;; immediate (third) operand is the lane index not the byte index. (define_insn "*aarch64_sve_ext<mode>" - [(set (match_operand:SVE_ALL 0 "register_operand" "=w") - (unspec:SVE_ALL [(match_operand:SVE_ALL 1 "register_operand" "0") - (match_operand:SVE_ALL 2 "register_operand" "w") + [(set (match_operand:SVE_ALL 0 "register_operand" "=w, ?&w") + (unspec:SVE_ALL [(match_operand:SVE_ALL 1 "register_operand" "0, w") + (match_operand:SVE_ALL 2 "register_operand" "w, w") (match_operand:SI 3 "const_int_operand")] UNSPEC_EXT))] "TARGET_SVE && IN_RANGE (INTVAL (operands[3]) * GET_MODE_SIZE (<VEL>mode), 0, 255)" { operands[3] = GEN_INT (INTVAL (operands[3]) * GET_MODE_SIZE (<VEL>mode)); - return "ext\\t%0.b, %0.b, %2.b, #%3"; + return (which_alternative == 0 + ? "ext\\t%0.b, %0.b, %2.b, #%3" + : "movprfx\t%0, %1\;ext\\t%0.b, %0.b, %2.b, #%3"); } + [(set_attr "movprfx" "*,yes")] ) ;; ------------------------------------------------------------------------- |