2015-01-28 Jakub Jelinek 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; +}