https://gcc.gnu.org/g:f9c01c47f8e5451e41a5df78f044d7b1e7b3d5d6

commit r16-5466-gf9c01c47f8e5451e41a5df78f044d7b1e7b3d5d6
Author: Josef Melcr <[email protected]>
Date:   Thu Nov 20 23:57:57 2025 +0100

    ipa: Remove LTO requirement for builtin callback carriers.
    
    Due to the if statement in ipa_compute_jump_functions_for_bb, callback
    edges were never constructed for builtin functions unless LTO was
    enabled.  This patch corrects this behavior, allowing GCC to optimize
    callbacks more broadly.  It also extends our testing capabilities.
    
    gcc/ChangeLog:
    
            * attr-callback.cc (callback_edge_callee_has_attr): New
            function.
            * attr-callback.h (callback_edge_callee_has_attr): New function
            decl.
            * ipa-prop.cc (ipa_compute_jump_functions_for_bb): Don't skip
            callback carriers when calculating jump functions.
    
    libgomp/ChangeLog:
    
            * testsuite/libgomp.c/ipcp-cb-spec1.c: Remove LTO requirement.
            * testsuite/libgomp.c/ipcp-cb-spec2.c: Likewise.
            * testsuite/libgomp.c/ipcp-cb1.c: Likewise.
    
    Signed-off-by: Josef Melcr <[email protected]>

Diff:
---
 gcc/attr-callback.cc                        | 9 +++++++++
 gcc/attr-callback.h                         | 3 +++
 gcc/ipa-prop.cc                             | 3 ++-
 libgomp/testsuite/libgomp.c/ipcp-cb-spec1.c | 5 ++---
 libgomp/testsuite/libgomp.c/ipcp-cb-spec2.c | 3 +--
 libgomp/testsuite/libgomp.c/ipcp-cb1.c      | 7 +++----
 6 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/gcc/attr-callback.cc b/gcc/attr-callback.cc
index 04b5ad0ef119..f116f0472f32 100644
--- a/gcc/attr-callback.cc
+++ b/gcc/attr-callback.cc
@@ -83,6 +83,15 @@ callback_special_case_attr (tree decl)
   gcc_unreachable ();
 }
 
+/* Returns TRUE if the callee of E has a callback attribute.  */
+bool
+callback_edge_callee_has_attr (cgraph_edge *e)
+{
+  return lookup_attribute (CALLBACK_ATTR_IDENT,
+                          DECL_ATTRIBUTES (e->callee->decl))
+        || callback_is_special_cased (e->callee->decl, e->call_stmt);
+}
+
 /* Given an instance of callback attribute, return the 0-based
    index of the called function in question.  */
 int
diff --git a/gcc/attr-callback.h b/gcc/attr-callback.h
index b0b08438afbe..39a4fe8ac94e 100644
--- a/gcc/attr-callback.h
+++ b/gcc/attr-callback.h
@@ -43,6 +43,9 @@ bool callback_is_special_cased (tree decl, gcall *stmt);
 /* Returns an attribute for a special cased function.  */
 tree callback_special_case_attr (tree decl);
 
+/* Returns TRUE if the callee of E has a callback attribute.  */
+bool callback_edge_callee_has_attr (cgraph_edge *e);
+
 /* Given an instance of callback attribute, return the 0-based
    index of the called function in question.  */
 int callback_get_fn_index (tree cb_attr);
diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc
index 1e4b6d4548d9..2debbe10de38 100644
--- a/gcc/ipa-prop.cc
+++ b/gcc/ipa-prop.cc
@@ -2698,7 +2698,8 @@ ipa_compute_jump_functions_for_bb (struct 
ipa_func_body_info *fbi, basic_block b
          /* We do not need to bother analyzing calls to unknown functions
             unless they may become known during lto/whopr.  */
          if (!callee->definition && !flag_lto
-             && !gimple_call_fnspec (cs->call_stmt).known_p ())
+             && !gimple_call_fnspec (cs->call_stmt).known_p ()
+             && !callback_edge_callee_has_attr (cs))
            continue;
        }
       ipa_compute_jump_functions_for_edge (fbi, cs);
