From: Richard Biener Date: Thu, 24 Aug 2017 13:44:35 +0000 (+0000) Subject: re PR target/81921 (Fails to always-inline intrinsics with -flto) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9b25e12d2d940a61ec97fdc3e5c1fe6060e159f8;p=gcc.git re PR target/81921 (Fails to always-inline intrinsics with -flto) 2017-08-23 Richard Biener PR target/81921 * targhooks.c (default_target_can_inline_p): Properly use target_option_default_node when no DECL_FUNCTION_SPECIFIC_TARGET is present and always compare. * config/i386/i386.c (ix86_valid_target_attribute_tree): Do not imply -mfpmath=sse from TARGET_SSE_P. (ix86_can_inline_p): Properly use target_option_default_node when no DECL_FUNCTION_SPECIFIC_TARGET is present and always compare. * gcc.target/i386/pr81921.c: New testcase. From-SVN: r251333 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 67261275be0..cca96ed3c13 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2017-08-23 Richard Biener + + PR target/81921 + * targhooks.c (default_target_can_inline_p): Properly + use target_option_default_node when no DECL_FUNCTION_SPECIFIC_TARGET + is present and always compare. + * config/i386/i386.c (ix86_valid_target_attribute_tree): Do not + imply -mfpmath=sse from TARGET_SSE_P. + (ix86_can_inline_p): Properly use target_option_default_node when + no DECL_FUNCTION_SPECIFIC_TARGET is present and always compare. + 2017-08-24 Richard Biener PR debug/81936 diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 268946b9059..b5c113d95aa 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -7405,16 +7405,6 @@ ix86_valid_target_attribute_tree (tree args, /* If fpmath= is not set, and we now have sse2 on 32-bit, use it. */ if (enum_opts_set.x_ix86_fpmath) opts_set->x_ix86_fpmath = (enum fpmath_unit) 1; - else if (!TARGET_64BIT_P (opts->x_ix86_isa_flags) - && TARGET_SSE_P (opts->x_ix86_isa_flags)) - { - if (TARGET_80387_P (opts->x_target_flags)) - opts->x_ix86_fpmath = (enum fpmath_unit) (FPMATH_SSE - | FPMATH_387); - else - opts->x_ix86_fpmath = (enum fpmath_unit) FPMATH_SSE; - opts_set->x_ix86_fpmath = (enum fpmath_unit) 1; - } /* Do any overrides, such as arch=xxx, or tune=xxx support. */ bool r = ix86_option_override_internal (false, opts, opts_set); @@ -7509,60 +7499,54 @@ ix86_valid_target_attribute_p (tree fndecl, static bool ix86_can_inline_p (tree caller, tree callee) { - bool ret = false; tree caller_tree = DECL_FUNCTION_SPECIFIC_TARGET (caller); tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (callee); - - /* If callee has no option attributes, then it is ok to inline. */ if (!callee_tree) - ret = true; - - /* If caller has no option attributes, but callee does then it is not ok to - inline. */ - else if (!caller_tree) - ret = false; + callee_tree = target_option_default_node; + if (!caller_tree) + caller_tree = target_option_default_node; + if (callee_tree == caller_tree) + return true; - else - { - struct cl_target_option *caller_opts = TREE_TARGET_OPTION (caller_tree); - struct cl_target_option *callee_opts = TREE_TARGET_OPTION (callee_tree); + struct cl_target_option *caller_opts = TREE_TARGET_OPTION (caller_tree); + struct cl_target_option *callee_opts = TREE_TARGET_OPTION (callee_tree); + bool ret = false; - /* Callee's isa options should be a subset of the caller's, i.e. a SSE4 - function can inline a SSE2 function but a SSE2 function can't inline - a SSE4 function. */ - if (((caller_opts->x_ix86_isa_flags & callee_opts->x_ix86_isa_flags) - != callee_opts->x_ix86_isa_flags) - || ((caller_opts->x_ix86_isa_flags2 & callee_opts->x_ix86_isa_flags2) - != callee_opts->x_ix86_isa_flags2)) - ret = false; + /* Callee's isa options should be a subset of the caller's, i.e. a SSE4 + function can inline a SSE2 function but a SSE2 function can't inline + a SSE4 function. */ + if (((caller_opts->x_ix86_isa_flags & callee_opts->x_ix86_isa_flags) + != callee_opts->x_ix86_isa_flags) + || ((caller_opts->x_ix86_isa_flags2 & callee_opts->x_ix86_isa_flags2) + != callee_opts->x_ix86_isa_flags2)) + ret = false; - /* See if we have the same non-isa options. */ - else if (caller_opts->x_target_flags != callee_opts->x_target_flags) - ret = false; + /* See if we have the same non-isa options. */ + else if (caller_opts->x_target_flags != callee_opts->x_target_flags) + ret = false; - /* See if arch, tune, etc. are the same. */ - else if (caller_opts->arch != callee_opts->arch) - ret = false; + /* See if arch, tune, etc. are the same. */ + else if (caller_opts->arch != callee_opts->arch) + ret = false; - else if (caller_opts->tune != callee_opts->tune) - ret = false; + else if (caller_opts->tune != callee_opts->tune) + ret = false; - else if (caller_opts->x_ix86_fpmath != callee_opts->x_ix86_fpmath - /* If the calle doesn't use FP expressions differences in - ix86_fpmath can be ignored. We are called from FEs - for multi-versioning call optimization, so beware of - ipa_fn_summaries not available. */ - && (! ipa_fn_summaries - || ipa_fn_summaries->get - (cgraph_node::get (callee))->fp_expressions)) - ret = false; + else if (caller_opts->x_ix86_fpmath != callee_opts->x_ix86_fpmath + /* If the calle doesn't use FP expressions differences in + ix86_fpmath can be ignored. We are called from FEs + for multi-versioning call optimization, so beware of + ipa_fn_summaries not available. */ + && (! ipa_fn_summaries + || ipa_fn_summaries->get + (cgraph_node::get (callee))->fp_expressions)) + ret = false; - else if (caller_opts->branch_cost != callee_opts->branch_cost) - ret = false; + else if (caller_opts->branch_cost != callee_opts->branch_cost) + ret = false; - else - ret = true; - } + else + ret = true; return ret; } diff --git a/gcc/targhooks.c b/gcc/targhooks.c index 6a8fae656d0..2adabcd9777 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -1442,27 +1442,18 @@ default_target_option_pragma_parse (tree ARG_UNUSED (args), bool default_target_can_inline_p (tree caller, tree callee) { - bool ret = false; tree callee_opts = DECL_FUNCTION_SPECIFIC_TARGET (callee); tree caller_opts = DECL_FUNCTION_SPECIFIC_TARGET (caller); - - /* If callee has no option attributes, then it is ok to inline */ - if (!callee_opts) - ret = true; - - /* If caller has no option attributes, but callee does then it is not ok to - inline */ - else if (!caller_opts) - ret = false; + if (! callee_opts) + callee_opts = target_option_default_node; + if (! caller_opts) + caller_opts = target_option_default_node; /* If both caller and callee have attributes, assume that if the pointer is different, the two functions have different target options since build_target_option_node uses a hash table for the options. */ - else - ret = (callee_opts == caller_opts); - - return ret; + return callee_opts == caller_opts; } /* If the machine does not have a case insn that compares the bounds, diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 158f523fe17..115d44550ad 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-08-23 Richard Biener + + PR target/81921 + * gcc.target/i386/pr81921.c: New testcase. + 2017-08-23 Daniel Santos * gcc.target/i386/pr80969-1.c: New testcase. diff --git a/gcc/testsuite/gcc.target/i386/pr81921.c b/gcc/testsuite/gcc.target/i386/pr81921.c new file mode 100644 index 00000000000..332c0b81a35 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr81921.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target lto } */ +/* { dg-options "-flto -march=x86-64" } */ + +extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__, target("sse2"))) +_mm_loadu_si128 (int const *__P) +{ + return *__P; +} + +void __attribute__((target("ssse3"))) foo (void *p) +{ + volatile int x = _mm_loadu_si128 (p); +}