aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlejandro Martinez <alejandro.martinezvicente@arm.com>2019-05-29 14:12:02 +0000
committerAlejandro Martinez <alejandro@gcc.gnu.org>2019-05-29 14:12:02 +0000
commit0617e23c9531373d3b232152c0d81a2c707858d9 (patch)
tree474ae225558a832a916f9157ee792a05831a5f22
parentffeebc4ff1100a14f439314f90651b42e30fb81a (diff)
downloadgcc-0617e23c9531373d3b232152c0d81a2c707858d9.zip
gcc-0617e23c9531373d3b232152c0d81a2c707858d9.tar.gz
gcc-0617e23c9531373d3b232152c0d81a2c707858d9.tar.bz2
This patch implements the [u]avgM3_floor and [u]avgM3_ceil optabs for SVE2.
From-SVN: r271739
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/config/aarch64/aarch64-c.c1
-rw-r--r--gcc/config/aarch64/aarch64-sve2.md65
-rw-r--r--gcc/config/aarch64/aarch64.h4
-rw-r--r--gcc/config/aarch64/aarch64.md3
-rw-r--r--gcc/testsuite/ChangeLog11
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve2/aarch64-sve2.exp52
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve2/average_1.c46
-rw-r--r--gcc/testsuite/lib/target-supports.exp36
9 files changed, 227 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 92b2282..4452293 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/aarch64/aarch64-c.c b/gcc/config/aarch64/aarch64-c.c
index 6d5acb0..5af65b1 100644
--- a/gcc/config/aarch64/aarch64-c.c
+++ b/gcc/config/aarch64/aarch64-c.c
@@ -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
index 0000000..d0c235b
--- /dev/null
+++ b/gcc/config/aarch64/aarch64-sve2.md
@@ -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
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index 4b3e2f9..516f636 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -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)
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 49582f2..526c7fb 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -7244,3 +7244,6 @@
;; SVE.
(include "aarch64-sve.md")
+
+;; SVE2.
+(include "aarch64-sve2.md")
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 7198222..a2d4635 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..557de27
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve2/aarch64-sve2.exp
@@ -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
index 0000000..3c00710
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve2/average_1.c
@@ -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 } } */
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 4bcf1a1..13c3a6a 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -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