aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilco Dijkstra <wilco.dijkstra@arm.com>2024-10-08 15:55:25 +0000
committerWilco Dijkstra <wilco.dijkstra@arm.com>2024-10-23 12:45:10 +0000
commit756890d66cf4971fc11187ccdf5893681aa661a1 (patch)
tree4777775c5b8a173f3baee31769d78624e55c5c81
parentbcbf4fa46ae2919cf281322bd39f4810b7c18c9d (diff)
downloadgcc-756890d66cf4971fc11187ccdf5893681aa661a1.zip
gcc-756890d66cf4971fc11187ccdf5893681aa661a1.tar.gz
gcc-756890d66cf4971fc11187ccdf5893681aa661a1.tar.bz2
AArch64: Improve SIMD immediate generation (2/3)
Allow use of SVE immediates when generating AdvSIMD code and SVE is available. First check for a valid AdvSIMD immediate, and if SVE is available, try using an SVE move or bitmask immediate. gcc/ChangeLog: * config/aarch64/aarch64-simd.md (ior<mode>3<vczle><vczbe>): Use aarch64_reg_or_orr_imm predicate. Combine SVE/AdvSIMD immediates and use aarch64_output_simd_orr_imm. * config/aarch64/aarch64.cc (struct simd_immediate_info): Add SVE_MOV. (aarch64_sve_valid_immediate): Use SVE_MOV for SVE move immediates. (aarch64_simd_valid_imm): Enable SVE SIMD immediates when possible. (aarch64_output_simd_imm): Support emitting SVE SIMD immediates. * config/aarch64/predicates.md (aarch64_orr_imm_sve_advsimd): Remove. gcc/testsuite/ChangeLog: * gcc.target/aarch64/sve/acle/asm/insr_s64.c: Allow SVE MOV imm. * gcc.target/aarch64/sve/acle/asm/insr_u64.c: Likewise. * gcc.target/aarch64/sve/fneg-abs_1.c: Update to check for ORRI. * gcc.target/aarch64/sve/fneg-abs_2.c: Likewise. * gcc.target/aarch64/sve/simd_imm_mov.c: New test.
-rw-r--r--gcc/config/aarch64/aarch64-simd.md10
-rw-r--r--gcc/config/aarch64/aarch64.cc41
-rw-r--r--gcc/config/aarch64/predicates.md5
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/insr_s64.c4
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/insr_u64.c4
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/fneg-abs_1.c6
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/fneg-abs_2.c4
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/simd_imm_mov.c39
8 files changed, 85 insertions, 28 deletions
diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md
index b031b52..bf48634 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -1135,13 +1135,11 @@
(define_insn "ior<mode>3<vczle><vczbe>"
[(set (match_operand:VDQ_I 0 "register_operand")
(ior:VDQ_I (match_operand:VDQ_I 1 "register_operand")
- (match_operand:VDQ_I 2 "aarch64_orr_imm_sve_advsimd")))]
+ (match_operand:VDQ_I 2 "aarch64_reg_or_orr_imm")))]
"TARGET_SIMD"
- {@ [ cons: =0 , 1 , 2; attrs: arch ]
- [ w , w , w ; simd ] orr\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>
- [ w , 0 , vsl; sve ] orr\t%Z0.<Vetype>, %Z0.<Vetype>, #%2
- [ w , 0 , Do ; simd ] \
- << aarch64_output_simd_orr_imm (operands[2], <bitsize>);
+ {@ [ cons: =0 , 1 , 2 ]
+ [ w , w , w ] orr\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>
+ [ w , 0 , Do ] << aarch64_output_simd_orr_imm (operands[2], <bitsize>);
}
[(set_attr "type" "neon_logic<q>")]
)
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 4db224f..614f99e 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -140,7 +140,7 @@ enum simd_immediate_check {
/* Information about a legitimate vector immediate operand. */
struct simd_immediate_info
{
- enum insn_type { MOV, MVN, INDEX, PTRUE };
+ enum insn_type { MOV, MVN, INDEX, PTRUE, SVE_MOV };
enum modifier_type { LSL, MSL };
simd_immediate_info () {}
@@ -22982,14 +22982,16 @@ aarch64_sve_valid_immediate (unsigned HOST_WIDE_INT ival, scalar_int_mode mode,
{
/* DUP with no shift. */
if (info)
- *info = simd_immediate_info (mode, val);
+ *info = simd_immediate_info (mode, val,
+ simd_immediate_info::SVE_MOV);
return true;
}
if ((val & 0xff) == 0 && IN_RANGE (val, -0x8000, 0x7f00))
{
/* DUP with LSL #8. */
if (info)
- *info = simd_immediate_info (mode, val);
+ *info = simd_immediate_info (mode, val,
+ simd_immediate_info::SVE_MOV);
return true;
}
}
@@ -22997,7 +22999,7 @@ aarch64_sve_valid_immediate (unsigned HOST_WIDE_INT ival, scalar_int_mode mode,
{
/* DUPM. */
if (info)
- *info = simd_immediate_info (mode, val);
+ *info = simd_immediate_info (mode, val, simd_immediate_info::SVE_MOV);
return true;
}
return false;
@@ -23322,8 +23324,13 @@ aarch64_simd_valid_imm (rtx op, simd_immediate_info *info,
if (vec_flags & VEC_SVE_DATA)
return aarch64_sve_valid_immediate (ival, imode, info, which);
- else
- return aarch64_advsimd_valid_immediate (val64, imode, info, which);
+
+ if (aarch64_advsimd_valid_immediate (val64, imode, info, which))
+ return true;
+
+ if (TARGET_SVE)
+ return aarch64_sve_valid_immediate (ival, imode, info, which);
+ return false;
}
/* Return true if OP is a valid SIMD move immediate for SVE or AdvSIMD. */
@@ -25427,6 +25434,14 @@ aarch64_output_simd_imm (rtx const_vector, unsigned width,
return templ;
}
+ if (info.insn == simd_immediate_info::SVE_MOV)
+ {
+ gcc_assert (TARGET_SVE);
+ snprintf (templ, sizeof (templ), "mov\t%%Z0.%c, #" HOST_WIDE_INT_PRINT_DEC,
+ element_char, INTVAL (info.u.mov.value));
+ return templ;
+ }
+
mnemonic = info.insn == simd_immediate_info::MVN ? "mvni" : "movi";
shift_op = (info.u.mov.modifier == simd_immediate_info::MSL
? "msl" : "lsl");
@@ -25446,8 +25461,18 @@ aarch64_output_simd_imm (rtx const_vector, unsigned width,
else
{
/* AARCH64_CHECK_ORR or AARCH64_CHECK_AND. */
- mnemonic = info.insn == simd_immediate_info::MVN ? "bic" : "orr";
- if (info.u.mov.shift)
+ mnemonic = "orr";
+ if (which == AARCH64_CHECK_AND)
+ mnemonic = info.insn == simd_immediate_info::MVN ? "bic" : "and";
+
+ if (info.insn == simd_immediate_info::SVE_MOV)
+ {
+ gcc_assert (TARGET_SVE);
+ snprintf (templ, sizeof (templ), "%s\t%%Z0.%c, %%Z0.%c, "
+ HOST_WIDE_INT_PRINT_DEC, mnemonic, element_char,
+ element_char, INTVAL (info.u.mov.value));
+ }
+ else if (info.u.mov.shift)
snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, #"
HOST_WIDE_INT_PRINT_DEC ", %s #%d", mnemonic, lane_count,
element_char, UINTVAL (info.u.mov.value), "lsl",
diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md
index 0a17138..2c18af9 100644
--- a/gcc/config/aarch64/predicates.md
+++ b/gcc/config/aarch64/predicates.md
@@ -943,11 +943,6 @@
(ior (match_operand 0 "register_operand")
(match_operand 0 "aarch64_sve_logical_immediate")))
-(define_predicate "aarch64_orr_imm_sve_advsimd"
- (ior (match_operand 0 "aarch64_reg_or_orr_imm")
- (and (match_test "TARGET_SVE")
- (match_operand 0 "aarch64_sve_logical_operand"))))
-
(define_predicate "aarch64_sve_gather_offset_b"
(ior (match_operand 0 "register_operand")
(match_operand 0 "aarch64_sve_gather_immediate_b")))
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/insr_s64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/insr_s64.c
index 32cdc82..6f36f32 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/insr_s64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/insr_s64.c
@@ -43,8 +43,8 @@ TEST_UNIFORM_Z (insr_0_s64_untied, svint64_t,
/*
** insr_1_s64:
** (
-** mov (x[0-9]+), #?1
-** insr z0\.d, \1
+** mov z([0-9]+)\.d, #?1
+** insr z0\.d, d\1
** |
** movi v([0-9]+)\.2d, 0x1
** insr z0\.d, d\2
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/insr_u64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/insr_u64.c
index ab23f67..f92059a 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/insr_u64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/insr_u64.c
@@ -43,8 +43,8 @@ TEST_UNIFORM_Z (insr_0_u64_untied, svuint64_t,
/*
** insr_1_u64:
** (
-** mov (x[0-9]+), #?1
-** insr z0\.d, \1
+** mov z([0-9]+)\.d, #?1
+** insr z0\.d, d\1
** |
** movi v([0-9]+)\.2d, 0x1
** insr z0\.d, d\2
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/fneg-abs_1.c b/gcc/testsuite/gcc.target/aarch64/sve/fneg-abs_1.c
index a8b2719..0356000 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/fneg-abs_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/fneg-abs_1.c
@@ -6,7 +6,7 @@
/*
** t1:
-** orr z[0-9]+.s, z[0-9]+.s, #-2147483648
+** orr v0.2s, #?128, lsl #?24
** ret
*/
float32x2_t t1 (float32x2_t a)
@@ -16,7 +16,7 @@ float32x2_t t1 (float32x2_t a)
/*
** t2:
-** orr z[0-9]+.s, z[0-9]+.s, #-2147483648
+** orr v0.4s, #?128, lsl #?24
** ret
*/
float32x4_t t2 (float32x4_t a)
@@ -26,7 +26,7 @@ float32x4_t t2 (float32x4_t a)
/*
** t3:
-** orr z[0-9]+.d, z[0-9]+.d, #-9223372036854775808
+** orr z[0-9]+.d, z[0-9]+.d, #?-9223372036854775808
** ret
*/
float64x2_t t3 (float64x2_t a)
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/fneg-abs_2.c b/gcc/testsuite/gcc.target/aarch64/sve/fneg-abs_2.c
index 19a7695..fe08fe3 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/fneg-abs_2.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/fneg-abs_2.c
@@ -7,7 +7,7 @@
/*
** f1:
-** orr z0.s, z0.s, #-2147483648
+** orr v0.2s, #?128, lsl #?24
** ret
*/
float32_t f1 (float32_t a)
@@ -17,7 +17,7 @@ float32_t f1 (float32_t a)
/*
** f2:
-** orr z0.d, z0.d, #-9223372036854775808
+** orr z0.d, z0.d, #?-9223372036854775808
** ret
*/
float64_t f2 (float64_t a)
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/simd_imm_mov.c b/gcc/testsuite/gcc.target/aarch64/sve/simd_imm_mov.c
new file mode 100644
index 0000000..57aa980
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/simd_imm_mov.c
@@ -0,0 +1,39 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+#include <arm_neon.h>
+
+typedef short v8hi __attribute__((vector_size(16)));
+typedef int v4si __attribute__((vector_size(16)));
+typedef long v2di __attribute__((vector_size(16)));
+
+/*
+** t1:
+** mov z0.s, #?4092
+** ret
+*/
+v4si t1 ()
+{
+ return (v4si) { 0xffc, 0xffc, 0xffc, 0xffc };
+}
+
+/*
+** t2:
+** mov z0.h, #?510
+** ret
+*/
+v8hi t2 ()
+{
+ return (v8hi) { 510, 510, 510, 510, 510, 510, 510, 510 };
+}
+
+/*
+** t3:
+** mov z0.d, #?1
+** ret
+*/
+v2di t3 ()
+{
+ return (v2di) { 1, 1 };
+}