arm: Fix some more vec-common.md patterns for iwmmxt [PR99724]
authorJakub Jelinek <jakub@redhat.com>
Wed, 24 Mar 2021 10:22:35 +0000 (11:22 +0100)
committerJakub Jelinek <jakub@redhat.com>
Wed, 24 Mar 2021 10:22:35 +0000 (11:22 +0100)
The following patch fixes similar issues as in PR98849;
in older gcc versions, the expanders were present in neon.md guarded
with TARGET_NEON, but they got moved to vec-common.md and guarded with
ARM_HAVE_<MODE>_ARITH so that they handle both MVE and Neon.
The macros are enabled for some modes even for iwmmxt which has some
vector support for those modes, but only limited.  In particular,
neither the one_cmpl, nor neg, nor movmisalign patterns are present.
For some reason I've failed to construct something that ICEs with
movmisalign, so that is not covered by the testsuite, but both
one_cmpl and neg ICE.

2021-03-24  Jakub Jelinek  <jakub@redhat.com>

PR target/99724
* config/arm/vec-common.md (one_cmpl<mode>2, neg<mode>2,
movmisalign<mode>): Disable expanders for TARGET_REALLY_IWMMXT.

* gcc.target/arm/pr99724.c: New test.

gcc/config/arm/vec-common.md
gcc/testsuite/gcc.target/arm/pr99724.c [new file with mode: 0644]

index 0e13187..48ee659 100644 (file)
 (define_expand "one_cmpl<mode>2"
   [(set (match_operand:VDQ 0 "s_register_operand")
        (not:VDQ (match_operand:VDQ 1 "s_register_operand")))]
-  "ARM_HAVE_<MODE>_ARITH"
+  "ARM_HAVE_<MODE>_ARITH && !TARGET_REALLY_IWMMXT"
 )
 
 (define_expand "neg<mode>2"
   [(set (match_operand:VDQWH 0 "s_register_operand" "")
        (neg:VDQWH (match_operand:VDQWH 1 "s_register_operand" "")))]
-  "ARM_HAVE_<MODE>_ARITH"
+  "ARM_HAVE_<MODE>_ARITH && !TARGET_REALLY_IWMMXT"
 )
 
 (define_expand "cadd<rot><mode>3"
  [(set (match_operand:VDQX 0 "neon_perm_struct_or_reg_operand")
        (unspec:VDQX [(match_operand:VDQX 1 "neon_perm_struct_or_reg_operand")]
         UNSPEC_MISALIGNED_ACCESS))]
- "ARM_HAVE_<MODE>_LDST && !BYTES_BIG_ENDIAN && unaligned_access"
+ "ARM_HAVE_<MODE>_LDST && !BYTES_BIG_ENDIAN
+  && unaligned_access && !TARGET_REALLY_IWMMXT"
 {
  rtx adjust_mem;
  /* This pattern is not permitted to fail during expansion: if both arguments
diff --git a/gcc/testsuite/gcc.target/arm/pr99724.c b/gcc/testsuite/gcc.target/arm/pr99724.c
new file mode 100644 (file)
index 0000000..5411078
--- /dev/null
@@ -0,0 +1,31 @@
+/* PR target/99724 */
+/* { dg-do compile } */
+/* { dg-skip-if "Test is specific to the iWMMXt" { arm*-*-* } { "-mcpu=*" } { "-mcpu=iwmmxt" } } */
+/* { dg-skip-if "Test is specific to the iWMMXt" { arm*-*-* } { "-mabi=*" } { "-mabi=iwmmxt" } } */
+/* { dg-skip-if "Test is specific to the iWMMXt" { arm*-*-* } { "-march=*" } { "-march=iwmmxt" } } */
+/* { dg-skip-if "Test is specific to ARM mode" { arm*-*-* } { "-mthumb" } { "" } } */
+/* { dg-require-effective-target arm32 } */
+/* { dg-require-effective-target arm_iwmmxt_ok } */
+/* { dg-options "-O1 -mcpu=iwmmxt" } */
+
+typedef int V __attribute__((vector_size (8)));
+struct __attribute__((packed)) S { char a; V b; char c[7]; };
+
+void
+foo (V *x)
+{
+  *x = ~*x;
+}
+
+void
+bar (V *x)
+{
+  *x = -*x;
+}
+
+void
+baz (V *x, struct S *p)
+{
+  V y = p->b;
+  *x = y;
+}