From: Alejandro Martinez Date: Wed, 29 May 2019 14:12:02 +0000 (+0000) Subject: This patch implements the [u]avgM3_floor and [u]avgM3_ceil optabs for SVE2. X-Git-Tag: upstream/12.2.0~24305 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0617e23c9531373d3b232152c0d81a2c707858d9;p=platform%2Fupstream%2Fgcc.git This patch implements the [u]avgM3_floor and [u]avgM3_ceil optabs for SVE2. From-SVN: r271739 --- 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 + + * config/aarch64/aarch64-c.c: Added TARGET_SVE2. + * config/aarch64/aarch64-sve2.md: New file. + (avg3_floor): New pattern. + (avg3_ceil): Likewise. + (*h): 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 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 +;; . + +;; Integer average (floor). +(define_expand "avg3_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 (mode, CONSTM1_RTX (mode)); + } +) + +;; Integer average (rounding). +(define_expand "avg3_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 (mode, CONSTM1_RTX (mode)); + } +) + +;; Predicated halving addsub. +(define_insn "*h" + [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w") + (unspec:SVE_I + [(match_operand: 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" + "@ + h\t%0., %1/m, %0., %3. + movprfx\t%0, %2\;h\t%0., %1/m, %0., %3." + [(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 + + * 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 * 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 +# . */ + +# 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 + +#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