Commit 0617e23c by Alejandro Martinez Committed by Alejandro Martinez

This patch implements the [u]avgM3_floor and [u]avgM3_ceil optabs for SVE2.

From-SVN: r271739
parent ffeebc4f
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
......
......@@ -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);
......
;; 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
......@@ -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)
......
......@@ -7244,3 +7244,6 @@
;; SVE.
(include "aarch64-sve.md")
;; SVE2.
(include "aarch64-sve2.md")
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.
......
# 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
/* { 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 } } */
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment