221 lines
7.0 KiB
Diff
221 lines
7.0 KiB
Diff
|
2015-01-28 Jakub Jelinek <jakub@redhat.com>
|
|||
|
|
|||
|
PR target/61925
|
|||
|
* config/i386/i386.c (ix86_reset_to_default_globals): Removed.
|
|||
|
(ix86_reset_previous_fndecl): Restore it here, unconditionally.
|
|||
|
(ix86_set_current_function): Rewritten.
|
|||
|
(ix86_add_new_builtins): Temporarily clear current_target_pragma
|
|||
|
when creating builtin fndecls.
|
|||
|
|
|||
|
* gcc.target/i386/pr61925-1.c: New test.
|
|||
|
* gcc.target/i386/pr61925-2.c: New test.
|
|||
|
* gcc.target/i386/pr61925-3.c: New test.
|
|||
|
|
|||
|
--- gcc/config/i386/i386.c.jj 2015-01-26 22:27:20.000000000 +0100
|
|||
|
+++ gcc/config/i386/i386.c 2015-01-28 14:41:03.008727087 +0100
|
|||
|
@@ -5076,35 +5076,20 @@ ix86_can_inline_p (tree caller, tree cal
|
|||
|
/* Remember the last target of ix86_set_current_function. */
|
|||
|
static GTY(()) tree ix86_previous_fndecl;
|
|||
|
|
|||
|
-/* Set target globals to default. */
|
|||
|
+/* Set targets globals to the default (or current #pragma GCC target
|
|||
|
+ if active). Invalidate ix86_previous_fndecl cache. */
|
|||
|
|
|||
|
-static void
|
|||
|
-ix86_reset_to_default_globals (void)
|
|||
|
-{
|
|||
|
- tree old_tree = (ix86_previous_fndecl
|
|||
|
- ? DECL_FUNCTION_SPECIFIC_TARGET (ix86_previous_fndecl)
|
|||
|
- : NULL_TREE);
|
|||
|
-
|
|||
|
- if (old_tree)
|
|||
|
- {
|
|||
|
- tree new_tree = target_option_current_node;
|
|||
|
- cl_target_option_restore (&global_options,
|
|||
|
- TREE_TARGET_OPTION (new_tree));
|
|||
|
- if (TREE_TARGET_GLOBALS (new_tree))
|
|||
|
- restore_target_globals (TREE_TARGET_GLOBALS (new_tree));
|
|||
|
- else if (new_tree == target_option_default_node)
|
|||
|
- restore_target_globals (&default_target_globals);
|
|||
|
- else
|
|||
|
- TREE_TARGET_GLOBALS (new_tree)
|
|||
|
- = save_target_globals_default_opts ();
|
|||
|
- }
|
|||
|
-}
|
|||
|
-
|
|||
|
-/* Invalidate ix86_previous_fndecl cache. */
|
|||
|
void
|
|||
|
ix86_reset_previous_fndecl (void)
|
|||
|
{
|
|||
|
- ix86_reset_to_default_globals ();
|
|||
|
+ tree new_tree = target_option_current_node;
|
|||
|
+ cl_target_option_restore (&global_options, TREE_TARGET_OPTION (new_tree));
|
|||
|
+ if (TREE_TARGET_GLOBALS (new_tree))
|
|||
|
+ restore_target_globals (TREE_TARGET_GLOBALS (new_tree));
|
|||
|
+ else if (new_tree == target_option_default_node)
|
|||
|
+ restore_target_globals (&default_target_globals);
|
|||
|
+ else
|
|||
|
+ TREE_TARGET_GLOBALS (new_tree) = save_target_globals_default_opts ();
|
|||
|
ix86_previous_fndecl = NULL_TREE;
|
|||
|
}
|
|||
|
|
|||
|
@@ -5117,34 +5102,39 @@ ix86_set_current_function (tree fndecl)
|
|||
|
/* Only change the context if the function changes. This hook is called
|
|||
|
several times in the course of compiling a function, and we don't want to
|
|||
|
slow things down too much or call target_reinit when it isn't safe. */
|
|||
|
- if (fndecl && fndecl != ix86_previous_fndecl)
|
|||
|
- {
|
|||
|
- tree old_tree = (ix86_previous_fndecl
|
|||
|
- ? DECL_FUNCTION_SPECIFIC_TARGET (ix86_previous_fndecl)
|
|||
|
- : NULL_TREE);
|
|||
|
+ if (fndecl == ix86_previous_fndecl)
|
|||
|
+ return;
|
|||
|
|
|||
|
- tree new_tree = (fndecl
|
|||
|
- ? DECL_FUNCTION_SPECIFIC_TARGET (fndecl)
|
|||
|
- : NULL_TREE);
|
|||
|
+ tree old_tree;
|
|||
|
+ if (ix86_previous_fndecl == NULL_TREE)
|
|||
|
+ old_tree = target_option_current_node;
|
|||
|
+ else if (DECL_FUNCTION_SPECIFIC_TARGET (ix86_previous_fndecl))
|
|||
|
+ old_tree = DECL_FUNCTION_SPECIFIC_TARGET (ix86_previous_fndecl);
|
|||
|
+ else
|
|||
|
+ old_tree = target_option_default_node;
|
|||
|
|
|||
|
- if (old_tree == new_tree)
|
|||
|
- ;
|
|||
|
+ if (fndecl == NULL_TREE)
|
|||
|
+ {
|
|||
|
+ if (old_tree != target_option_current_node)
|
|||
|
+ ix86_reset_previous_fndecl ();
|
|||
|
+ return;
|
|||
|
+ }
|
|||
|
|
|||
|
- else if (new_tree && new_tree != target_option_default_node)
|
|||
|
- {
|
|||
|
- cl_target_option_restore (&global_options,
|
|||
|
- TREE_TARGET_OPTION (new_tree));
|
|||
|
- if (TREE_TARGET_GLOBALS (new_tree))
|
|||
|
- restore_target_globals (TREE_TARGET_GLOBALS (new_tree));
|
|||
|
- else
|
|||
|
- TREE_TARGET_GLOBALS (new_tree)
|
|||
|
- = save_target_globals_default_opts ();
|
|||
|
- }
|
|||
|
+ tree new_tree = DECL_FUNCTION_SPECIFIC_TARGET (fndecl);
|
|||
|
+ if (new_tree == NULL_TREE)
|
|||
|
+ new_tree = target_option_default_node;
|
|||
|
|
|||
|
- else if (old_tree && old_tree != target_option_default_node)
|
|||
|
- ix86_reset_to_default_globals ();
|
|||
|
- ix86_previous_fndecl = fndecl;
|
|||
|
+ if (old_tree != new_tree)
|
|||
|
+ {
|
|||
|
+ cl_target_option_restore (&global_options, TREE_TARGET_OPTION (new_tree));
|
|||
|
+ if (TREE_TARGET_GLOBALS (new_tree))
|
|||
|
+ restore_target_globals (TREE_TARGET_GLOBALS (new_tree));
|
|||
|
+ else if (new_tree == target_option_default_node)
|
|||
|
+ restore_target_globals (&default_target_globals);
|
|||
|
+ else
|
|||
|
+ TREE_TARGET_GLOBALS (new_tree) = save_target_globals_default_opts ();
|
|||
|
}
|
|||
|
+ ix86_previous_fndecl = fndecl;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
@@ -30580,6 +30570,8 @@ static void
|
|||
|
ix86_add_new_builtins (HOST_WIDE_INT isa)
|
|||
|
{
|
|||
|
int i;
|
|||
|
+ tree saved_current_target_pragma = current_target_pragma;
|
|||
|
+ current_target_pragma = NULL_TREE;
|
|||
|
|
|||
|
for (i = 0; i < (int)IX86_BUILTIN_MAX; i++)
|
|||
|
{
|
|||
|
@@ -30606,6 +30598,8 @@ ix86_add_new_builtins (HOST_WIDE_INT isa
|
|||
|
TREE_NOTHROW (decl) = 1;
|
|||
|
}
|
|||
|
}
|
|||
|
+
|
|||
|
+ current_target_pragma = saved_current_target_pragma;
|
|||
|
}
|
|||
|
|
|||
|
/* Bits for builtin_description.flag. */
|
|||
|
--- gcc/testsuite/gcc.target/i386/pr61925-1.c.jj 2015-01-28 15:10:45.756833647 +0100
|
|||
|
+++ gcc/testsuite/gcc.target/i386/pr61925-1.c 2015-01-28 15:11:49.911722473 +0100
|
|||
|
@@ -0,0 +1,21 @@
|
|||
|
+/* PR target/61925 */
|
|||
|
+/* { dg-do compile } */
|
|||
|
+/* { dg-options "-O2 -w" } */
|
|||
|
+/* { dg-additional-options "-march=i386 -mno-sse" { target ia32 } } */
|
|||
|
+
|
|||
|
+#pragma GCC push_options
|
|||
|
+#pragma GCC target("sse")
|
|||
|
+typedef float __m128 __attribute__ ((__vector_size__ (16), __may_alias__));
|
|||
|
+typedef long long __m128i __attribute__ ((__vector_size__ (16), __may_alias__));
|
|||
|
+__m128i
|
|||
|
+bar (__m128 __A)
|
|||
|
+{
|
|||
|
+}
|
|||
|
+
|
|||
|
+#pragma GCC pop_options
|
|||
|
+
|
|||
|
+__attribute__ ((vector_size (16))) int
|
|||
|
+foo (__attribute__ ((vector_size (16))) int a, __attribute__ ((vector_size (16))) int b)
|
|||
|
+{
|
|||
|
+ return a + b;
|
|||
|
+}
|
|||
|
--- gcc/testsuite/gcc.target/i386/pr61925-2.c.jj 2015-01-28 15:10:48.651783506 +0100
|
|||
|
+++ gcc/testsuite/gcc.target/i386/pr61925-2.c 2015-01-28 15:11:55.432626851 +0100
|
|||
|
@@ -0,0 +1,21 @@
|
|||
|
+/* PR target/61925 */
|
|||
|
+/* { dg-do compile } */
|
|||
|
+/* { dg-options "-O2 -w" } */
|
|||
|
+/* { dg-additional-options "-march=i386 -mno-sse" { target ia32 } } */
|
|||
|
+
|
|||
|
+#pragma GCC push_options
|
|||
|
+#pragma GCC target("sse")
|
|||
|
+typedef float __m128 __attribute__ ((__vector_size__ (16), __may_alias__));
|
|||
|
+extern __inline __m128 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
|
|||
|
+foo (void)
|
|||
|
+{
|
|||
|
+}
|
|||
|
+
|
|||
|
+#pragma GCC target("sse2")
|
|||
|
+#pragma GCC pop_options
|
|||
|
+
|
|||
|
+__attribute__ ((vector_size (16))) int
|
|||
|
+bar (__attribute__ ((vector_size (16))) int a, __attribute__ ((vector_size (16))) int b)
|
|||
|
+{
|
|||
|
+ return a + b;
|
|||
|
+}
|
|||
|
--- gcc/testsuite/gcc.target/i386/pr61925-3.c.jj 2015-01-28 15:10:51.538733503 +0100
|
|||
|
+++ gcc/testsuite/gcc.target/i386/pr61925-3.c 2015-01-28 15:12:01.316524940 +0100
|
|||
|
@@ -0,0 +1,27 @@
|
|||
|
+/* PR target/61925 */
|
|||
|
+/* { dg-do compile } */
|
|||
|
+/* { dg-options "-O2 -w" } */
|
|||
|
+/* { dg-additional-options "-march=i386 -mno-sse" { target ia32 } } */
|
|||
|
+
|
|||
|
+#pragma GCC push_options
|
|||
|
+#pragma GCC target("sse")
|
|||
|
+typedef float __m128 __attribute__ ((__vector_size__ (16), __may_alias__));
|
|||
|
+
|
|||
|
+void
|
|||
|
+foo (void)
|
|||
|
+{
|
|||
|
+}
|
|||
|
+
|
|||
|
+__attribute__((target ("avx"))) void
|
|||
|
+bar (void)
|
|||
|
+{
|
|||
|
+}
|
|||
|
+
|
|||
|
+#pragma GCC target("sse2")
|
|||
|
+#pragma GCC pop_options
|
|||
|
+
|
|||
|
+__attribute__ ((vector_size (16))) int
|
|||
|
+baz (__attribute__ ((vector_size (16))) int a, __attribute__ ((vector_size (16))) int b)
|
|||
|
+{
|
|||
|
+ return a + b;
|
|||
|
+}
|