aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/aarch64/predicates.md
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2018-02-01 11:04:28 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2018-02-01 11:04:28 +0000
commit002092be4027b1fd667178e9bbe99fa6ecee2e10 (patch)
treee5e9f2d690b39be0b02462b747c0a8c2b3cf6740 /gcc/config/aarch64/predicates.md
parent8179efe00e04285184112de7dbb977a75852197c (diff)
downloadgcc-002092be4027b1fd667178e9bbe99fa6ecee2e10.zip
gcc-002092be4027b1fd667178e9bbe99fa6ecee2e10.tar.gz
gcc-002092be4027b1fd667178e9bbe99fa6ecee2e10.tar.bz2
[AArch64] Handle SVE subregs that are effectively REVs
Subreg reads should be equivalent to storing the inner register to memory and loading the appropriate memory bytes back, with subreg writes doing the reverse. For the reasons explained in the comments, this isn't what happens for big-endian SVE if we simply reinterpret one vector register as having a different element size, so the conceptual store and load is needed in the general case. However, that obviously produces poor code if we do it too often. The patch therefore adds a pattern for handling the operation in registers. This copes with the important case of a VIEW_CONVERT created by tree-vect-slp.c:duplicate_and_interleave. It might make sense to tighten the predicates in aarch64-sve.md so that such subregs are not allowed as operands to most instructions, but that's future work. This fixes the sve/slp_*.c tests on aarch64_be. 2018-02-01 Richard Sandiford <richard.sandiford@linaro.org> gcc/ * config/aarch64/aarch64-protos.h (aarch64_split_sve_subreg_move) (aarch64_maybe_expand_sve_subreg_move): Declare. * config/aarch64/aarch64.md (UNSPEC_REV_SUBREG): New unspec. * config/aarch64/predicates.md (aarch64_any_register_operand): New predicate. * config/aarch64/aarch64-sve.md (mov<mode>): Optimize subreg moves that are semantically a reverse operation. (*aarch64_sve_mov<mode>_subreg_be): New pattern. * config/aarch64/aarch64.c (aarch64_maybe_expand_sve_subreg_move): (aarch64_replace_reg_mode, aarch64_split_sve_subreg_move): New functions. (aarch64_can_change_mode_class): For big-endian, forbid changes between two SVE modes if they have different element sizes. Reviewed-by: James Greenhalgh <james.greenhalgh@arm.com> From-SVN: r257289
Diffstat (limited to 'gcc/config/aarch64/predicates.md')
-rw-r--r--gcc/config/aarch64/predicates.md4
1 files changed, 4 insertions, 0 deletions
diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md
index 159e74a..804be16 100644
--- a/gcc/config/aarch64/predicates.md
+++ b/gcc/config/aarch64/predicates.md
@@ -617,3 +617,7 @@
(define_predicate "aarch64_gather_scale_operand_d"
(and (match_code "const_int")
(match_test "INTVAL (op) == 1 || INTVAL (op) == 8")))
+
+;; A special predicate that doesn't match a particular mode.
+(define_special_predicate "aarch64_any_register_operand"
+ (match_code "reg"))