diff --git a/libgomp/testsuite/libgomp.c/ipcp-cb-spec1.c 
b/libgomp/testsuite/libgomp.c/ipcp-cb-spec1.c
index a85e62300f98..ff82f4c2f29d 100644
--- a/libgomp/testsuite/libgomp.c/ipcp-cb-spec1.c
+++ b/libgomp/testsuite/libgomp.c/ipcp-cb-spec1.c
@@ -1,9 +1,8 @@
 /* Test that GOMP_task is special cased when cpyfn is NULL.  */
 
 /* { dg-do run } */
-/* { dg-options "-O3 -fopenmp -flto -std=gnu99 -fdump-ipa-cp-details" } */
+/* { dg-options "-O3 -fopenmp -std=gnu99 -fdump-ipa-cp-details" } */
 /* { dg-require-effective-target fopenmp } */
-/* { dg-require-effective-target lto } */
 
 void test(int c) {
   for (int i = 0; i < c; i++)
@@ -16,4 +15,4 @@ int main() {
   return 0;
 }
 
-/* { dg-final { scan-wpa-ipa-dump "Creating a specialized node of 
main._omp_fn" "cp" } } */
+/* { dg-final { scan-ipa-dump "Creating a specialized node of main._omp_fn" 
"cp" } } */
diff --git a/libgomp/testsuite/libgomp.c/ipcp-cb-spec2.c 
b/libgomp/testsuite/libgomp.c/ipcp-cb-spec2.c
index 01d7425c99f9..30894d7d748b 100644
--- a/libgomp/testsuite/libgomp.c/ipcp-cb-spec2.c
+++ b/libgomp/testsuite/libgomp.c/ipcp-cb-spec2.c
@@ -2,9 +2,8 @@
    NULL.  */
 
 /* { dg-do run } */
-/* { dg-options "-O3 -fopenmp -flto -std=gnu99 -fdump-ipa-cp-details" } */
+/* { dg-options "-O3 -fopenmp -std=gnu99 -fdump-ipa-cp-details" } */
 /* { dg-require-effective-target fopenmp } */
-/* { dg-require-effective-target lto } */
 
 void test(int *a) {
   for (int i = 0; i < 100; i++) {
diff --git a/libgomp/testsuite/libgomp.c/ipcp-cb1.c 
b/libgomp/testsuite/libgomp.c/ipcp-cb1.c
index 3418b5dedab2..e390f04d8cf3 100644
--- a/libgomp/testsuite/libgomp.c/ipcp-cb1.c
+++ b/libgomp/testsuite/libgomp.c/ipcp-cb1.c
@@ -2,9 +2,8 @@
    This tests the underlying callback attribute and its related edges.  */
 
 /* { dg-do run } */
-/* { dg-options "-O3 -fopenmp -flto -std=gnu99 -fdump-ipa-cp-details" } */
+/* { dg-options "-O3 -fopenmp -std=gnu99 -fdump-ipa-cp-details" } */
 /* { dg-require-effective-target fopenmp } */
-/* { dg-require-effective-target lto } */
 
 int a[100];
 void test(int c) {
@@ -21,5 +20,5 @@ int main() {
   return a[5] - 5;
 }
 
-/* { dg-final { scan-wpa-ipa-dump "Creating a specialized node of 
test._omp_fn" "cp" } } */
-/* { dg-final { scan-wpa-ipa-dump "Aggregate replacements: 
0\\\[0]=100\\(by_ref\\)" "cp" } } */
+/* { dg-final { scan-ipa-dump "Creating a specialized node of test._omp_fn" 
"cp" } } */
+/* { dg-final { scan-ipa-dump "Aggregate replacements: 
0\\\[0]=100\\(by_ref\\)" "cp" } } */

Reply via email to