re PR target/71991 (Inconsistency for __attribute__ ((__always_inline__)) among LTO...
authorJan Hubicka <hubicka@ucw.cz>
Fri, 13 Apr 2018 08:51:47 +0000 (10:51 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Fri, 13 Apr 2018 08:51:47 +0000 (08:51 +0000)
PR lto/71991
* config/i386/i386.c (ix86_can_inline_p): Allow safe transitions for
always inline.
* gcc.target/i386/pr71991.c: New testcase.

From-SVN: r259367

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr71991.c [new file with mode: 0644]

index 4a3f07f..bc3a749 100644 (file)
@@ -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>
 
index 03e5c43..99ac84e 100644 (file)
@@ -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
index 665a3d8..20b3d2c 100644 (file)
@@ -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 (file)
index 0000000..9d70a1c
--- /dev/null
@@ -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();
+}
+