PR101609: Use the correct iterator for AArch64 vector right shift pattern
authorTejas Belagod <tbelagod@arm.com>
Mon, 9 Aug 2021 10:33:30 +0000 (11:33 +0100)
committerTejas Belagod <tbelagod@arm.com>
Mon, 9 Aug 2021 11:54:14 +0000 (12:54 +0100)
Loops containing long long shifts fail to vectorize due to the vectorizer
not being able to recognize long long right shifts. This is due to a bug
in the iterator used for the vashr and vlshr patterns in aarch64-simd.md.

2021-08-09  Tejas Belagod  <tejas.belagod@arm.com>

gcc/ChangeLog
PR target/101609
* config/aarch64/aarch64-simd.md (vlshr<mode>3, vashr<mode>3): Use
the right iterator.

gcc/testsuite/ChangeLog
* gcc.target/aarch64/vect-shr-reg.c: New testcase.
* gcc.target/aarch64/vect-shr-reg-run.c: Likewise.

gcc/config/aarch64/aarch64-simd.md
gcc/testsuite/gcc.target/aarch64/vect-shr-reg-run.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/vect-shr-reg.c [new file with mode: 0644]

index c5638d0..48eddf6 100644 (file)
   DONE;
 })
 
-;; Using mode VDQ_BHSI as there is no V2DImode neg!
-;; Negating individual lanes most certainly offsets the
-;; gain from vectorization.
 (define_expand "vashr<mode>3"
- [(match_operand:VDQ_BHSI 0 "register_operand")
-  (match_operand:VDQ_BHSI 1 "register_operand")
-  (match_operand:VDQ_BHSI 2 "register_operand")]
+ [(match_operand:VDQ_I 0 "register_operand")
+  (match_operand:VDQ_I 1 "register_operand")
+  (match_operand:VDQ_I 2 "register_operand")]
  "TARGET_SIMD"
 {
   rtx neg = gen_reg_rtx (<MODE>mode);
 )
 
 (define_expand "vlshr<mode>3"
- [(match_operand:VDQ_BHSI 0 "register_operand")
-  (match_operand:VDQ_BHSI 1 "register_operand")
-  (match_operand:VDQ_BHSI 2 "register_operand")]
+ [(match_operand:VDQ_I 0 "register_operand")
+  (match_operand:VDQ_I 1 "register_operand")
+  (match_operand:VDQ_I 2 "register_operand")]
  "TARGET_SIMD"
 {
   rtx neg = gen_reg_rtx (<MODE>mode);
diff --git a/gcc/testsuite/gcc.target/aarch64/vect-shr-reg-run.c b/gcc/testsuite/gcc.target/aarch64/vect-shr-reg-run.c
new file mode 100644 (file)
index 0000000..3190448
--- /dev/null
@@ -0,0 +1,53 @@
+/* { dg-do run } */
+/* { dg-options "-O3 -march=armv8.2-a" } */
+
+#include "vect-shr-reg.c"
+
+int
+main(void)
+{
+  int64_t a[16];
+  int64_t b[16];
+  int64_t c[17];
+
+  uint64_t ua[16];
+  uint64_t ub[16];
+  uint64_t uc[17];
+
+  int64_t res_a[16];
+  uint64_t res_ua[16];
+
+  int i;
+
+  /* Set up inputs.  */
+  for (i = 0; i < 16; i++)
+    {
+      b[i] = -2;
+      c[i] = 34;
+      ub[i] = 0xffffffffffffffff;
+      uc[i] = 52;
+    }
+
+  /* Set up reference values.  */
+  for (i = 0; i < 16; i++)
+    {
+      res_a[i] = -1LL;
+      res_ua[i] = 0x0fffLL;
+    }
+
+  /* Do the shifts.  */
+  f (ua, ub, uc);
+  g (a, b, c);
+
+  /* Compare outputs against reference values.  */
+  for (i = 0; i < 16; i++)
+    {
+      if (a[i] != res_a[i])
+       __builtin_abort ();
+
+      if (ua[i] != res_ua[i])
+       __builtin_abort ();
+    }
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/vect-shr-reg.c b/gcc/testsuite/gcc.target/aarch64/vect-shr-reg.c
new file mode 100644 (file)
index 0000000..5736daf
--- /dev/null
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=armv8.2-a" } */
+
+#include <stdint.h>
+#include <stdio.h>
+
+#pragma GCC target "+nosve"
+
+int __attribute__((noinline))
+f(uint64_t *__restrict a, uint64_t *__restrict b, uint64_t *__restrict c)
+{
+  int i;
+
+  for (i = 0; i < 16; i++)
+    a[i] = b[i] >> c[i];
+}
+
+
+int __attribute__((noinline))
+g(int64_t *__restrict a, int64_t *__restrict b, int64_t *__restrict c)
+{
+  int i;
+
+  for (i = 0; i < 16; i++)
+    a[i] = b[i] >> c[i];
+}
+
+/* { dg-final { scan-assembler "neg\\tv" } } */
+/* { dg-final { scan-assembler "ushl\\tv" } } */
+/* { dg-final { scan-assembler "sshl\\tv" } } */