From: Kyrylo Tkachov Date: Tue, 23 May 2023 10:09:08 +0000 (+0100) Subject: aarch64: PR target/109855 Add predicate and constraints to define_subst in aarch64... X-Git-Tag: basepoints/gcc-15~9011 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=75d1eff5933fc0d853af730627218f182612b561;p=thirdparty%2Fgcc.git aarch64: PR target/109855 Add predicate and constraints to define_subst in aarch64-simd.md In this PR we ICE because the substituted pattern for mla "lost" its predicate and constraint for operand 0 because the define_subst template: [(set (match_operand: 0) (vec_concat: (match_dup 1) (match_operand:VDZ 2 "aarch64_simd_or_scalar_imm_zero")))]) Uses match_operand instead of match_dup for operand 0. We can't use match_dup 0 for it because we need to specify the widened mode. The problem is fixed by adding a "register_operand" predicate and "=w" constraint to the match_operand. This makes sense conceptually too as the transformation we're targeting only applies to instructions that write a "w" register. With this change the mddump pattern that ICEs goes from: (define_insn ("aarch64_mlav4hi_vec_concatz_le") [ (set (match_operand:V8HI 0 ("") ("")) <<------ Missing constraint! (vec_concat:V8HI (plus:V4HI (mult:V4HI (match_operand:V4HI 2 ("register_operand") ("w")) (match_operand:V4HI 3 ("register_operand") ("w"))) (match_operand:V4HI 1 ("register_operand") ("0"))) (match_operand:V4HI 4 ("aarch64_simd_or_scalar_imm_zero") ("")))) ] ("(!BYTES_BIG_ENDIAN) && (TARGET_SIMD)") ("mla\t%0.4h, %2.4h, %3.4h") to the proper: (define_insn ("aarch64_mlav4hi_vec_concatz_le") [ (set (match_operand:V8HI 0 ("register_operand") ("=w")) <<-------- Constraint in the right place (vec_concat:V8HI (plus:V4HI (mult:V4HI (match_operand:V4HI 2 ("register_operand") ("w")) (match_operand:V4HI 3 ("register_operand") ("w"))) (match_operand:V4HI 1 ("register_operand") ("0"))) (match_operand:V4HI 4 ("aarch64_simd_or_scalar_imm_zero") ("")))) ] ("(!BYTES_BIG_ENDIAN) && (TARGET_SIMD)") ("mla\t%0.4h, %2.4h, %3.4h") This seems to do the right thing for multi-alternative patterns as well, the annotated pattern for aarch64_cmltv8qi is: (define_insn ("aarch64_cmltv8qi") [ (set (match_operand:V8QI 0 ("register_operand") ("=w,w")) (neg:V8QI (lt:V8QI (match_operand:V8QI 1 ("register_operand") ("w,w")) (match_operand:V8QI 2 ("aarch64_simd_reg_or_zero") ("w,ZDz"))))) ] whereas the substituted version now looks like: (define_insn ("aarch64_cmltv8qi_vec_concatz_le") [ (set (match_operand:V16QI 0 ("register_operand") ("=w,w")) (vec_concat:V16QI (neg:V8QI (lt:V8QI (match_operand:V8QI 1 ("register_operand") ("w,w")) (match_operand:V8QI 2 ("aarch64_simd_reg_or_zero") ("w,ZDz")))) (match_operand:V8QI 3 ("aarch64_simd_or_scalar_imm_zero") ("")))) ] Bootstrapped and tested on aarch64-none-linux-gnu. gcc/ChangeLog: PR target/109855 * config/aarch64/aarch64-simd.md (add_vec_concat_subst_le): Add predicate and constraint for operand 0. (add_vec_concat_subst_be): Likewise. gcc/testsuite/ChangeLog: PR target/109855 * gcc.target/aarch64/pr109855.c: New test. --- diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md index 61c815b9a1fc..af95bbb29a7b 100644 --- a/gcc/config/aarch64/aarch64-simd.md +++ b/gcc/config/aarch64/aarch64-simd.md @@ -26,7 +26,7 @@ [(set (match_operand:VDZ 0) (match_operand:VDZ 1))] "!BYTES_BIG_ENDIAN" - [(set (match_operand: 0) + [(set (match_operand: 0 "register_operand" "=w") (vec_concat: (match_dup 1) (match_operand:VDZ 2 "aarch64_simd_or_scalar_imm_zero")))]) @@ -35,7 +35,7 @@ [(set (match_operand:VDZ 0) (match_operand:VDZ 1))] "BYTES_BIG_ENDIAN" - [(set (match_operand: 0) + [(set (match_operand: 0 "register_operand" "=w") (vec_concat: (match_operand:VDZ 2 "aarch64_simd_or_scalar_imm_zero") (match_dup 1)))]) diff --git a/gcc/testsuite/gcc.target/aarch64/pr109855.c b/gcc/testsuite/gcc.target/aarch64/pr109855.c new file mode 100644 index 000000000000..90db90c6cf9a --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/pr109855.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O" } */ + +typedef char __attribute__((__vector_size__ (4))) U; +typedef short __attribute__((__vector_size__ (8))) V; + +U +foo (V v, V w) +{ + return __builtin_convertvector (w * w + w, U); +} +