]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Fix PR51469 (attr-ifunc fails on ppc); Make #pragma GCC target ("...") change macros...
authorMichael Meissner <meissner@the-meissners.org>
Fri, 9 Dec 2011 17:10:27 +0000 (17:10 +0000)
committerMichael Meissner <meissner@gcc.gnu.org>
Fri, 9 Dec 2011 17:10:27 +0000 (17:10 +0000)
From-SVN: r182169

gcc/ChangeLog
gcc/config/rs6000/rs6000.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/powerpc/ppc-target-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/recip-5.c
gcc/varasm.c

index d00131af25ede1ec90210b372aa598ede7f76580..3f3506179d456653d52eeb4799130c7b790641d8 100644 (file)
@@ -1,3 +1,19 @@
+2011-12-09  Michael Meissner  <meissner@the-meissners.org>
+
+       * config/rs6000/rs6000.c (altivec_expand_builtin): Call
+       expand_call to return a valid funciton instead of return
+       cosnt0_rtx/NULL_RTX if there was an error with the builtin.
+       (altivec_expand_ld_builtin): Ditto.
+       (rs6000_inner_target_options): If VSX is selected as a target
+       attribute or pragma, enable ALTIVEC also.
+       (rs6000_pragma_target_parse): Call rs6000_option_override_internal
+       to do all of the standard processing when switching options,
+       including redefining appropriate macros.
+
+       PR rtl-optimization/51469
+       * varasm.c (default_binds_local_p_1): If the symbol is a gnu
+       indirect function, mark the symbol as non-local.
+
 2011-12-09  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR bootstrap/51479
index 46ad820300d92b57e538ed3a0c86fe3b598a605b..fb983097659c000e430e60de096919499ac8dca4 100644 (file)
@@ -10578,7 +10578,9 @@ altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
     {
       *expandedp = true;
       error ("unresolved overload for Altivec builtin %qF", fndecl);
-      return const0_rtx;
+
+      /* Given it is invalid, just generate a normal call.  */
+      return expand_call (exp, target, false);
     }
 
   target = altivec_expand_ld_builtin (exp, target, expandedp);
@@ -11306,7 +11308,9 @@ rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
   if (!func_valid_p)
     {
       rs6000_invalid_builtin (fcode);
-      return NULL_RTX;
+
+      /* Given it is invalid, just generate a normal call.  */
+      return expand_call (exp, target, ignore);
     }
 
   switch (fcode)
@@ -26789,6 +26793,11 @@ rs6000_inner_target_options (tree args, bool attr_p)
                        error_p = false;
                        target_flags_explicit |= mask;
 
+                       /* VSX needs altivec, so -mvsx automagically sets
+                          altivec.  */
+                       if (mask == MASK_VSX && !invert)
+                         mask |= MASK_ALTIVEC;
+
                        if (rs6000_opt_masks[i].invert)
                          invert = !invert;
 
@@ -27001,7 +27010,6 @@ rs6000_pragma_target_parse (tree args, tree pop_target)
   struct cl_target_option *prev_opt, *cur_opt;
   unsigned prev_bumask, cur_bumask, diff_bumask;
   int prev_flags, cur_flags, diff_flags;
-  bool ret;
 
   if (TARGET_DEBUG_TARGET)
     {
@@ -27023,7 +27031,6 @@ rs6000_pragma_target_parse (tree args, tree pop_target)
 
   if (! args)
     {
-      ret = true;
       cur_tree = ((pop_target)
                  ? pop_target
                  : target_option_default_node);
@@ -27033,13 +27040,13 @@ rs6000_pragma_target_parse (tree args, tree pop_target)
   else
     {
       rs6000_cpu_index = rs6000_tune_index = -1;
-      ret = rs6000_inner_target_options (args, false);
-      cur_tree = build_target_option_node ();
-
-      if (!cur_tree)
+      if (!rs6000_inner_target_options (args, false)
+         || !rs6000_option_override_internal (false)
+         || (cur_tree = build_target_option_node ()) == NULL_TREE)
        {
          if (TARGET_DEBUG_BUILTIN || TARGET_DEBUG_TARGET)
-           fprintf (stderr, "build_target_option_node returned NULL\n");
+           fprintf (stderr, "invalid pragma\n");
+
          return false;
        }
     }
@@ -27075,7 +27082,7 @@ rs6000_pragma_target_parse (tree args, tree pop_target)
        }
     }
 
-  return ret;
+  return true;
 }
 
 \f
index 7a165ae88ba578ec3b71d8caa910d14b8bd1595e..3a97bf76a68dda1d5146fb0bf2da101cce746857 100644 (file)
@@ -1,3 +1,11 @@
+2011-12-09  Michael Meissner  <meissner@the-meissners.org>
+
+       * gcc.target/powerpc/recip-5.c: Disable running on any system that
+       does not support VSX.
+
+       * gcc.target/powerpc/ppc-target-4.c: New file to test target
+       specific functions enabling target specific builtins.
+
 2011-12-09  Michael Zolotukhin  <michael.v.zolotukhin@intel.com>
 
        * gcc.dg/vect/slp-13.c: Array size increase reverted.
        PR target/50123
        * gcc.dg/atomic-op-optimize.c: New.  Test for optimizations.
 
