]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
rs6000: Ignore OPTION_MASK_SAVE_TOC_INDIRECT differences in inlining decisions [PR119327]
authorJakub Jelinek <jakub@redhat.com>
Tue, 22 Apr 2025 19:27:28 +0000 (21:27 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 13 Jun 2025 11:10:21 +0000 (13:10 +0200)
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  <jakub@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)

gcc/config/rs6000/rs6000.cc
gcc/testsuite/g++.dg/opt/pr119327.C [new file with mode: 0644]

index cf0d089d06ba127b0625460726141172d0ad22d1..c1bb212a637b0589f6343453e8851460f16587e3 100644 (file)
@@ -25326,10 +25326,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 (file)
index 0000000..598ae1c
--- /dev/null
@@ -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;