From c91062822060a9cab744b3d10fda6456822740aa Mon Sep 17 00:00:00 2001 From: Christian Bruel Date: Mon, 16 Nov 2015 11:21:09 +0100 Subject: [PATCH] re PR target/65837 ([arm-linux-gnueabihf] lto1 target specific builtin not available) 2015-11-16 Christian Bruel PR target/65837 * config/arm/arm-c.c (arm_cpu_builtins): Set or reset __ARM_FEATURE_CRYPTO, __VFP_FP__, __ARM_NEON__ (arm_pragma_target_parse): Change check for arm_cpu_builtins. undefine __ARM_FP. * config/arm/arm.c (arm_can_inline_p): Check FPUs. (arm_valid_target_attribute_rec): Handle -mfpu attribute target. * doc/invoke.texi (-mfpu=): Mention attribute and pragma. * doc/extend.texi (-mfpu=): Describe attribute. 2015-11-16 Christian Bruel PR target/65837 gcc.target/arm/lto/pr65837_0.c gcc.target/arm/attr-neon2.c gcc.target/arm/attr-neon.c gcc.target/arm/attr-neon-builtin-fail.c gcc.target/arm/attr-crypto.c From-SVN: r230408 --- gcc/ChangeLog | 12 ++++ gcc/config/arm/arm-c.c | 30 ++++---- gcc/config/arm/arm.c | 72 ++++++++++++++----- gcc/doc/extend.texi | 9 ++- gcc/doc/invoke.texi | 2 + gcc/testsuite/ChangeLog | 11 ++- gcc/testsuite/gcc.target/arm/attr-crypto.c | 39 ++++++++++ .../gcc.target/arm/attr-neon-builtin-fail.c | 17 +++++ gcc/testsuite/gcc.target/arm/attr-neon.c | 22 ++++++ gcc/testsuite/gcc.target/arm/attr-neon2.c | 28 ++++++++ gcc/testsuite/gcc.target/arm/lto/pr65837_0.c | 14 ++++ 11 files changed, 222 insertions(+), 34 deletions(-) create mode 100644 gcc/testsuite/gcc.target/arm/attr-crypto.c create mode 100644 gcc/testsuite/gcc.target/arm/attr-neon-builtin-fail.c create mode 100644 gcc/testsuite/gcc.target/arm/attr-neon.c create mode 100644 gcc/testsuite/gcc.target/arm/attr-neon2.c create mode 100644 gcc/testsuite/gcc.target/arm/lto/pr65837_0.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2febfca57c2..fb7dc5a37ae 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2015-11-16 Christian Bruel + + PR target/65837 + * config/arm/arm-c.c (arm_cpu_builtins): Set or reset + __ARM_FEATURE_CRYPTO, __VFP_FP__, __ARM_NEON__ + (arm_pragma_target_parse): Change check for arm_cpu_builtins. + undefine __ARM_FP. + * config/arm/arm.c (arm_can_inline_p): Check FPUs. + (arm_valid_target_attribute_rec): Handle -mfpu attribute target. + * doc/invoke.texi (-mfpu=): Mention attribute and pragma. + * doc/extend.texi (-mfpu=): Describe attribute. + 2015-11-16 Christian Bruel PR target/65837 diff --git a/gcc/config/arm/arm-c.c b/gcc/config/arm/arm-c.c index 6471dba4794..e94fa107537 100644 --- a/gcc/config/arm/arm-c.c +++ b/gcc/config/arm/arm-c.c @@ -64,8 +64,8 @@ arm_cpu_builtins (struct cpp_reader* pfile) def_or_undef_macro (pfile, "__ARM_FEATURE_DSP", TARGET_DSP_MULTIPLY); def_or_undef_macro (pfile, "__ARM_FEATURE_QBIT", TARGET_ARM_QBIT); def_or_undef_macro (pfile, "__ARM_FEATURE_SAT", TARGET_ARM_SAT); - if (TARGET_CRYPTO) - builtin_define ("__ARM_FEATURE_CRYPTO"); + def_or_undef_macro (pfile, "__ARM_FEATURE_CRYPTO", TARGET_CRYPTO); + if (unaligned_access) builtin_define ("__ARM_FEATURE_UNALIGNED"); if (TARGET_CRC32) @@ -125,9 +125,8 @@ arm_cpu_builtins (struct cpp_reader* pfile) if (TARGET_SOFT_FLOAT) builtin_define ("__SOFTFP__"); - if (TARGET_VFP) - builtin_define ("__VFP_FP__"); - + def_or_undef_macro (pfile, "__VFP_FP__", TARGET_VFP); + if (TARGET_ARM_FP) builtin_define_with_int_value ("__ARM_FP", TARGET_ARM_FP); if (arm_fp16_format == ARM_FP16_FORMAT_IEEE) @@ -137,19 +136,16 @@ arm_cpu_builtins (struct cpp_reader* pfile) if (TARGET_FMA) builtin_define ("__ARM_FEATURE_FMA"); - if (TARGET_NEON) - { - builtin_define ("__ARM_NEON__"); - builtin_define ("__ARM_NEON"); - } + def_or_undef_macro (pfile, "__ARM_NEON__", TARGET_NEON); + def_or_undef_macro (pfile, "__ARM_NEON", TARGET_NEON); + if (TARGET_NEON_FP) builtin_define_with_int_value ("__ARM_NEON_FP", TARGET_NEON_FP); - + /* Add a define for interworking. Needed when building libgcc.a. */ if (arm_cpp_interwork) builtin_define ("__THUMB_INTERWORK__"); - builtin_define (arm_arch_name); if (arm_arch_xscale) builtin_define ("__XSCALE__"); @@ -228,19 +224,27 @@ arm_pragma_target_parse (tree args, tree pop_target) gcc_assert (prev_opt); gcc_assert (cur_opt); - if (cur_opt->x_target_flags != prev_opt->x_target_flags) + if (cur_opt != prev_opt) { /* For the definitions, ensure all newly defined macros are considered as used for -Wunused-macros. There is no point warning about the compiler predefined macros. */ cpp_options *cpp_opts = cpp_get_options (parse_in); unsigned char saved_warn_unused_macros = cpp_opts->warn_unused_macros; + unsigned char saved_warn_builtin_macro_redefined + = cpp_opts->warn_builtin_macro_redefined; + cpp_opts->warn_unused_macros = 0; + cpp_opts->warn_builtin_macro_redefined = 0; /* Update macros. */ gcc_assert (cur_opt->x_target_flags == target_flags); + /* This one can be redefined by the pragma without warning. */ + cpp_undef (parse_in, "__ARM_FP"); + arm_cpu_builtins (parse_in); + cpp_opts->warn_builtin_macro_redefined = saved_warn_builtin_macro_redefined; cpp_opts->warn_unused_macros = saved_warn_unused_macros; } diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 98b5c8258dc..a6b25dccb01 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -29759,11 +29759,36 @@ arm_option_print (FILE *file, int indent, struct cl_target_option *ptr) /* Hook to determine if one function can safely inline another. */ static bool -arm_can_inline_p (tree caller ATTRIBUTE_UNUSED, tree callee ATTRIBUTE_UNUSED) +arm_can_inline_p (tree caller, tree callee) { - /* Overidde default hook: Always OK to inline between different modes. - Function with mode specific instructions, e.g using asm, must be explicitely - protected with noinline. */ + tree caller_tree = DECL_FUNCTION_SPECIFIC_TARGET (caller); + tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (callee); + + struct cl_target_option *caller_opts + = TREE_TARGET_OPTION (caller_tree ? caller_tree + : target_option_default_node); + + struct cl_target_option *callee_opts + = TREE_TARGET_OPTION (callee_tree ? callee_tree + : target_option_default_node); + + const struct arm_fpu_desc *caller_fpu + = &all_fpus[caller_opts->x_arm_fpu_index]; + const struct arm_fpu_desc *callee_fpu + = &all_fpus[callee_opts->x_arm_fpu_index]; + + /* Callee's fpu features should be a subset of the caller's. */ + if ((caller_fpu->features & callee_fpu->features) != callee_fpu->features) + return false; + + /* Need same model and regs. */ + if (callee_fpu->model != caller_fpu->model + || callee_fpu->regs != callee_fpu->regs) + return false; + + /* OK to inline between different modes. + Function with mode specific instructions, e.g using asm, + must be explicitly protected with noinline. */ return true; } @@ -29794,6 +29819,7 @@ arm_valid_target_attribute_rec (tree args, struct gcc_options *opts) if (TREE_CODE (args) == TREE_LIST) { bool ret = true; + for (; args; args = TREE_CHAIN (args)) if (TREE_VALUE (args) && !arm_valid_target_attribute_rec (TREE_VALUE (args), opts)) @@ -29808,30 +29834,38 @@ arm_valid_target_attribute_rec (tree args, struct gcc_options *opts) } char *argstr = ASTRDUP (TREE_STRING_POINTER (args)); - while (argstr && *argstr != '\0') + char *q; + + while ((q = strtok (argstr, ",")) != NULL) { - while (ISSPACE (*argstr)) - argstr++; + while (ISSPACE (*q)) ++q; - if (!strcmp (argstr, "thumb")) - { + argstr = NULL; + if (!strncmp (q, "thumb", 5)) opts->x_target_flags |= MASK_THUMB; - arm_option_check_internal (opts); - return true; - } - if (!strcmp (argstr, "arm")) - { + else if (!strncmp (q, "arm", 3)) opts->x_target_flags &= ~MASK_THUMB; - arm_option_check_internal (opts); - return true; + + else if (!strncmp (q, "fpu=", 4)) + { + if (! opt_enum_arg_to_value (OPT_mfpu_, q+4, + &opts->x_arm_fpu_index, CL_TARGET)) + { + error ("invalid fpu for attribute(target(\"%s\"))", q); + return false; + } + } + else + { + error ("attribute(target(\"%s\")) is unknown", q); + return false; } - warning (0, "attribute(target(\"%s\")) is unknown", argstr); - return false; + arm_option_check_internal (opts); } - return false; + return true; } /* Return a TARGET_OPTION_NODE tree of the target options listed or NULL. */ diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index aab6bad905c..4d64e14f5b8 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -3701,10 +3701,17 @@ architecture level. @item arm @cindex @code{target("arm")} function attribute, ARM Force code generation in the ARM (A32) ISA. -@end table Functions from different modes can be inlined in the caller's mode. +@item fpu= +@cindex @code{target("fpu=")} function attribute, ARM +Specifies the fpu for which to tune the performance of this function. +The behavior and permissible arguments are the same as for the @option{-mfpu=} +command-line option. + +@end table + @end table @node AVR Function Attributes diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index eeb79e65c0e..8057ac94549 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -13644,6 +13644,8 @@ because NEON hardware does not fully implement the IEEE 754 standard for floating-point arithmetic (in particular denormal values are treated as zero), so the use of NEON instructions may lead to a loss of precision. +You can also set the fpu name at function level by using the @code{target("fpu=")} function attributes (@pxref{ARM Function Attributes}) or pragmas (@pxref{Function Specific Option Pragmas}). + @item -mfp16-format=@var{name} @opindex mfp16-format Specify the format of the @code{__fp16} half-precision floating-point type. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cb3cc6dea60..10def9fd152 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2015-11-16 Christian Bruel + + PR target/65837 + gcc.target/arm/lto/pr65837_0.c + gcc.target/arm/attr-neon2.c + gcc.target/arm/attr-neon.c + gcc.target/arm/attr-neon-builtin-fail.c + gcc.target/arm/attr-crypto.c + 2015-11-16 Richard Biener * gcc.dg/vect/bb-slp-32.c: Adjust testcase. @@ -4782,7 +4791,7 @@ PR c++-common/67882 * c-c++-common/builtin-offsetof-2.c: New test. -2015-11-03 Dominique d'Humieres +015-11-03 Dominique d'Humieres PR fortran/67982 * gfortran.dg/warn_unused_function_3.f90: New test. diff --git a/gcc/testsuite/gcc.target/arm/attr-crypto.c b/gcc/testsuite/gcc.target/arm/attr-crypto.c new file mode 100644 index 00000000000..1db598447cd --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/attr-crypto.c @@ -0,0 +1,39 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target arm_crypto_ok } */ +/* { dg-options "-O2 -mfloat-abi=softfp" } */ + +#pragma GCC target ("fpu=crypto-neon-fp-armv8") + +#ifndef __ARM_FEATURE_CRYPTO +#error __ARM_FEATURE_CRYPTO not defined. +#endif + +#ifndef __ARM_NEON +#error __ARM_NEON not defined. +#endif + +#if !defined(__ARM_FP) || (__ARM_FP != 14) +#error __ARM_FP +#endif + +#include "arm_neon.h" + +int +foo (void) +{ + uint32x4_t a = {0xd, 0xe, 0xa, 0xd}; + uint32x4_t b = {0, 1, 2, 3}; + + uint32x4_t res = vsha256su0q_u32 (a, b); + return res[0]; +} + +#pragma GCC reset_options + +/* Check that the FP version is correctly reset. */ + +#if !defined(__ARM_FP) || (__ARM_FP != 12) +#error __ARM_FP +#endif + +/* { dg-final { scan-assembler "sha256su0.32\tq\[0-9\]+, q\[0-9\]+" } } */ diff --git a/gcc/testsuite/gcc.target/arm/attr-neon-builtin-fail.c b/gcc/testsuite/gcc.target/arm/attr-neon-builtin-fail.c new file mode 100644 index 00000000000..6ac32fca166 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/attr-neon-builtin-fail.c @@ -0,0 +1,17 @@ +/* Check that calling a neon builtin from a function compiled with vfp fails. */ +/* { dg-do compile } */ +/* { dg-require-effective-target arm_neon_ok } */ +/* { dg-options "-O2 -mfloat-abi=softfp" } */ + +#include + +__attribute__ ((target ("fpu=vfp"))) +void +foo (uint8x16_t *p) +{ + *p = vmovq_n_u8 (3); /* { dg-message "called from here" } */ +} + +/* { dg-error "inlining failed in call to always_inline" "" { target *-*-* } 0 } + */ + diff --git a/gcc/testsuite/gcc.target/arm/attr-neon.c b/gcc/testsuite/gcc.target/arm/attr-neon.c new file mode 100644 index 00000000000..a29ea12c8e0 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/attr-neon.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target arm_neon_ok } */ +/* { dg-options "-O2 -mfloat-abi=softfp -ftree-vectorize" } */ + +/* Verify that neon instructions are emitted once. */ +void __attribute__ ((target("fpu=neon"))) + f1(int n, int x[], int y[]) { + int i; + for (i = 0; i < n; ++i) + y[i] = x[i] << 3; +} + +void __attribute__ ((target("fpu=vfp"))) +f3(int n, int x[], int y[]) { + int i; + for (i = 0; i < n; ++i) + y[i] = x[i] << 3; +} + +/* { dg-final { scan-assembler-times "\.fpu vfp" 1 } } */ +/* { dg-final { scan-assembler-times "\.fpu neon" 1 } } */ +/* { dg-final { scan-assembler-times "vshl" 1 } } */ diff --git a/gcc/testsuite/gcc.target/arm/attr-neon2.c b/gcc/testsuite/gcc.target/arm/attr-neon2.c new file mode 100644 index 00000000000..819fad4ce62 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/attr-neon2.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target arm_neon_ok } */ +/* { dg-options "-O2 -mfloat-abi=softfp -mfpu=vfp" } */ + +#pragma GCC target ("fpu=neon") +#include + +/* Check that pragma target is used. */ +int8x8_t +my (int8x8_t __a, int8x8_t __b) +{ + return __a + __b; +} + +#pragma GCC reset_options + +/* Check that command line option is restored. */ +int8x8_t +my1 (int8x8_t __a, int8x8_t __b) +{ + return __a + __b; +} + +/* { dg-final { scan-assembler-times "\.fpu vfp" 1 } } */ +/* { dg-final { scan-assembler-times "\.fpu neon" 1 } } */ +/* { dg-final { scan-assembler "vadd" } } */ + + diff --git a/gcc/testsuite/gcc.target/arm/lto/pr65837_0.c b/gcc/testsuite/gcc.target/arm/lto/pr65837_0.c new file mode 100644 index 00000000000..000fc2a31c9 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/lto/pr65837_0.c @@ -0,0 +1,14 @@ +/* { dg-lto-do run } */ +/* { dg-lto-options {{-flto -mfpu=neon}} } */ +/* { dg-suppress-ld-options {-mfpu=neon} } */ + +#include "arm_neon.h" + +float32x2_t a, b, c, e; + +int main() +{ + e = __builtin_neon_vmls_lanev2sf (a, b, c, 0); + return 0; +} + -- 2.30.2