-2011-11-29  Michael Meissner  <meissner@linux.vnet.ibm.com>
-
-       * gcc.target/powerpc/ppc-target-4.c: New file to test target
-       specific functions enabling target specific builtins.
-
 2011-11-29  Yufeng Zhang  <yufeng.zhang@arm.com>
 
        Use complex floating-point constant in CDBL.
diff --git a/gcc/testsuite/gcc.target/powerpc/ppc-target-4.c b/gcc/testsuite/gcc.target/powerpc/ppc-target-4.c
new file mode 100644 (file)
index 0000000..ac72833
--- /dev/null
@@ -0,0 +1,84 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-options "-O2 -ffast-math -mcpu=power5 -mno-altivec -mabi=altivec -fno-unroll-loops" } */
+/* { dg-final { scan-assembler-times "vaddfp" 1 } } */
+/* { dg-final { scan-assembler-times "xvaddsp" 1 } } */
+/* { dg-final { scan-assembler-times "fadds" 1 } } */
+
+#ifndef SIZE
+#define SIZE 1024
+#endif
+
+#ifdef __ALTIVEC__
+#error "__ALTIVEC__ should not be defined."
+#endif
+
+#ifdef __VSX__
+#error "__VSX__ should not be defined."
+#endif
+
+#pragma GCC target("vsx")
+#include <altivec.h>
+#pragma GCC reset_options
+
+#pragma GCC push_options
+#pragma GCC target("altivec,no-vsx")
+
+#ifndef __ALTIVEC__
+#error "__ALTIVEC__ should be defined."
+#endif
+
+#ifdef __VSX__
+#error "__VSX__ should not be defined."
+#endif
+
+void
+av_add (vector float *a, vector float *b, vector float *c)
+{
+  unsigned long i;
+  unsigned long n = SIZE / 4;
+
+  for (i = 0; i < n; i++)
+    a[i] = vec_add (b[i], c[i]);
+}
+
+#pragma GCC target("vsx")
+
+#ifndef __ALTIVEC__
+#error "__ALTIVEC__ should be defined."
+#endif
+
+#ifndef __VSX__
+#error "__VSX__ should be defined."
+#endif
+
+void
+vsx_add (vector float *a, vector float *b, vector float *c)
+{
+  unsigned long i;
+  unsigned long n = SIZE / 4;
+
+  for (i = 0; i < n; i++)
+    a[i] = vec_add (b[i], c[i]);
+}
+
+#pragma GCC pop_options
+#pragma GCC target("no-vsx,no-altivec")
+
+#ifdef __ALTIVEC__
+#error "__ALTIVEC__ should not be defined."
+#endif
+
+#ifdef __VSX__
+#error "__VSX__ should not be defined."
+#endif
+
+void
+norm_add (float *a, float *b, float *c)
+{
+  unsigned long i;
+
+  for (i = 0; i < SIZE; i++)
+    a[i] = b[i] + c[i];
+}
index 0b3823cfa512e4565cdba28bcb1a93c0bae2ad2a..3d7d691d5acdf81effdb3fc9800e438fcb62f1bd 100644 (file)
@@ -1,5 +1,6 @@
 /* { dg-do compile { target { powerpc*-*-* } } } */
-/* { dg-require-effective-target powerpc_fprs } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_vsx_ok } */
 /* { dg-options "-O3 -ftree-vectorize -mrecip=all -ffast-math -mcpu=power7 -fno-unroll-loops" } */
 /* { dg-final { scan-assembler-times "xvredp" 4 } } */
 /* { dg-final { scan-assembler-times "xvresp" 5 } } */
index 78dc4cd83f018a0ab86bdae0905e390ba0c44ce9..86134672cbe6c0c85b4c19e8f63f3c726910f7c4 100644 (file)
@@ -6911,11 +6911,14 @@ default_binds_local_p_1 (const_tree exp, int shlib)
   /* A non-decl is an entry in the constant pool.  */
   if (!DECL_P (exp))
     local_p = true;
-  /* Weakrefs may not bind locally, even though the weakref itself is
-     always static and therefore local.
-     FIXME: We can resolve this more curefuly by looking at the weakref
-     alias.  */
-  else if (lookup_attribute ("weakref", DECL_ATTRIBUTES (exp)))
+  /* Weakrefs may not bind locally, even though the weakref itself is always
+     static and therefore local.  Similarly, the resolver for ifunc functions
+     might resolve to a non-local function.
+     FIXME: We can resolve the weakref case more curefuly by looking at the
+     weakref alias.  */
+  else if (lookup_attribute ("weakref", DECL_ATTRIBUTES (exp))
+          || (TREE_CODE (exp) == FUNCTION_DECL
+              && lookup_attribute ("ifunc", DECL_ATTRIBUTES (exp))))
     local_p = false;
   /* Static variables are always local.  */
   else if (! TREE_PUBLIC (exp))