https://gcc.gnu.org/g:00cc9725634f5547bbe29e0b7f94b87d0fe03e4b

commit r15-9586-g00cc9725634f5547bbe29e0b7f94b87d0fe03e4b
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Tue Apr 22 21:27:28 2025 +0200

    rs6000: Ignore OPTION_MASK_SAVE_TOC_INDIRECT differences in inlining 
decisions [PR119327]
    
    The following testcase FAILs because the always_inline function can't
    be inlined.
    The rs6000 backend has similarly to other targets a hook which rejects
    inlining which would bring in new ISAs which aren't there in the caller.
    And this hook rejects this because of OPTION_MASK_SAVE_TOC_INDIRECT
    differences.
    This flag is set if explicitly requested or by default depending on
    whether the current function looks hot (or at least not cold):
      if ((rs6000_isa_flags_explicit & OPTION_MASK_SAVE_TOC_INDIRECT) == 0
          && flag_shrink_wrap_separate
          && optimize_function_for_speed_p (cfun))
        rs6000_isa_flags |= OPTION_MASK_SAVE_TOC_INDIRECT;
    The target nodes that are being compared here are actually the default
    target node (which was created when cfun was NULL) vs. one that was
    created for the always_inline function when it wasn't NULL, so one
    doesn't have it, the other does.
    In any case, this flag feels like a tuning decision rather than hard
    ISA requirement and I see no problems why we couldn't inline
    even explicit -msave-toc-indirect function into -mno-save-toc-indirect
    or vice versa.
    We already ignore OPTION_MASK_P{8,10}_FUSION which are also more
    like tuning flags.
    
    2025-04-22  Jakub Jelinek  <ja...@redhat.com>
    
            PR target/119327
            * config/rs6000/rs6000.cc (rs6000_can_inline_p): Ignore also
            OPTION_MASK_SAVE_TOC_INDIRECT differences.
    
            * g++.dg/opt/pr119327.C: New test.
    
    (cherry picked from commit 4b62cf555b5446cb02fc471519cf1afa09e1a108)

Diff:
---
 gcc/config/rs6000/rs6000.cc         | 11 +++++++----
 gcc/testsuite/g++.dg/opt/pr119327.C | 16 ++++++++++++++++
 2 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index 737c3d6f7c75..12dbde2bc630 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -25765,10 +25765,13 @@ rs6000_can_inline_p (tree caller, tree callee)
        }
     }
 
-  /* Ignore -mpower8-fusion and -mpower10-fusion options for inlining
-     purposes.  */
-  callee_isa &= ~(OPTION_MASK_P8_FUSION | OPTION_MASK_P10_FUSION);
-  explicit_isa &= ~(OPTION_MASK_P8_FUSION | OPTION_MASK_P10_FUSION);
+  /* Ignore -mpower8-fusion, -mpower10-fusion and -msave-toc-indirect options
+     for inlining purposes.  */
+  HOST_WIDE_INT ignored_isas = (OPTION_MASK_P8_FUSION
+                               | OPTION_MASK_P10_FUSION
+                               | OPTION_MASK_SAVE_TOC_INDIRECT);
+  callee_isa &= ~ignored_isas;
+  explicit_isa &= ~ignored_isas;
 
   /* The callee's options must be a subset of the caller's options, i.e.
      a vsx function may inline an altivec function, but a no-vsx function
diff --git a/gcc/testsuite/g++.dg/opt/pr119327.C 
b/gcc/testsuite/g++.dg/opt/pr119327.C
new file mode 100644
index 000000000000..598ae1c8bfeb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr119327.C
@@ -0,0 +1,16 @@
+// PR target/119327
+// { dg-do compile { target c++11 } }
+// { dg-options "-Os" }
+
+#pragma GCC optimize "fp-contract=off"
+
+template <class T>
+void
+foo (T f)
+{
+  f ();
+}
+
+struct S {
+  S () { [] {}; foo ([] __attribute__((always_inline)) {}); }
+} s;

Reply via email to