aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/i386/i386.c27
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/i386/pr71991.c10
4 files changed, 45 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4a3f07f..bc3a749 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2018-04-13 Jan Hubicka <hubicka@ucw.cz>
+
+ PR lto/71991
+ * config/i386/i386.c (ix86_can_inline_p): Allow safe transitions for
+ always inline.
+
2018-04-13 Martin Liska <mliska@suse.cz>
Jakub Jelinek <jakub@redhat.com>
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 03e5c43..99ac84e 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -5766,6 +5766,19 @@ ix86_can_inline_p (tree caller, tree callee)
{
tree caller_tree = DECL_FUNCTION_SPECIFIC_TARGET (caller);
tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (callee);
+
+ /* Changes of those flags can be tolerated for always inlines. Lets hope
+ user knows what he is doing. */
+ const unsigned HOST_WIDE_INT always_inline_safe_mask
+ = (MASK_USE_8BIT_IDIV | MASK_ACCUMULATE_OUTGOING_ARGS
+ | MASK_NO_ALIGN_STRINGOPS | MASK_AVX256_SPLIT_UNALIGNED_LOAD
+ | MASK_AVX256_SPLIT_UNALIGNED_STORE | MASK_CLD
+ | MASK_NO_FANCY_MATH_387 | MASK_IEEE_FP | MASK_INLINE_ALL_STRINGOPS
+ | MASK_INLINE_STRINGOPS_DYNAMICALLY | MASK_RECIP | MASK_STACK_PROBE
+ | MASK_STV | MASK_TLS_DIRECT_SEG_REFS | MASK_VZEROUPPER
+ | MASK_NO_PUSH_ARGS | MASK_OMIT_LEAF_FRAME_POINTER);
+
+
if (!callee_tree)
callee_tree = target_option_default_node;
if (!caller_tree)
@@ -5776,6 +5789,10 @@ ix86_can_inline_p (tree caller, tree callee)
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;
+ bool always_inline =
+ (DECL_DISREGARD_INLINE_LIMITS (callee)
+ && lookup_attribute ("always_inline",
+ DECL_ATTRIBUTES (callee)));
/* 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
@@ -5787,14 +5804,17 @@ ix86_can_inline_p (tree caller, tree callee)
ret = false;
/* See if we have the same non-isa options. */
- else if (caller_opts->x_target_flags != callee_opts->x_target_flags)
+ else if ((!always_inline
+ && caller_opts->x_target_flags != callee_opts->x_target_flags)
+ || (caller_opts->x_target_flags & ~always_inline_safe_mask)
+ != (callee_opts->x_target_flags & ~always_inline_safe_mask))
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)
+ else if (!always_inline && caller_opts->tune != callee_opts->tune)
ret = false;
else if (caller_opts->x_ix86_fpmath != callee_opts->x_ix86_fpmath
@@ -5807,7 +5827,8 @@ ix86_can_inline_p (tree caller, tree callee)
(cgraph_node::get (callee))->fp_expressions))
ret = false;
- else if (caller_opts->branch_cost != callee_opts->branch_cost)
+ else if (!always_inline
+ && caller_opts->branch_cost != callee_opts->branch_cost)
ret = false;
else
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 665a3d8..20b3d2c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2018-04-13 Jan Hubicka <hubicka@ucw.cz>
+
+ PR lto/71991
+ * gcc.target/i386/pr71991.c: New testcase.
+
2018-04-13 Martin Liska <mliska@suse.cz>
Jakub Jelinek <jakub@redhat.com>
diff --git a/gcc/testsuite/gcc.target/i386/pr71991.c b/gcc/testsuite/gcc.target/i386/pr71991.c
new file mode 100644
index 0000000..9d70a1c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr71991.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+static inline __attribute__ ((__always_inline__)) int fn1 () { return 0; }
+static __attribute__ ((target ("inline-all-stringops"))) int fn2 () { fn1 (); }
+
+int main()
+{
+ fn2();
+}
+