This patch implements the [u]avgM3_floor and [u]avgM3_ceil optabs for SVE2.
authorAlejandro Martinez <alejandro.martinezvicente@arm.com>
Wed, 29 May 2019 14:12:02 +0000 (14:12 +0000)
committerAlejandro Martinez <alejandro@gcc.gnu.org>
Wed, 29 May 2019 14:12:02 +0000 (14:12 +0000)
From-SVN: r271739

gcc/ChangeLog
gcc/config/aarch64/aarch64-c.c
gcc/config/aarch64/aarch64-sve2.md [new file with mode: 0644]
gcc/config/aarch64/aarch64.h
gcc/config/aarch64/aarch64.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/aarch64/sve2/aarch64-sve2.exp [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/sve2/average_1.c [new file with mode: 0644]
gcc/testsuite/lib/target-supports.exp

index 92b2282a7afa956c6018d19cd32f1137119f14d1..4452293257c5a6a877b8b258760769becd7f9c16 100644 (file)
@@ -1,3 +1,13 @@
+2019-05-29  Alejandro Martinez  <alejandro.martinezvicente@arm.com>
+
+       * config/aarch64/aarch64-c.c: Added TARGET_SVE2.
+       * config/aarch64/aarch64-sve2.md: New file.
+       (<u>avg<mode>3_floor): New pattern.
+       (<u>avg<mode>3_ceil): Likewise.
+       (*<sur>h<addsub><mode>): Likewise.
+       * config/aarch64/aarch64.h: Added AARCH64_ISA_SVE2 and TARGET_SVE2.
+       * config/aarch64/aarch64.md: Include aarch64-sve2.md.
+
 2019-05-29  Jakub Jelinek  <jakub@redhat.com>
 
        PR bootstrap/90543
index 6d5acb02fc6c0bdecde8561121d9469e85802d9b..5af65b1d2f344842564b227a12f24ad04edd7271 100644 (file)
@@ -146,6 +146,7 @@ aarch64_update_cpp_builtins (cpp_reader *pfile)
        bits = 0;
       builtin_define_with_int_value ("__ARM_FEATURE_SVE_BITS", bits);
     }
+  aarch64_def_or_undef (TARGET_SVE2, "__ARM_FEATURE_SVE2", pfile);
 
   aarch64_def_or_undef (TARGET_LSE, "__ARM_FEATURE_ATOMICS", pfile);
   aarch64_def_or_undef (TARGET_AES, "__ARM_FEATURE_AES", pfile);
diff --git a/gcc/config/aarch64/aarch64-sve2.md b/gcc/config/aarch64/aarch64-sve2.md
new file mode 100644 (file)
index 0000000..d0c235b
--- /dev/null
@@ -0,0 +1,65 @@
+;; Machine description for AArch64 SVE2.
+;; Copyright (C) 2019 Free Software Foundation, Inc.
+;; Contributed by ARM Ltd.
+;;
+;; This file is part of GCC.
+;;
+;; GCC is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+;;
+;; GCC is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GCC; see the file COPYING3.  If not see
+;; <http://www.gnu.org/licenses/>.
+
+;; Integer average (floor).
+(define_expand "<u>avg<mode>3_floor"
+  [(set (match_operand:SVE_I 0 "register_operand")
+       (unspec:SVE_I
+         [(match_dup 3)
+          (unspec:SVE_I [(match_operand:SVE_I 1 "register_operand")
+                         (match_operand:SVE_I 2 "register_operand")]
+                        HADD)]
+         UNSPEC_MERGE_PTRUE))]
+  "TARGET_SVE2"
+  {
+    operands[3] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
+  }
+)
+
+;; Integer average (rounding).
+(define_expand "<u>avg<mode>3_ceil"
+  [(set (match_operand:SVE_I 0 "register_operand")
+       (unspec:SVE_I
+         [(match_dup 3)
+          (unspec:SVE_I [(match_operand:SVE_I 1 "register_operand")
+                         (match_operand:SVE_I 2 "register_operand")]
+                        RHADD)]
+         UNSPEC_MERGE_PTRUE))]
+  "TARGET_SVE2"
+  {
+    operands[3] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
+  }
+)
+
+;; Predicated halving addsub.
+(define_insn "*<sur>h<addsub><mode>"
+  [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
+       (unspec:SVE_I
+         [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
+          (unspec:SVE_I [(match_operand:SVE_I 2 "register_operand" "%0, w")
+                         (match_operand:SVE_I 3 "register_operand" "w, w")]
+                        HADDSUB)]
+         UNSPEC_MERGE_PTRUE))]
+  "TARGET_SVE2"
+  "@
+   <sur>h<addsub>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
+   movprfx\t%0, %2\;<sur>h<addsub>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
+  [(set_attr "movprfx" "*,yes")]
+)
\ No newline at end of file
index 4b3e2f97d61591e162bd60189103ec9b569988b2..516f63689c4fe17ffcdde57f19dd101b8e34fb71 100644 (file)
@@ -232,6 +232,7 @@ extern unsigned aarch64_architecture_version;
 #define AARCH64_ISA_V8_2          (aarch64_isa_flags & AARCH64_FL_V8_2)
 #define AARCH64_ISA_F16                   (aarch64_isa_flags & AARCH64_FL_F16)
 #define AARCH64_ISA_SVE            (aarch64_isa_flags & AARCH64_FL_SVE)
