aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2017-08-24 13:44:35 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2017-08-24 13:44:35 +0000
commit9b25e12d2d940a61ec97fdc3e5c1fe6060e159f8 (patch)
tree6b24e2669374d96abfb136318095097a99da7990 /gcc
parent5d52d2c949fe6277fd1f31be8d6f48e1dae06652 (diff)
downloadgcc-9b25e12d2d940a61ec97fdc3e5c1fe6060e159f8.zip
gcc-9b25e12d2d940a61ec97fdc3e5c1fe6060e159f8.tar.gz
gcc-9b25e12d2d940a61ec97fdc3e5c1fe6060e159f8.tar.bz2
re PR target/81921 (Fails to always-inline intrinsics with -flto)
2017-08-23 Richard Biener <rguenther@suse.de> 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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/config/i386/i386.c90
-rw-r--r--gcc/targhooks.c19
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/i386/pr81921.c14
5 files changed, 72 insertions, 67 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6726127..cca96ed 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+2017-08-23 Richard Biener <rguenther@suse.de>
+
+ 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 <rguenther@suse.de>
PR debug/81936
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 268946b..b5c113d 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 6a8fae6..2adabcd 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 158f523..115d445 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2017-08-23 Richard Biener <rguenther@suse.de>
+
+ PR target/81921
+ * gcc.target/i386/pr81921.c: New testcase.
+
2017-08-23 Daniel Santos <daniel.santos@pobox.com>
* 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 0000000..332c0b8
--- /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);
+}