2015-11-16 Christian Bruel <christian.bruel@st.com>
authorchrbr <chrbr@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 16 Nov 2015 10:21:09 +0000 (10:21 +0000)
committerchrbr <chrbr@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 16 Nov 2015 10:21:09 +0000 (10:21 +0000)
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  <christian.bruel@st.com>

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

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@230408 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/arm/arm-c.c
gcc/config/arm/arm.c
gcc/doc/extend.texi
gcc/doc/invoke.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/arm/attr-crypto.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/attr-neon-builtin-fail.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/attr-neon.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/attr-neon2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/lto/pr65837_0.c [new file with mode: 0644]

index 2febfca..fb7dc5a 100644 (file)
@@ -1,6 +1,18 @@
 2015-11-16  Christian Bruel  <christian.bruel@st.com>
 
        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  <christian.bruel@st.com>
+
+       PR target/65837
        * config/arm/arm-protos.h (arm_init_neon_builtins): Declare.
        * config/arm/arm.c (arm_valid_target_attribute_tree): Call
        arm_init_neon_builtins.
index 6471dba..e94fa10 100644 (file)
@@ -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;
     }
 
index 98b5c82..a6b25dc 100644 (file)
@@ -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.  */
index aab6bad..4d64e14 100644 (file)
@@ -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
index eeb79e6..8057ac9 100644 (file)
@@ -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.
index cb3cc6d..10def9f 100644 (file)
@@ -1,3 +1,12 @@
+2015-11-16  Christian Bruel  <christian.bruel@st.com>
+
+       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  <rguenther@suse.de>
 
        * gcc.dg/vect/bb-slp-32.c: Adjust testcase.
        PR c++-common/67882
        * c-c++-common/builtin-offsetof-2.c: New test.
 
-2015-11-03  Dominique d'Humieres <dominiq@lps.ens.fr>
+015-11-03  Dominique d'Humieres <dominiq@lps.ens.fr>
 
        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 (file)
index 0000000..1db5984
--- /dev/null
@@ -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 (file)
index 0000000..6ac32fc
--- /dev/null
@@ -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 <arm_neon.h>
+
+__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 (file)
index 0000000..a29ea12
--- /dev/null
@@ -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 (file)
index 0000000..819fad4
--- /dev/null
@@ -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 <arm_neon.h>
+
+/* 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 (file)
index 0000000..000fc2a
--- /dev/null
@@ -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;
+}
+