+#define AARCH64_ISA_SVE2          (aarch64_isa_flags & AARCH64_FL_SVE2)
 #define AARCH64_ISA_V8_3          (aarch64_isa_flags & AARCH64_FL_V8_3)
 #define AARCH64_ISA_DOTPROD       (aarch64_isa_flags & AARCH64_FL_DOTPROD)
 #define AARCH64_ISA_AES                   (aarch64_isa_flags & AARCH64_FL_AES)
@@ -277,6 +278,9 @@ extern unsigned aarch64_architecture_version;
 /* SVE instructions, enabled through +sve.  */
 #define TARGET_SVE (AARCH64_ISA_SVE)
 
+/* SVE2 instructions, enabled through +sve2.  */
+#define TARGET_SVE2 (AARCH64_ISA_SVE2)
+
 /* ARMv8.3-A features.  */
 #define TARGET_ARMV8_3 (AARCH64_ISA_V8_3)
 
index 49582f2e7e4fb51f6c7fa60639c56fd862147b27..526c7fb0dabc540065d77d4a7922aeca16a402aa 100644 (file)
 
 ;; SVE.
 (include "aarch64-sve.md")
+
+;; SVE2.
+(include "aarch64-sve2.md")
index 71982226f080f41aa8ae642de3534a9c37329230..a2d46357e3995b32fd4c3189a3f67ea11166de56 100644 (file)
@@ -1,3 +1,14 @@
+2019-05-29  Alejandro Martinez  <alejandro.martinezvicente@arm.com>
+
+       * gcc.target/aarch64/sve2/aarch64-sve2.exp: New file, regression driver
+       for AArch64 SVE2.
+       * gcc.target/aarch64/sve2/average_1.c: New test.
+       * lib/target-supports.exp (check_effective_target_aarch64_sve2): New
+       helper.
+       (check_effective_target_aarch64_sve1_only): Likewise.
+       (check_effective_target_aarch64_sve2_hw): Likewise.
+       (check_effective_target_vect_avg_qi): Check for SVE1 only.
+
 2019-05-29  Sam Tebbs  <sam.tebbs@arm.com>
 
        * gcc.target/aarch64/return_address_sign_b_1.c: New file.
diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/aarch64-sve2.exp b/gcc/testsuite/gcc.target/aarch64/sve2/aarch64-sve2.exp
new file mode 100644 (file)
index 0000000..557de27
--- /dev/null
@@ -0,0 +1,52 @@
+#  Specific regression driver for AArch64 SVE2.
+#  Copyright (C) 2009-2019 Free Software Foundation, Inc.
+#  Contributed by ARM Ltd.
+#
+#  This file is part of GCC.
+#
+#  GCC is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU General Public License as published by
+#  the Free Software Foundation; either version 3, or (at your option)
+#  any later version.
+#
+#  GCC is distributed in the hope that it will be useful, but
+#  WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#  General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with GCC; see the file COPYING3.  If not see
+#  <http://www.gnu.org/licenses/>.  */
+
+# GCC testsuite that uses the `dg.exp' driver.
+
+# Exit immediately if this isn't an AArch64 target.
+if {![istarget aarch64*-*-*] } then {
+  return
+}
+
+# Load support procs.
+load_lib gcc-dg.exp
+
+# If a testcase doesn't have special options, use these.
+global DEFAULT_CFLAGS
+if ![info exists DEFAULT_CFLAGS] then {
+    set DEFAULT_CFLAGS " -ansi -pedantic-errors"
+}
+
+# Initialize `dg'.
+dg-init
+
+# Force SVE2 if we're not testing it already.
+if { [check_effective_target_aarch64_sve2] } {
+    set sve2_flags ""
+} else {
+    set sve2_flags "-march=armv8.5-a+sve2"
+}
+
+# Main loop.
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cCS\]]] \
+    $sve2_flags $DEFAULT_CFLAGS
+
+# All done.
+dg-finish
diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/average_1.c b/gcc/testsuite/gcc.target/aarch64/sve2/average_1.c
new file mode 100644 (file)
index 0000000..3c00710
--- /dev/null
@@ -0,0 +1,46 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-details --save-temps" } */
+
+#include <stdint.h>
+
+#define AVERAGE(TYPE, BIGGER, RND)                                       \
+TYPE __attribute__ ((noinline, noclone))                                 \
+avg_##TYPE##_##RND (TYPE *restrict x, TYPE *restrict y, TYPE *restrict z, \
+                   int n)                                                \
+{                                                                        \
+  for (int i = 0; i < n; i++)                                            \
+    {                                                                    \
+      z[i] = ((BIGGER)x[i] + y[i] + RND) >> 1;                           \
+    }                                                                    \
+}
+
+AVERAGE (int8_t, int64_t, 0)
+AVERAGE (int16_t, int64_t, 0)
+AVERAGE (int32_t, int64_t, 0)
+AVERAGE (uint8_t, uint64_t, 0)
+AVERAGE (uint16_t, uint64_t, 0)
+AVERAGE (uint32_t, uint64_t, 0)
+AVERAGE (int8_t, int64_t, 1)
+AVERAGE (int16_t, int64_t, 1)
+AVERAGE (int32_t, int64_t, 1)
+AVERAGE (uint8_t, uint64_t, 1)
+AVERAGE (uint16_t, uint64_t, 1)
+AVERAGE (uint32_t, uint64_t, 1)
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 12 "vect" } } */
+
+/* { dg-final { scan-assembler-times {\tshadd\tz[0-9]+\.b, p[0-7]/m, z[0-9]+\.b, z[0-9]+\.b\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tshadd\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, z[0-9]+\.h\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tshadd\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, z[0-9]+\.s\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tuhadd\tz[0-9]+\.b, p[0-7]/m, z[0-9]+\.b, z[0-9]+\.b\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tuhadd\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, z[0-9]+\.h\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tuhadd\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, z[0-9]+\.s\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tsrhadd\tz[0-9]+\.b, p[0-7]/m, z[0-9]+\.b, z[0-9]+\.b\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tsrhadd\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, z[0-9]+\.h\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tsrhadd\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, z[0-9]+\.s\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\turhadd\tz[0-9]+\.b, p[0-7]/m, z[0-9]+\.b, z[0-9]+\.b\n} 1 } } */
+/* { dg-final { scan-assembler-times {\turhadd\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, z[0-9]+\.h\n} 1 } } */
+/* { dg-final { scan-assembler-times {\turhadd\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, z[0-9]+\.s\n} 1 } } */
index 4bcf1a1c8f77d963bf0735b3a33d3cdce00ad021..13c3a6a7157a941de152d6784efc004a3ebdbf03 100644 (file)
@@ -3306,6 +3306,24 @@ proc check_effective_target_aarch64_sve { } {
     }]
 }
 
+# Return 1 if this is an AArch64 target supporting SVE2.
+proc check_effective_target_aarch64_sve2 { } {
+    if { ![istarget aarch64*-*-*] } {
+       return 0
+    }
+    return [check_no_compiler_messages aarch64_sve2 assembly {
+       #if !defined (__ARM_FEATURE_SVE2)
+       #error FOO
+       #endif
+    }]
+}
+
+# Return 1 if this is an AArch64 target only supporting SVE (not SVE2).
+proc check_effective_target_aarch64_sve1_only { } {
+    return [expr { [check_effective_target_aarch64_sve]
+                  && ![check_effective_target_aarch64_sve2] }]
+}
+
 # Return the size in bits of an SVE vector, or 0 if the size is variable.
 proc aarch64_sve_bits { } {
     return [check_cached_effective_target aarch64_sve_bits {
@@ -4326,6 +4344,22 @@ proc check_effective_target_aarch64_sve_hw { } {
     }]
 }
 
+# Return true if this is an AArch64 target that can run SVE2 code.
+
+proc check_effective_target_aarch64_sve2_hw { } {
+    if { ![istarget aarch64*-*-*] } {
+       return 0
+    }
+    return [check_runtime aarch64_sve2_hw_available {
+       int
+       main (void)
+       {
+         asm volatile ("addp z0.b, p0/m, z0.b, z1.b");
+         return 0;
+       }
+    }]
+}
+
 # Return true if this is an AArch64 target that can run SVE code and
 # if its SVE vectors have exactly BITS bits.
 
@@ -6063,7 +6097,7 @@ proc check_effective_target_vect_usad_char { } {
 
 proc check_effective_target_vect_avg_qi {} {
     return [expr { [istarget aarch64*-*-*]
-                  && ![check_effective_target_aarch64_sve] }]
+                  && ![check_effective_target_aarch64_sve1_only] }]
 }
 
 # Return 1 if the target plus current options supports a vector