From 64cd6492011fed84690a154257e11f0464859eb0 Mon Sep 17 00:00:00 2001 From: meissner Date: Fri, 9 Dec 2011 17:10:27 +0000 Subject: [PATCH] Fix PR51469 (attr-ifunc fails on ppc); Make #pragma GCC target ("...") change macros on PPC git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@182169 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 16 +++++ gcc/config/rs6000/rs6000.c | 27 +++++--- gcc/testsuite/ChangeLog | 13 ++-- gcc/testsuite/gcc.target/powerpc/ppc-target-4.c | 84 +++++++++++++++++++++++++ gcc/testsuite/gcc.target/powerpc/recip-5.c | 3 +- gcc/varasm.c | 13 ++-- 6 files changed, 135 insertions(+), 21 deletions(-) create mode 100644 gcc/testsuite/gcc.target/powerpc/ppc-target-4.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d00131af25e..3f3506179d4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2011-12-09 Michael Meissner + + * 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 PR bootstrap/51479 diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 46ad820300d..fb983097659 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -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; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7a165ae88ba..3a97bf76a68 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2011-12-09 Michael Meissner + + * 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 * gcc.dg/vect/slp-13.c: Array size increase reverted. @@ -635,11 +643,6 @@ PR target/50123 * gcc.dg/atomic-op-optimize.c: New. Test for optimizations. -2011-11-29 Michael Meissner - - * gcc.target/powerpc/ppc-target-4.c: New file to test target - specific functions enabling target specific builtins. - 2011-11-29 Yufeng Zhang 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 index 00000000000..ac728334cd5 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/ppc-target-4.c @@ -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 +#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]; +} diff --git a/gcc/testsuite/gcc.target/powerpc/recip-5.c b/gcc/testsuite/gcc.target/powerpc/recip-5.c index 0b3823cfa51..3d7d691d5ac 100644 --- a/gcc/testsuite/gcc.target/powerpc/recip-5.c +++ b/gcc/testsuite/gcc.target/powerpc/recip-5.c @@ -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 } } */ diff --git a/gcc/varasm.c b/gcc/varasm.c index 78dc4cd83f0..86134672cbe 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -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)) -- 2.11.4.GIT