[gcc r12-10475] ipa: Compare jump functions in ICF (PR 113907)
https://gcc.gnu.org/g:72f6b7ec3915f0b5b3517dffa19e3b34c8af687d commit r12-10475-g72f6b7ec3915f0b5b3517dffa19e3b34c8af687d Author: Martin Jambor Date: Tue May 28 13:33:02 2024 +0200 ipa: Compare jump functions in ICF (PR 113907) This is a manual backport of r14-9840-g1162861439fd3c from master. Manual because the bits and value range representation in jump functions have changes during the gcc 14 development cycle. In PR 113907 comment #58, Honza found a case where ICF thinks bodies of functions are equivalent but becaise of difference in aliases in a memory access, different aggregate jump functions are associated with supposedly equivalent call statements. This patch adds a way to compare jump functions and plugs it into ICF to avoid the issue. gcc/ChangeLog: 2024-05-14 Martin Jambor PR ipa/113907 * ipa-prop.h (ipa_jump_functions_equivalent_p): Declare. (values_equal_for_ipcp_p): Likewise. * ipa-prop.cc (ipa_agg_pass_through_jf_equivalent_p): New function. (ipa_agg_jump_functions_equivalent_p): Likewise. (ipa_jump_functions_equivalent_p): Likewise. * ipa-cp.cc (values_equal_for_ipcp_p): Make function public. * ipa-icf-gimple.cc: Include alloc-pool.h, symbol-summary.h, sreal.h, ipa-cp.h and ipa-prop.h. (func_checker::compare_gimple_call): Comapre jump functions. gcc/testsuite/ChangeLog: 2024-05-10 Martin Jambor PR ipa/113907 * gcc.dg/lto/pr113907_0.c: New. * gcc.dg/lto/pr113907_1.c: Likewise. * gcc.dg/lto/pr113907_2.c: Likewise. (cherry picked from commit 1db45e83021a8a87f41e22053910fcce6e8e2c2c) Diff: --- gcc/ipa-cp.cc | 2 +- gcc/ipa-icf-gimple.cc | 29 +++ gcc/ipa-prop.cc | 157 ++ gcc/ipa-prop.h| 3 + gcc/testsuite/gcc.dg/lto/pr113907_0.c | 18 gcc/testsuite/gcc.dg/lto/pr113907_1.c | 35 gcc/testsuite/gcc.dg/lto/pr113907_2.c | 11 +++ 7 files changed, 254 insertions(+), 1 deletion(-) diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc index fbb31f6dff2..909464f4ac4 100644 --- a/gcc/ipa-cp.cc +++ b/gcc/ipa-cp.cc @@ -1402,7 +1402,7 @@ ipacp_value_safe_for_type (tree param_type, tree value) /* Return true iff X and Y should be considered equal values by IPA-CP. */ -static bool +bool values_equal_for_ipcp_p (tree x, tree y) { gcc_checking_assert (x != NULL_TREE && y != NULL_TREE); diff --git a/gcc/ipa-icf-gimple.cc b/gcc/ipa-icf-gimple.cc index ab398ca051c..e81409c16f9 100644 --- a/gcc/ipa-icf-gimple.cc +++ b/gcc/ipa-icf-gimple.cc @@ -41,7 +41,11 @@ along with GCC; see the file COPYING3. If not see #include "gimple-walk.h" #include "tree-ssa-alias-compare.h" +#include "alloc-pool.h" +#include "symbol-summary.h" #include "ipa-icf-gimple.h" +#include "sreal.h" +#include "ipa-prop.h" namespace ipa_icf_gimple { @@ -714,6 +718,31 @@ func_checker::compare_gimple_call (gcall *s1, gcall *s2) && !compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2))) return return_false_with_msg ("GIMPLE internal call LHS type mismatch"); + if (!gimple_call_internal_p (s1)) +{ + cgraph_edge *e1 = cgraph_node::get (m_source_func_decl)->get_edge (s1); + cgraph_edge *e2 = cgraph_node::get (m_target_func_decl)->get_edge (s2); + class ipa_edge_args *args1 = ipa_edge_args_sum->get (e1); + class ipa_edge_args *args2 = ipa_edge_args_sum->get (e2); + if ((args1 != nullptr) != (args2 != nullptr)) + return return_false_with_msg ("ipa_edge_args mismatch"); + if (args1) + { + int n1 = ipa_get_cs_argument_count (args1); + int n2 = ipa_get_cs_argument_count (args2); + if (n1 != n2) + return return_false_with_msg ("ipa_edge_args nargs mismatch"); + for (int i = 0; i < n1; i++) + { + struct ipa_jump_func *jf1 = ipa_get_ith_jump_func (args1, i); + struct ipa_jump_func *jf2 = ipa_get_ith_jump_func (args2, i); + if (((jf1 != nullptr) != (jf2 != nullptr)) + || (jf1 && !ipa_jump_functions_equivalent_p (jf1, jf2))) + return return_false_with_msg ("jump function mismatch"); + } + } +} + return compare_operand (t1, t2, get_operand_access_type (, t1)); } diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc index 0197ac6108d..e2e83b5f3f5 100644 --- a/gcc/ipa-prop.cc +++ b/gcc/ipa-prop.cc @@ -6096,6 +6096,163 @@ ipcp_transform_function (struct cgraph_node *node) return modified_mem_access ? TODO_update_ssa_only_virtuals : 0; } +/* Return true if the two pass_through components of two jump functions are + known to be equivalent. AGG_JF denotes whether they are part of aggregate + functions or not. The function can be
[gcc r14-10237] sra: Do not leave work for DSE (that it can sometimes not perform)
https://gcc.gnu.org/g:1a6c1c85b7ab1ad4bdf9573fcdc04dcce894ba82 commit r14-10237-g1a6c1c85b7ab1ad4bdf9573fcdc04dcce894ba82 Author: Martin Jambor Date: Thu May 9 16:39:44 2024 +0200 sra: Do not leave work for DSE (that it can sometimes not perform) When looking again at the g++.dg/tree-ssa/pr109849.C testcase we discovered that it generates terrible store-to-load forwarding stalls because SRA was leaving behind aggregate loads but all the stores were by scalar parts and DSE failed to remove the useless load. SRA has all the knowledge to remove the statement even now, so this small patch makes it do so. With this patch, the g++.dg/tree-ssa/pr109849.C micro-benchmark runs 9 times faster (on an AMD EPYC 75F3 machine). gcc/ChangeLog: 2024-04-18 Martin Jambor * tree-sra.cc (sra_modify_assign): Remove the original statement also when dealing with a store to a fully covered aggregate from a non-candidate. gcc/testsuite/ChangeLog: 2024-04-23 Martin Jambor * g++.dg/tree-ssa/pr109849.C: Also check that the aggeegate store to cur disappears. * gcc.dg/tree-ssa/ssa-dse-26.c: Instead of relying on DSE, check that the unwanted stores were removed at early SRA time. (cherry picked from commit f6743695b4d2bd4da96e56a19157372f93b800bd) Diff: --- gcc/testsuite/g++.dg/tree-ssa/pr109849.C | 3 ++- gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c | 6 +++--- gcc/tree-sra.cc| 14 -- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr109849.C b/gcc/testsuite/g++.dg/tree-ssa/pr109849.C index cd348c0f590..d06dbb10482 100644 --- a/gcc/testsuite/g++.dg/tree-ssa/pr109849.C +++ b/gcc/testsuite/g++.dg/tree-ssa/pr109849.C @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-sra" } */ +/* { dg-options "-O2 -fdump-tree-sra -fdump-tree-optimized" } */ #include typedef unsigned int uint32_t; @@ -29,3 +29,4 @@ main() } /* { dg-final { scan-tree-dump "Created a replacement for stack offset" "sra"} } */ +/* { dg-final { scan-tree-dump-not "cur = MEM" "optimized"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c index 43152de5616..1d01392c595 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-dse1-details -fno-short-enums -fno-tree-fre" } */ +/* { dg-options "-O2 -fdump-tree-esra -fno-short-enums -fno-tree-fre" } */ /* { dg-skip-if "we want a BIT_FIELD_REF from fold_truth_andor" { ! lp64 } } */ /* { dg-skip-if "temporary variable names are not x and y" { mmix-knuth-mmixware } } */ @@ -31,5 +31,5 @@ constraint_equal (struct constraint a, struct constraint b) && constraint_expr_equal (a.rhs, b.rhs); } -/* { dg-final { scan-tree-dump-times "Deleted dead store: x = " 2 "dse1" } } */ -/* { dg-final { scan-tree-dump-times "Deleted dead store: y = " 2 "dse1" } } */ +/* { dg-final { scan-tree-dump-not "x = " "esra" } } */ +/* { dg-final { scan-tree-dump-not "y = " "esra" } } */ diff --git a/gcc/tree-sra.cc b/gcc/tree-sra.cc index 32fa28911f2..8040b0c5645 100644 --- a/gcc/tree-sra.cc +++ b/gcc/tree-sra.cc @@ -4854,8 +4854,18 @@ sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi) But use the RHS aggregate to load from to expose more optimization opportunities. */ if (access_has_children_p (lacc)) - generate_subtree_copies (lacc->first_child, rhs, lacc->offset, -0, 0, gsi, true, true, loc); + { + generate_subtree_copies (lacc->first_child, rhs, lacc->offset, + 0, 0, gsi, true, true, loc); + if (lacc->grp_covered) + { + unlink_stmt_vdef (stmt); + gsi_remove (& orig_gsi, true); + release_defs (stmt); + sra_stats.deleted++; + return SRA_AM_REMOVED; + } + } } return SRA_AM_NONE;
[gcc r13-8785] testsuite: Adjust pr113359-2_*.c with unsigned long long [PR114662]
https://gcc.gnu.org/g:c827f46d8652d7a089e614302a4cffb6b192284d commit r13-8785-gc827f46d8652d7a089e614302a4cffb6b192284d Author: Kewen Lin Date: Wed Apr 10 02:59:43 2024 -0500 testsuite: Adjust pr113359-2_*.c with unsigned long long [PR114662] pr113359-2_*.c define a struct having unsigned long type members ay and az which have 4 bytes size at -m32, while the related constants CL1 and CL2 used for equality check are always 8 bytes, it makes compiler consider the below 69 if (a.ay != CL1) 70 __builtin_abort (); always to abort and optimize away the following call to getb, which leads to the expected wpa dumping on "Semantic equality" missing. This patch is to modify the types with unsigned long long accordingly. PR testsuite/114662 gcc/testsuite/ChangeLog: * gcc.dg/lto/pr113359-2_0.c: Use unsigned long long instead of unsigned long. * gcc.dg/lto/pr113359-2_1.c: Likewise. (cherry picked from commit 4923ed49b93352bcf9e43cafac38345e4a54c3f8) Diff: --- gcc/testsuite/gcc.dg/lto/pr113359-2_0.c | 8 gcc/testsuite/gcc.dg/lto/pr113359-2_1.c | 8 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/gcc/testsuite/gcc.dg/lto/pr113359-2_0.c b/gcc/testsuite/gcc.dg/lto/pr113359-2_0.c index 8b2d5bdfab2..8495667599d 100644 --- a/gcc/testsuite/gcc.dg/lto/pr113359-2_0.c +++ b/gcc/testsuite/gcc.dg/lto/pr113359-2_0.c @@ -8,15 +8,15 @@ struct SA { unsigned int ax; - unsigned long ay; - unsigned long az; + unsigned long long ay; + unsigned long long az; }; struct SB { unsigned int bx; - unsigned long by; - unsigned long bz; + unsigned long long by; + unsigned long long bz; }; struct ZA diff --git a/gcc/testsuite/gcc.dg/lto/pr113359-2_1.c b/gcc/testsuite/gcc.dg/lto/pr113359-2_1.c index 61bc0547981..8320f347efe 100644 --- a/gcc/testsuite/gcc.dg/lto/pr113359-2_1.c +++ b/gcc/testsuite/gcc.dg/lto/pr113359-2_1.c @@ -5,15 +5,15 @@ struct SA { unsigned int ax; - unsigned long ay; - unsigned long az; + unsigned long long ay; + unsigned long long az; }; struct SB { unsigned int bx; - unsigned long by; - unsigned long bz; + unsigned long long by; + unsigned long long bz; }; struct ZA
[gcc r12-10443] ipa: Self-DCE of uses of removed call LHSs (PR 108007)
https://gcc.gnu.org/g:2183e5b5aa3a080624cb95a06993e34dedd09cb2 commit r12-10443-g2183e5b5aa3a080624cb95a06993e34dedd09cb2 Author: Martin Jambor Date: Mon Apr 8 17:34:33 2024 +0200 ipa: Self-DCE of uses of removed call LHSs (PR 108007) PR 108007 is another manifestation where we rely on DCE to clean-up after IPA-SRA and if the user explicitely switches DCE off, IPA-SRA can leave behind statements which are fed uninitialized values and trap, even though their results are themselves never used. I have already fixed this for unused parameters in callees, this bug shows that almost the same thing can happen for removed returns, on the side of callers. This means that the issue has to be fixed elsewhere, in call redirection. This patch adds a function which looks for (and through, using a work-list) uses of operations fed specific SSA names and removes them all. That would have been easy if it wasn't for debug statements during tree-inline (from which call redirection is also invoked). Debug statements are decoupled from the rest at this point and iterating over uses of SSAs does not bring them up. During tree-inline they are handled especially at the end, I assume in order to make sure that relative ordering of UIDs are the same with and without debug info. This means that during tree-inline we need to make a hash of killed SSAs, that we already have in copy_body_data, available to the function making the purging. So the patch duly does also that, making the interface slightly ugly. Moreover, all newly unused SSA names need to be freed and as PR 112616 showed, it must be done in a defined order, which is what newly added ipa_release_ssas_in_hash does. This backport to gcc-13 also contains 54e505d0446f86b7ad383acbb8e5501f20872b64 in order not to reintroduce PR 113757. gcc/ChangeLog: 2024-04-05 Martin Jambor PR ipa/108007 PR ipa/112616 * cgraph.h (cgraph_edge): Add a parameter to redirect_call_stmt_to_callee. * ipa-param-manipulation.h (ipa_param_adjustments): Add a parameter to modify_call. (ipa_release_ssas_in_hash): Declare. * cgraph.cc (cgraph_edge::redirect_call_stmt_to_callee): New parameter killed_ssas, pass it to padjs->modify_call. * ipa-param-manipulation.cc (purge_all_uses): New function. (ipa_param_adjustments::modify_call): New parameter killed_ssas. Instead of substituting uses, invoke purge_all_uses. If hash of killed SSAs has not been provided, create a temporary one and release SSAs that have been added to it. (compare_ssa_versions): New function. (ipa_release_ssas_in_hash): Likewise. * tree-inline.cc (redirect_all_calls): Create id->killed_new_ssa_names earlier, pass it to edge redirection, adjust a comment. (copy_body): Release SSAs in id->killed_new_ssa_names. gcc/testsuite/ChangeLog: 2024-01-15 Martin Jambor PR ipa/108007 PR ipa/112616 * gcc.dg/ipa/pr108007.c: New test. * gcc.dg/ipa/pr112616.c: Likewise. (cherry picked from commit 40ddc0b05a47f999b24f20c1becb79004995731b) Diff: --- gcc/cgraph.cc | 10 +++- gcc/cgraph.h| 9 ++- gcc/ipa-param-manipulation.cc | 112 +--- gcc/ipa-param-manipulation.h| 5 +- gcc/testsuite/g++.dg/ipa/pr113757.C | 14 + gcc/testsuite/gcc.dg/ipa/pr108007.c | 32 +++ gcc/testsuite/gcc.dg/ipa/pr112616.c | 28 + gcc/tree-inline.cc | 27 - 8 files changed, 193 insertions(+), 44 deletions(-) diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc index 3734c85db637..b5cfa3b36c57 100644 --- a/gcc/cgraph.cc +++ b/gcc/cgraph.cc @@ -1403,11 +1403,17 @@ cgraph_edge::redirect_callee (cgraph_node *n) speculative indirect call, remove "speculative" of the indirect call and also redirect stmt to it's final direct target. + When called from within tree-inline, KILLED_SSAs has to contain the pointer + to killed_new_ssa_names within the copy_body_data structure and SSAs + discovered to be useless (if LHS is removed) will be added to it, otherwise + it needs to be NULL. + It is up to caller to iteratively transform each "speculative" direct call as appropriate. */ gimple * -cgraph_edge::redirect_call_stmt_to_callee (cgraph_edge *e) +cgraph_edge::redirect_call_stmt_to_callee (cgraph_edge *e, + hash_set *killed_ssas) { tree decl = gimple_call_fndecl (e->call_stmt); gcall *new_stmt; @@ -1528,7 +1534,7 @@ cgraph_edge::redirect_call_stmt_to_callee (cgraph_edge *e) remove_stmt_from_eh_lp
[gcc r12-10442] ipa: Force args obtined through pass-through maps to the expected type (PR 114247)
https://gcc.gnu.org/g:44191982c6bd41db1c9d126ea2f15febec3c1f81 commit r12-10442-g44191982c6bd41db1c9d126ea2f15febec3c1f81 Author: Martin Jambor Date: Tue May 14 14:13:36 2024 +0200 ipa: Force args obtined through pass-through maps to the expected type (PR 114247) Interactions of IPA-CP and IPA-SRA on the same data is a rather big source of issues, I'm afraid. PR 113964 is a situation where IPA-CP propagates an unsigned short in a union parameter into a function which itself calls a different function which has a same union parameter and both these union parameters are split with IPA-SRA. The leaf function however uses a signed short member of the union. In the calling function, we get the unsigned constant as the replacement for the union and it is then passed in the call without any type compatibility checks. Apparently on riscv64 it matters whether the parameter is signed or unsigned short and so the leaf function can see different values. Fixed by using useless_type_conversion_p at the appropriate place and if it fails, use force_value_to type as elsewhere in similar situations. gcc/ChangeLog: 2024-04-04 Martin Jambor PR ipa/114247 * ipa-param-manipulation.cc (ipa_param_adjustments::modify_call): Force values obtined through pass-through maps to the expected split type. gcc/testsuite/ChangeLog: 2024-04-04 Patrick O'Neill Martin Jambor PR ipa/114247 * gcc.dg/ipa/pr114247.c: New test. (cherry picked from commit 8cd0d29270d4ed86c69b80c08de66dcb6c1e22fe) Diff: --- gcc/ipa-param-manipulation.cc | 6 ++ gcc/testsuite/gcc.dg/ipa/pr114247.c | 31 +++ 2 files changed, 37 insertions(+) diff --git a/gcc/ipa-param-manipulation.cc b/gcc/ipa-param-manipulation.cc index 38328c3e8d0a..3472ef13bc2f 100644 --- a/gcc/ipa-param-manipulation.cc +++ b/gcc/ipa-param-manipulation.cc @@ -719,6 +719,12 @@ ipa_param_adjustments::modify_call (cgraph_edge *cs, } if (repl) { + if (!useless_type_conversion_p(apm->type, repl->typed.type)) + { + repl = force_value_to_type (apm->type, repl); + repl = force_gimple_operand_gsi (, repl, + true, NULL, true, GSI_SAME_STMT); + } vargs.quick_push (repl); continue; } diff --git a/gcc/testsuite/gcc.dg/ipa/pr114247.c b/gcc/testsuite/gcc.dg/ipa/pr114247.c new file mode 100644 index ..60aa2bc0122f --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/pr114247.c @@ -0,0 +1,31 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -fsigned-char -fno-strict-aliasing -fwrapv" } */ + +union a { + unsigned short b; + int c; + signed short d; +}; +int e, f = 1, g; +long h; +const int **i; +void j(union a k, int l, unsigned m) { + const int *a[100]; + i = [0]; + h = k.d; +} +static int o(union a k) { + k.d = -1; + while (1) +if (f) + break; + j(k, g, e); + return 0; +} +int main() { + union a n = {1}; + o(n); + if (h != -1) +__builtin_abort(); + return 0; +}
[gcc r13-8774] ipa: Compare jump functions in ICF (PR 113907)
https://gcc.gnu.org/g:1db45e83021a8a87f41e22053910fcce6e8e2c2c commit r13-8774-g1db45e83021a8a87f41e22053910fcce6e8e2c2c Author: Martin Jambor Date: Tue May 14 17:01:21 2024 +0200 ipa: Compare jump functions in ICF (PR 113907) This is a manual backport of r14-9840-g1162861439fd3c from master. Manual because the bits and value range representation in jump functions have changes during the gcc 14 development cycle. In PR 113907 comment #58, Honza found a case where ICF thinks bodies of functions are equivalent but becaise of difference in aliases in a memory access, different aggregate jump functions are associated with supposedly equivalent call statements. This patch adds a way to compare jump functions and plugs it into ICF to avoid the issue. gcc/ChangeLog: 2024-05-14 Martin Jambor PR ipa/113907 * ipa-prop.h (ipa_jump_functions_equivalent_p): Declare. (values_equal_for_ipcp_p): Likewise. * ipa-prop.cc (ipa_agg_pass_through_jf_equivalent_p): New function. (ipa_agg_jump_functions_equivalent_p): Likewise. (ipa_jump_functions_equivalent_p): Likewise. * ipa-cp.cc (values_equal_for_ipcp_p): Make function public. * ipa-icf-gimple.cc: Include alloc-pool.h, symbol-summary.h, sreal.h, ipa-cp.h and ipa-prop.h. (func_checker::compare_gimple_call): Comapre jump functions. gcc/testsuite/ChangeLog: 2024-05-10 Martin Jambor PR ipa/113907 * gcc.dg/lto/pr113907_0.c: New. * gcc.dg/lto/pr113907_1.c: Likewise. * gcc.dg/lto/pr113907_2.c: Likewise. Diff: --- gcc/ipa-cp.cc | 2 +- gcc/ipa-icf-gimple.cc | 29 +++ gcc/ipa-prop.cc | 157 ++ gcc/ipa-prop.h| 3 + gcc/testsuite/gcc.dg/lto/pr113907_0.c | 18 gcc/testsuite/gcc.dg/lto/pr113907_1.c | 35 gcc/testsuite/gcc.dg/lto/pr113907_2.c | 11 +++ 7 files changed, 254 insertions(+), 1 deletion(-) diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc index b3e0f62e4003..8f36608cf33b 100644 --- a/gcc/ipa-cp.cc +++ b/gcc/ipa-cp.cc @@ -458,7 +458,7 @@ ipcp_lattice::is_single_const () /* Return true iff X and Y should be considered equal values by IPA-CP. */ -static bool +bool values_equal_for_ipcp_p (tree x, tree y) { gcc_checking_assert (x != NULL_TREE && y != NULL_TREE); diff --git a/gcc/ipa-icf-gimple.cc b/gcc/ipa-icf-gimple.cc index 49302ad56c65..054a557bd588 100644 --- a/gcc/ipa-icf-gimple.cc +++ b/gcc/ipa-icf-gimple.cc @@ -42,7 +42,11 @@ along with GCC; see the file COPYING3. If not see #include "tree-sra.h" #include "tree-ssa-alias-compare.h" +#include "alloc-pool.h" +#include "symbol-summary.h" #include "ipa-icf-gimple.h" +#include "sreal.h" +#include "ipa-prop.h" namespace ipa_icf_gimple { @@ -751,6 +755,31 @@ func_checker::compare_gimple_call (gcall *s1, gcall *s2) && !compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2))) return return_false_with_msg ("GIMPLE internal call LHS type mismatch"); + if (!gimple_call_internal_p (s1)) +{ + cgraph_edge *e1 = cgraph_node::get (m_source_func_decl)->get_edge (s1); + cgraph_edge *e2 = cgraph_node::get (m_target_func_decl)->get_edge (s2); + class ipa_edge_args *args1 = ipa_edge_args_sum->get (e1); + class ipa_edge_args *args2 = ipa_edge_args_sum->get (e2); + if ((args1 != nullptr) != (args2 != nullptr)) + return return_false_with_msg ("ipa_edge_args mismatch"); + if (args1) + { + int n1 = ipa_get_cs_argument_count (args1); + int n2 = ipa_get_cs_argument_count (args2); + if (n1 != n2) + return return_false_with_msg ("ipa_edge_args nargs mismatch"); + for (int i = 0; i < n1; i++) + { + struct ipa_jump_func *jf1 = ipa_get_ith_jump_func (args1, i); + struct ipa_jump_func *jf2 = ipa_get_ith_jump_func (args2, i); + if (((jf1 != nullptr) != (jf2 != nullptr)) + || (jf1 && !ipa_jump_functions_equivalent_p (jf1, jf2))) + return return_false_with_msg ("jump function mismatch"); + } + } +} + return compare_operand (t1, t2, get_operand_access_type (, t1)); } diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc index 0d8167495341..11ba2521b2c9 100644 --- a/gcc/ipa-prop.cc +++ b/gcc/ipa-prop.cc @@ -6022,5 +6022,162 @@ ipcp_transform_function (struct cgraph_node *node) return modified_mem_access ? TODO_update_ssa_only_virtuals : 0; } +/* Return true if the two pass_through components of two jump functions are + known to be equivalent. AGG_JF denotes whether they are part of aggregate + functions or not. The function can be used before the IPA phase of IPA-CP + or inlining because it cannot cope with refdesc changes these
[gcc r13-8773] ICF: Make ICF and SRA agree on padding
https://gcc.gnu.org/g:10bf53a80eefa46500bffb442719777e2640e7d7 commit r13-8773-g10bf53a80eefa46500bffb442719777e2640e7d7 Author: Martin Jambor Date: Mon Apr 8 18:53:23 2024 +0200 ICF: Make ICF and SRA agree on padding PR 113359 shows that (at least with -fno-strict-aliasing) ICF can unify two functions which copy an aggregate type of the same size but then SRA, through its total scalarization, can copy the aggregate by pieces, skipping paddding, but the padding was not the same in the two original functions that ICF unified. This patch enhances SRA with the ability to collect padding information which then can be compared from within ICF. Unfortunately SRA uses OPTION_SET_P when determining its limits, so ICF needs to switch cfuns at least once to figure it out too. gcc/ChangeLog: 2024-03-27 Martin Jambor PR ipa/113359 * ipa-icf-gimple.h (func_checker): New members safe_for_total_scalarization_p, m_total_scalarization_limit_known_p and m_total_scalarization_limit. (func_checker::func_checker): Initialize new member variables. * ipa-icf-gimple.cc: Include tree-sra.h. (func_checker::func_checker): Initialize new member variables. (func_checker::safe_for_total_scalarization_p): New function. (func_checker::compare_operand): Use the new function. * tree-sra.h (sra_get_max_scalarization_size): Declare. (sra_total_scalarization_would_copy_same_data_p): Likewise. * tree-sra.cc (prepare_iteration_over_array_elts): New function. (class sra_padding_collecting): New. (sra_padding_collecting::record_padding): Likewise. (scalarizable_type_p): Rename to totally_scalarizable_type_p. Add ability to record padding when requested. (totally_scalarize_subtree): Split out gathering information necessary to iterate over array elements to prepare_iteration_over_array_elts. Fix errornous early exit. (analyze_all_variable_accesses): Adjust the call to totally_scalarizable_type_p. Move determining of total scalariation size limit... (sra_get_max_scalarization_size): ...here. (check_ts_and_push_padding_to_vec): New function. (sra_total_scalarization_would_copy_same_data_p): Likewise. gcc/testsuite/ChangeLog: 2024-03-27 Martin Jambor PR ipa/113359 * gcc.dg/lto/pr113359-1_0.c: New. * gcc.dg/lto/pr113359-1_1.c: Likewise. * gcc.dg/lto/pr113359-2_0.c: Likewise. * gcc.dg/lto/pr113359-2_1.c: Likewise. * gcc.dg/lto/pr113359-3_0.c: Likewise. * gcc.dg/lto/pr113359-3_1.c: Likewise. * gcc.dg/lto/pr113359-4_0.c: Likewise. * gcc.dg/lto/pr113359-4_1.c: Likewise. * gcc.dg/lto/pr113359-5_0.c: Likewise. * gcc.dg/lto/pr113359-5_1.c: Likewise. (cherry picked from commit 1e3312a25a7b34d6e3f549273e1674c7114e4408) Diff: --- gcc/ipa-icf-gimple.cc | 41 +- gcc/ipa-icf-gimple.h| 15 +- gcc/testsuite/gcc.dg/lto/pr113359-1_0.c | 86 +++ gcc/testsuite/gcc.dg/lto/pr113359-1_1.c | 38 + gcc/testsuite/gcc.dg/lto/pr113359-2_0.c | 87 +++ gcc/testsuite/gcc.dg/lto/pr113359-2_1.c | 38 + gcc/testsuite/gcc.dg/lto/pr113359-3_0.c | 114 +++ gcc/testsuite/gcc.dg/lto/pr113359-3_1.c | 49 +++ gcc/testsuite/gcc.dg/lto/pr113359-4_0.c | 114 +++ gcc/testsuite/gcc.dg/lto/pr113359-4_1.c | 49 +++ gcc/testsuite/gcc.dg/lto/pr113359-5_0.c | 118 +++ gcc/testsuite/gcc.dg/lto/pr113359-5_1.c | 50 +++ gcc/tree-sra.cc | 252 +--- gcc/tree-sra.h | 3 + 14 files changed, 999 insertions(+), 55 deletions(-) diff --git a/gcc/ipa-icf-gimple.cc b/gcc/ipa-icf-gimple.cc index f4180c0fa813..49302ad56c65 100644 --- a/gcc/ipa-icf-gimple.cc +++ b/gcc/ipa-icf-gimple.cc @@ -39,6 +39,7 @@ along with GCC; see the file COPYING3. If not see #include "cfgloop.h" #include "attribs.h" #include "gimple-walk.h" +#include "tree-sra.h" #include "tree-ssa-alias-compare.h" #include "ipa-icf-gimple.h" @@ -59,7 +60,8 @@ func_checker::func_checker (tree source_func_decl, tree target_func_decl, : m_source_func_decl (source_func_decl), m_target_func_decl (target_func_decl), m_ignored_source_nodes (ignored_source_nodes), m_ignored_target_nodes (ignored_target_nodes), -m_ignore_labels (ignore_labels), m_tbaa (tbaa) +m_ignore_labels (ignore_labels), m_tbaa (tbaa), +m_total_scalarization_limit_known_p (false) { function *source_func = DECL_STRUCT_FUNCTION (source_func_decl); function *target_func = DECL_STRUCT_FUNCTION
[gcc r15-346] sra: Do not leave work for DSE (that it can sometimes not perform)
https://gcc.gnu.org/g:f6743695b4d2bd4da96e56a19157372f93b800bd commit r15-346-gf6743695b4d2bd4da96e56a19157372f93b800bd Author: Martin Jambor Date: Thu May 9 16:39:44 2024 +0200 sra: Do not leave work for DSE (that it can sometimes not perform) When looking again at the g++.dg/tree-ssa/pr109849.C testcase we discovered that it generates terrible store-to-load forwarding stalls because SRA was leaving behind aggregate loads but all the stores were by scalar parts and DSE failed to remove the useless load. SRA has all the knowledge to remove the statement even now, so this small patch makes it do so. With this patch, the g++.dg/tree-ssa/pr109849.C micro-benchmark runs 9 times faster (on an AMD EPYC 75F3 machine). gcc/ChangeLog: 2024-04-18 Martin Jambor * tree-sra.cc (sra_modify_assign): Remove the original statement also when dealing with a store to a fully covered aggregate from a non-candidate. gcc/testsuite/ChangeLog: 2024-04-23 Martin Jambor * g++.dg/tree-ssa/pr109849.C: Also check that the aggeegate store to cur disappears. * gcc.dg/tree-ssa/ssa-dse-26.c: Instead of relying on DSE, check that the unwanted stores were removed at early SRA time. Diff: --- gcc/testsuite/g++.dg/tree-ssa/pr109849.C | 3 ++- gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c | 6 +++--- gcc/tree-sra.cc| 14 -- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr109849.C b/gcc/testsuite/g++.dg/tree-ssa/pr109849.C index cd348c0f5906..d06dbb104829 100644 --- a/gcc/testsuite/g++.dg/tree-ssa/pr109849.C +++ b/gcc/testsuite/g++.dg/tree-ssa/pr109849.C @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-sra" } */ +/* { dg-options "-O2 -fdump-tree-sra -fdump-tree-optimized" } */ #include typedef unsigned int uint32_t; @@ -29,3 +29,4 @@ main() } /* { dg-final { scan-tree-dump "Created a replacement for stack offset" "sra"} } */ +/* { dg-final { scan-tree-dump-not "cur = MEM" "optimized"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c index 43152de56163..1d01392c5957 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-dse1-details -fno-short-enums -fno-tree-fre" } */ +/* { dg-options "-O2 -fdump-tree-esra -fno-short-enums -fno-tree-fre" } */ /* { dg-skip-if "we want a BIT_FIELD_REF from fold_truth_andor" { ! lp64 } } */ /* { dg-skip-if "temporary variable names are not x and y" { mmix-knuth-mmixware } } */ @@ -31,5 +31,5 @@ constraint_equal (struct constraint a, struct constraint b) && constraint_expr_equal (a.rhs, b.rhs); } -/* { dg-final { scan-tree-dump-times "Deleted dead store: x = " 2 "dse1" } } */ -/* { dg-final { scan-tree-dump-times "Deleted dead store: y = " 2 "dse1" } } */ +/* { dg-final { scan-tree-dump-not "x = " "esra" } } */ +/* { dg-final { scan-tree-dump-not "y = " "esra" } } */ diff --git a/gcc/tree-sra.cc b/gcc/tree-sra.cc index 32fa28911f2d..8040b0c56451 100644 --- a/gcc/tree-sra.cc +++ b/gcc/tree-sra.cc @@ -4854,8 +4854,18 @@ sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi) But use the RHS aggregate to load from to expose more optimization opportunities. */ if (access_has_children_p (lacc)) - generate_subtree_copies (lacc->first_child, rhs, lacc->offset, -0, 0, gsi, true, true, loc); + { + generate_subtree_copies (lacc->first_child, rhs, lacc->offset, + 0, 0, gsi, true, true, loc); + if (lacc->grp_covered) + { + unlink_stmt_vdef (stmt); + gsi_remove (& orig_gsi, true); + release_defs (stmt); + sra_stats.deleted++; + return SRA_AM_REMOVED; + } + } } return SRA_AM_NONE;
gcc-wwwdocs branch master updated. d63b0ce2968ddaa335a679ba4595ca582ef76d6d
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "gcc-wwwdocs". The branch, master has been updated via d63b0ce2968ddaa335a679ba4595ca582ef76d6d (commit) from d2323d3efa30008ed05519a398eb7fe1e9b446d3 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log - commit d63b0ce2968ddaa335a679ba4595ca582ef76d6d Author: Martin Jambor Date: Fri May 3 11:53:43 2024 +0200 List znver5 in the GCC 14 changes document diff --git a/htdocs/gcc-14/changes.html b/htdocs/gcc-14/changes.html index 8dfbf7dc..46a0266d 100644 --- a/htdocs/gcc-14/changes.html +++ b/htdocs/gcc-14/changes.html @@ -954,6 +954,12 @@ __asm (".global __flmap_lock" "\n\t" -fsanitize=hwaddress will enable -mlam=u57 by default. + GCC now supports AMD CPUs based on the znver5 core via +-march=znver5. In addition to the ISA extensions +enabled on a znver4 core, this switch further enables the +AVX512VP2INTERSECT, AVXVNNI, MOVDIR64B, MOVDIRI, and PREFETCHI ISA +extensions. + MCore --- Summary of changes: htdocs/gcc-14/changes.html | 6 ++ 1 file changed, 6 insertions(+) hooks/post-receive -- gcc-wwwdocs
gcc-wwwdocs branch master updated. d2323d3efa30008ed05519a398eb7fe1e9b446d3
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "gcc-wwwdocs". The branch, master has been updated via d2323d3efa30008ed05519a398eb7fe1e9b446d3 (commit) from 6c84b7b936a085c13e1f33f2028317fe31bbbcd8 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log - commit d2323d3efa30008ed05519a398eb7fe1e9b446d3 Author: Martin Jambor Date: Thu May 2 23:40:22 2024 +0200 Describe gcc target pragma changes in gcc-14/porting_to.html Adding a subsection on how gcc target pragma changed in GCC 14 in the corresponding porting-to document. diff --git a/htdocs/gcc-14/porting_to.html b/htdocs/gcc-14/porting_to.html index c825a68e..a20d82c2 100644 --- a/htdocs/gcc-14/porting_to.html +++ b/htdocs/gcc-14/porting_to.html @@ -514,6 +514,48 @@ be included explicitly when compiling with GCC 14: +Pragma GCC target now affects preprocessor symbols + + +The behavior of pragma GCC target and specifically how it affects ISA +macros has changed in GCC 14. In GCC 13 and older, the GCC +target pragma defined and undefined corresponding ISA macros in +C when using the integrated preprocessor during compilation but not +when the preprocessor was invoked as a separate step or when using +the -save-temps option. In C++ the ISA macro definitions +were performed in a way which did not have any actual effect. + +In GCC 14 C++ behaves like C with integrated preprocessing in earlier +versions. Moreover, in both languages ISA macros are defined and +undefined as expected when preprocessing separately from compilation. + + +This can lead to different behavior, especially in C++. For example, +a part of the C++ snippet below will be (silently) compiled for an +incorrect instruction set by GCC 14. + + + #if ! __AVX2__ + #pragma GCC push_options + #pragma GCC target("avx2") + #endif + + /* Code to be compiled for AVX2. */ + + /* With GCC 14, __AVX2__ here will always be defined and pop_options + never invoked. */ + #if ! __AVX2__ + #pragma GCC pop_options + #endif + + /* With GCC 14, all following functions will be compiled for AVX2 + which was not intended. */ + + + +The fix in this case is to remember whether pop_options +needs to be performed in a new user-defined macro. + --- Summary of changes: htdocs/gcc-14/porting_to.html | 42 ++ 1 file changed, 42 insertions(+) hooks/post-receive -- gcc-wwwdocs
[gcc r13-8620] ipa: Force args obtined through pass-through maps to the expected type (PR 113964)
https://gcc.gnu.org/g:5c3238b0d55ec13a2430aa606e2bfed9432e97ac commit r13-8620-g5c3238b0d55ec13a2430aa606e2bfed9432e97ac Author: Martin Jambor Date: Fri Apr 19 16:48:12 2024 +0200 ipa: Force args obtined through pass-through maps to the expected type (PR 113964) Interactions of IPA-CP and IPA-SRA on the same data is a rather big source of issues, I'm afraid. PR 113964 is a situation where IPA-CP propagates an unsigned short in a union parameter into a function which itself calls a different function which has a same union parameter and both these union parameters are split with IPA-SRA. The leaf function however uses a signed short member of the union. In the calling function, we get the unsigned constant as the replacement for the union and it is then passed in the call without any type compatibility checks. Apparently on riscv64 it matters whether the parameter is signed or unsigned short and so the leaf function can see different values. Fixed by using useless_type_conversion_p at the appropriate place and if it fails, use force_value_to type as elsewhere in similar situations. gcc/ChangeLog: 2024-04-04 Martin Jambor PR ipa/113964 * ipa-param-manipulation.cc (ipa_param_adjustments::modify_call): Force values obtined through pass-through maps to the expected split type. gcc/testsuite/ChangeLog: 2024-04-04 Patrick O'Neill Martin Jambor PR ipa/113964 * gcc.dg/ipa/pr114247.c: New test. (cherry picked from commit 8cd0d29270d4ed86c69b80c08de66dcb6c1e22fe) Diff: --- gcc/ipa-param-manipulation.cc | 6 ++ gcc/testsuite/gcc.dg/ipa/pr114247.c | 31 +++ 2 files changed, 37 insertions(+) diff --git a/gcc/ipa-param-manipulation.cc b/gcc/ipa-param-manipulation.cc index e4f626ae95e..729d5e8e688 100644 --- a/gcc/ipa-param-manipulation.cc +++ b/gcc/ipa-param-manipulation.cc @@ -738,6 +738,12 @@ ipa_param_adjustments::modify_call (cgraph_edge *cs, } if (repl) { + if (!useless_type_conversion_p(apm->type, repl->typed.type)) + { + repl = force_value_to_type (apm->type, repl); + repl = force_gimple_operand_gsi (, repl, + true, NULL, true, GSI_SAME_STMT); + } vargs.quick_push (repl); continue; } diff --git a/gcc/testsuite/gcc.dg/ipa/pr114247.c b/gcc/testsuite/gcc.dg/ipa/pr114247.c new file mode 100644 index 000..60aa2bc0122 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/pr114247.c @@ -0,0 +1,31 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -fsigned-char -fno-strict-aliasing -fwrapv" } */ + +union a { + unsigned short b; + int c; + signed short d; +}; +int e, f = 1, g; +long h; +const int **i; +void j(union a k, int l, unsigned m) { + const int *a[100]; + i = [0]; + h = k.d; +} +static int o(union a k) { + k.d = -1; + while (1) +if (f) + break; + j(k, g, e); + return 0; +} +int main() { + union a n = {1}; + o(n); + if (h != -1) +__builtin_abort(); + return 0; +}
[gcc r13-8619] ipa: Avoid duplicate replacements in IPA-SRA transformation phase
https://gcc.gnu.org/g:8a3784adf5cd873ca295a5a011d8623338ff3976 commit r13-8619-g8a3784adf5cd873ca295a5a011d8623338ff3976 Author: Martin Jambor Date: Fri Apr 19 16:48:12 2024 +0200 ipa: Avoid duplicate replacements in IPA-SRA transformation phase When the analysis part of IPA-SRA figures out that it would split out a scalar part of an aggregate which is known by IPA-CP to contain a known constant, it skips it knowing that the transformation part looks at IPA-CP aggregate results too and does the right thing (which can include doing the propagation in GIMPLE because that is the last moment the parameter exists). However, when IPA-SRA wants to split out a smaller aggregate out of an aggregate, which happens to be of the same size as a known scalar constant at the same offset, the transformation bit fails to recognize the situation, tries to do both splitting and constant propagation and in PR 111571 testcase creates a nonsensical call statement on which the call redirection then ICEs. Fixed by making sure we don't try to do two replacements of the same part of the same parameter. The look-up among replacements requires these are sorted and this patch just sorts them if they are not already sorted before each new look-up. The worst number of sortings that can happen is number of parameters which are both split and have aggregate constants times param_ipa_max_agg_items (default 16). I don't think complicating the source code to optimize for this unlikely case is worth it but if need be, it can of course be done. gcc/ChangeLog: 2024-03-15 Martin Jambor PR ipa/111571 * ipa-param-manipulation.cc (ipa_param_body_adjustments::common_initialization): Avoid creating duplicate replacement entries. gcc/testsuite/ChangeLog: 2024-03-15 Martin Jambor PR ipa/111571 * gcc.dg/ipa/pr111571.c: New test. (cherry picked from commit ca56b43105fc09021ec445f1978a17cd85ae5e0c) Diff: --- gcc/ipa-param-manipulation.cc | 16 gcc/testsuite/gcc.dg/ipa/pr111571.c | 29 + 2 files changed, 45 insertions(+) diff --git a/gcc/ipa-param-manipulation.cc b/gcc/ipa-param-manipulation.cc index 182f0c6741e..e4f626ae95e 100644 --- a/gcc/ipa-param-manipulation.cc +++ b/gcc/ipa-param-manipulation.cc @@ -1484,6 +1484,22 @@ ipa_param_body_adjustments::common_initialization (tree old_fndecl, replacement with a constant (for split aggregates passed by value). */ + if (split[parm_num]) + { + /* We must be careful not to add a duplicate +replacement. */ + sort_replacements (); + ipa_param_body_replacement *pbr + = lookup_replacement_1 (m_oparms[parm_num], + av.unit_offset); + if (pbr) + { + /* Otherwise IPA-SRA should have bailed out. */ + gcc_assert (AGGREGATE_TYPE_P (TREE_TYPE (pbr->repl))); + continue; + } + } + tree repl; if (av.by_ref) repl = av.value; diff --git a/gcc/testsuite/gcc.dg/ipa/pr111571.c b/gcc/testsuite/gcc.dg/ipa/pr111571.c new file mode 100644 index 000..2a4adc608db --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/pr111571.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +struct a { + int b; +}; +struct c { + long d; + struct a e; + long f; +}; +int g, h, i; +int j() {return 0;} +static void k(struct a l, int p) { + if (h) +g = 0; + for (; g; g = j()) +if (l.b) + break; +} +static void m(struct c l) { + k(l.e, l.f); + for (;; --i) +; +} +int main() { + struct c n = {10, 9}; + m(n); +}
[gcc r14-9926] contrib/check-params-in-docs.py: Ignore gcn-preferred-vectorization-factor
https://gcc.gnu.org/g:33f83d3cd84f9876180a2e2a9d1ea082debdaa37 commit r14-9926-g33f83d3cd84f9876180a2e2a9d1ea082debdaa37 Author: Martin Jambor Date: Thu Apr 11 19:37:45 2024 +0200 contrib/check-params-in-docs.py: Ignore gcn-preferred-vectorization-factor contrib/check-params-in-docs.py is a script that checks that all options reported with ./gcc/xgcc -Bgcc --help=param are in gcc/doc/invoke.texi and vice versa. gcn-preferred-vectorization-factor is in the manual but normally not reported by --help, probably because I do not have gcn offload configured. This patch makes the script silently about this particular fact. contrib/ChangeLog: 2024-04-11 Martin Jambor * check-params-in-docs.py (ignored): Add gcn-preferred-vectorization-factor. Diff: --- contrib/check-params-in-docs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/check-params-in-docs.py b/contrib/check-params-in-docs.py index 623c82284e2..f7879dd8e08 100755 --- a/contrib/check-params-in-docs.py +++ b/contrib/check-params-in-docs.py @@ -45,7 +45,7 @@ parser.add_argument('params_output') args = parser.parse_args() -ignored = {'logical-op-non-short-circuit'} +ignored = {'logical-op-non-short-circuit', 'gcn-preferred-vectorization-factor'} params = {} for line in open(args.params_output).readlines():
gcc-wwwdocs branch master updated. 8d40685d6a2b26aff26f1cd68f5bfd9728b2eda5
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "gcc-wwwdocs". The branch, master has been updated via 8d40685d6a2b26aff26f1cd68f5bfd9728b2eda5 (commit) from 408ef50eced845bc5a084bfac868686df74cbdcf (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log - commit 8d40685d6a2b26aff26f1cd68f5bfd9728b2eda5 Author: Martin Jambor Date: Wed Apr 10 16:33:14 2024 +0200 Fix link to "Feature Test Macros" in "Porting to GCC 14" page Michal Jireš found out that the link to Feature Test Macros on the Porting to GCC 14 page was broken, it misses a "/latest/" directory in the middle of the path. diff --git a/htdocs/gcc-14/porting_to.html b/htdocs/gcc-14/porting_to.html index 35274691..c825a68e 100644 --- a/htdocs/gcc-14/porting_to.html +++ b/htdocs/gcc-14/porting_to.html @@ -133,7 +133,7 @@ On GNU systems, headers described in standards (such as the C standard, or POSIX) may require the definition of certain macros at the start of the compilation before all required function declarations are made available. -See https://sourceware.org/glibc/manual/html_node/Feature-Test-Macros.html;>Feature Test Macros +See https://sourceware.org/glibc/manual/latest/html_node/Feature-Test-Macros.html;>Feature Test Macros in the GNU C Library manual for details. --- Summary of changes: htdocs/gcc-14/porting_to.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- gcc-wwwdocs
[gcc r14-9841] ICF: Make ICF and SRA agree on padding
https://gcc.gnu.org/g:1e3312a25a7b34d6e3f549273e1674c7114e4408 commit r14-9841-g1e3312a25a7b34d6e3f549273e1674c7114e4408 Author: Martin Jambor Date: Mon Apr 8 18:53:23 2024 +0200 ICF: Make ICF and SRA agree on padding PR 113359 shows that (at least with -fno-strict-aliasing) ICF can unify two functions which copy an aggregate type of the same size but then SRA, through its total scalarization, can copy the aggregate by pieces, skipping paddding, but the padding was not the same in the two original functions that ICF unified. This patch enhances SRA with the ability to collect padding information which then can be compared from within ICF. Unfortunately SRA uses OPTION_SET_P when determining its limits, so ICF needs to switch cfuns at least once to figure it out too. gcc/ChangeLog: 2024-03-27 Martin Jambor PR ipa/113359 * ipa-icf-gimple.h (func_checker): New members safe_for_total_scalarization_p, m_total_scalarization_limit_known_p and m_total_scalarization_limit. (func_checker::func_checker): Initialize new member variables. * ipa-icf-gimple.cc: Include tree-sra.h. (func_checker::func_checker): Initialize new member variables. (func_checker::safe_for_total_scalarization_p): New function. (func_checker::compare_operand): Use the new function. * tree-sra.h (sra_get_max_scalarization_size): Declare. (sra_total_scalarization_would_copy_same_data_p): Likewise. * tree-sra.cc (prepare_iteration_over_array_elts): New function. (class sra_padding_collecting): New. (sra_padding_collecting::record_padding): Likewise. (scalarizable_type_p): Rename to totally_scalarizable_type_p. Add ability to record padding when requested. (totally_scalarize_subtree): Split out gathering information necessary to iterate over array elements to prepare_iteration_over_array_elts. Fix errornous early exit. (analyze_all_variable_accesses): Adjust the call to totally_scalarizable_type_p. Move determining of total scalariation size limit... (sra_get_max_scalarization_size): ...here. (check_ts_and_push_padding_to_vec): New function. (sra_total_scalarization_would_copy_same_data_p): Likewise. gcc/testsuite/ChangeLog: 2024-03-27 Martin Jambor PR ipa/113359 * gcc.dg/lto/pr113359-1_0.c: New. * gcc.dg/lto/pr113359-1_1.c: Likewise. * gcc.dg/lto/pr113359-2_0.c: Likewise. * gcc.dg/lto/pr113359-2_1.c: Likewise. * gcc.dg/lto/pr113359-3_0.c: Likewise. * gcc.dg/lto/pr113359-3_1.c: Likewise. * gcc.dg/lto/pr113359-4_0.c: Likewise. * gcc.dg/lto/pr113359-4_1.c: Likewise. * gcc.dg/lto/pr113359-5_0.c: Likewise. * gcc.dg/lto/pr113359-5_1.c: Likewise. Diff: --- gcc/ipa-icf-gimple.cc | 41 +- gcc/ipa-icf-gimple.h| 15 +- gcc/testsuite/gcc.dg/lto/pr113359-1_0.c | 86 +++ gcc/testsuite/gcc.dg/lto/pr113359-1_1.c | 38 + gcc/testsuite/gcc.dg/lto/pr113359-2_0.c | 87 +++ gcc/testsuite/gcc.dg/lto/pr113359-2_1.c | 38 + gcc/testsuite/gcc.dg/lto/pr113359-3_0.c | 114 +++ gcc/testsuite/gcc.dg/lto/pr113359-3_1.c | 49 +++ gcc/testsuite/gcc.dg/lto/pr113359-4_0.c | 114 +++ gcc/testsuite/gcc.dg/lto/pr113359-4_1.c | 49 +++ gcc/testsuite/gcc.dg/lto/pr113359-5_0.c | 118 +++ gcc/testsuite/gcc.dg/lto/pr113359-5_1.c | 50 +++ gcc/tree-sra.cc | 252 +--- gcc/tree-sra.h | 3 + 14 files changed, 999 insertions(+), 55 deletions(-) diff --git a/gcc/ipa-icf-gimple.cc b/gcc/ipa-icf-gimple.cc index 17f62bec068..c25eb24710f 100644 --- a/gcc/ipa-icf-gimple.cc +++ b/gcc/ipa-icf-gimple.cc @@ -39,6 +39,7 @@ along with GCC; see the file COPYING3. If not see #include "cfgloop.h" #include "attribs.h" #include "gimple-walk.h" +#include "tree-sra.h" #include "tree-ssa-alias-compare.h" #include "alloc-pool.h" @@ -64,7 +65,8 @@ func_checker::func_checker (tree source_func_decl, tree target_func_decl, : m_source_func_decl (source_func_decl), m_target_func_decl (target_func_decl), m_ignored_source_nodes (ignored_source_nodes), m_ignored_target_nodes (ignored_target_nodes), -m_ignore_labels (ignore_labels), m_tbaa (tbaa) +m_ignore_labels (ignore_labels), m_tbaa (tbaa), +m_total_scalarization_limit_known_p (false) { function *source_func = DECL_STRUCT_FUNCTION (source_func_decl); function *target_func = DECL_STRUCT_FUNCTION (target_func_decl); @@ -361,6 +363,36 @@ func_checker::operand_equal_p (const_tree t1, const_tree t2,
[gcc r14-9840] ipa: Compare jump functions in ICF (PR 113907)
https://gcc.gnu.org/g:1162861439fd3c4b30fc3ccd49462e47e876f04a commit r14-9840-g1162861439fd3c4b30fc3ccd49462e47e876f04a Author: Martin Jambor Date: Mon Apr 8 18:53:23 2024 +0200 ipa: Compare jump functions in ICF (PR 113907) In PR 113907 comment #58, Honza found a case where ICF thinks bodies of functions are equivalent but becaise of difference in aliases in a memory access, different aggregate jump functions are associated with supposedly equivalent call statements. This patch adds a way to compare jump functions and plugs it into ICF to avoid the issue. gcc/ChangeLog: 2024-03-20 Martin Jambor PR ipa/113907 * ipa-prop.h (class ipa_vr): Declare new overload of a member function equal_p. (ipa_jump_functions_equivalent_p): Declare. * ipa-prop.cc (ipa_vr::equal_p): New function. (ipa_agg_pass_through_jf_equivalent_p): Likewise. (ipa_agg_jump_functions_equivalent_p): Likewise. (ipa_jump_functions_equivalent_p): Likewise. * ipa-cp.h (values_equal_for_ipcp_p): Declare. * ipa-cp.cc (values_equal_for_ipcp_p): Make function public. * ipa-icf-gimple.cc: Include alloc-pool.h, symbol-summary.h, sreal.h, ipa-cp.h and ipa-prop.h. (func_checker::compare_gimple_call): Comapre jump functions. gcc/testsuite/ChangeLog: 2024-03-20 Martin Jambor PR ipa/113907 * gcc.dg/lto/pr113907_0.c: New. * gcc.dg/lto/pr113907_1.c: Likewise. * gcc.dg/lto/pr113907_2.c: Likewise. Diff: --- gcc/ipa-cp.cc | 2 +- gcc/ipa-cp.h | 2 + gcc/ipa-icf-gimple.cc | 30 ++ gcc/ipa-prop.cc | 167 ++ gcc/ipa-prop.h| 3 + gcc/testsuite/gcc.dg/lto/pr113907_0.c | 18 gcc/testsuite/gcc.dg/lto/pr113907_1.c | 35 +++ gcc/testsuite/gcc.dg/lto/pr113907_2.c | 11 +++ 8 files changed, 267 insertions(+), 1 deletion(-) diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc index 2a1da631e9c..b7add455bd5 100644 --- a/gcc/ipa-cp.cc +++ b/gcc/ipa-cp.cc @@ -201,7 +201,7 @@ ipcp_lattice::is_single_const () /* Return true iff X and Y should be considered equal values by IPA-CP. */ -static bool +bool values_equal_for_ipcp_p (tree x, tree y) { gcc_checking_assert (x != NULL_TREE && y != NULL_TREE); diff --git a/gcc/ipa-cp.h b/gcc/ipa-cp.h index 0b3cfe4b526..7ff74fb5c98 100644 --- a/gcc/ipa-cp.h +++ b/gcc/ipa-cp.h @@ -289,4 +289,6 @@ public: bool virt_call = false; }; +bool values_equal_for_ipcp_p (tree x, tree y); + #endif /* IPA_CP_H */ diff --git a/gcc/ipa-icf-gimple.cc b/gcc/ipa-icf-gimple.cc index 8c2df7a354e..17f62bec068 100644 --- a/gcc/ipa-icf-gimple.cc +++ b/gcc/ipa-icf-gimple.cc @@ -41,7 +41,12 @@ along with GCC; see the file COPYING3. If not see #include "gimple-walk.h" #include "tree-ssa-alias-compare.h" +#include "alloc-pool.h" +#include "symbol-summary.h" #include "ipa-icf-gimple.h" +#include "sreal.h" +#include "ipa-cp.h" +#include "ipa-prop.h" namespace ipa_icf_gimple { @@ -714,6 +719,31 @@ func_checker::compare_gimple_call (gcall *s1, gcall *s2) && !compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2))) return return_false_with_msg ("GIMPLE internal call LHS type mismatch"); + if (!gimple_call_internal_p (s1)) +{ + cgraph_edge *e1 = cgraph_node::get (m_source_func_decl)->get_edge (s1); + cgraph_edge *e2 = cgraph_node::get (m_target_func_decl)->get_edge (s2); + class ipa_edge_args *args1 = ipa_edge_args_sum->get (e1); + class ipa_edge_args *args2 = ipa_edge_args_sum->get (e2); + if ((args1 != nullptr) != (args2 != nullptr)) + return return_false_with_msg ("ipa_edge_args mismatch"); + if (args1) + { + int n1 = ipa_get_cs_argument_count (args1); + int n2 = ipa_get_cs_argument_count (args2); + if (n1 != n2) + return return_false_with_msg ("ipa_edge_args nargs mismatch"); + for (int i = 0; i < n1; i++) + { + struct ipa_jump_func *jf1 = ipa_get_ith_jump_func (args1, i); + struct ipa_jump_func *jf2 = ipa_get_ith_jump_func (args2, i); + if (((jf1 != nullptr) != (jf2 != nullptr)) + || (jf1 && !ipa_jump_functions_equivalent_p (jf1, jf2))) + return return_false_with_msg ("jump function mismatch"); + } + } +} + return compare_operand (t1, t2, get_operand_access_type (, t1)); } diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc index e8e4918d5a8..374e998aa64 100644 --- a/gcc/ipa-prop.cc +++ b/gcc/ipa-prop.cc @@ -156,6 +156,20 @@ ipa_vr::equal_p (const vrange ) const return (types_compatible_p (m_type, r.type ()) && m_storage->equal_p (r)); } +bool +ipa_vr::equal_p (const ipa_vr ) const +{ + if
[gcc r13-8594] ipa: Self-DCE of uses of removed call LHSs (PR 108007)
https://gcc.gnu.org/g:40ddc0b05a47f999b24f20c1becb79004995731b commit r13-8594-g40ddc0b05a47f999b24f20c1becb79004995731b Author: Martin Jambor Date: Mon Apr 8 17:34:33 2024 +0200 ipa: Self-DCE of uses of removed call LHSs (PR 108007) PR 108007 is another manifestation where we rely on DCE to clean-up after IPA-SRA and if the user explicitely switches DCE off, IPA-SRA can leave behind statements which are fed uninitialized values and trap, even though their results are themselves never used. I have already fixed this for unused parameters in callees, this bug shows that almost the same thing can happen for removed returns, on the side of callers. This means that the issue has to be fixed elsewhere, in call redirection. This patch adds a function which looks for (and through, using a work-list) uses of operations fed specific SSA names and removes them all. That would have been easy if it wasn't for debug statements during tree-inline (from which call redirection is also invoked). Debug statements are decoupled from the rest at this point and iterating over uses of SSAs does not bring them up. During tree-inline they are handled especially at the end, I assume in order to make sure that relative ordering of UIDs are the same with and without debug info. This means that during tree-inline we need to make a hash of killed SSAs, that we already have in copy_body_data, available to the function making the purging. So the patch duly does also that, making the interface slightly ugly. Moreover, all newly unused SSA names need to be freed and as PR 112616 showed, it must be done in a defined order, which is what newly added ipa_release_ssas_in_hash does. This backport to gcc-13 also contains 54e505d0446f86b7ad383acbb8e5501f20872b64 in order not to reintroduce PR 113757. gcc/ChangeLog: 2024-04-05 Martin Jambor PR ipa/108007 PR ipa/112616 * cgraph.h (cgraph_edge): Add a parameter to redirect_call_stmt_to_callee. * ipa-param-manipulation.h (ipa_param_adjustments): Add a parameter to modify_call. (ipa_release_ssas_in_hash): Declare. * cgraph.cc (cgraph_edge::redirect_call_stmt_to_callee): New parameter killed_ssas, pass it to padjs->modify_call. * ipa-param-manipulation.cc (purge_all_uses): New function. (ipa_param_adjustments::modify_call): New parameter killed_ssas. Instead of substituting uses, invoke purge_all_uses. If hash of killed SSAs has not been provided, create a temporary one and release SSAs that have been added to it. (compare_ssa_versions): New function. (ipa_release_ssas_in_hash): Likewise. * tree-inline.cc (redirect_all_calls): Create id->killed_new_ssa_names earlier, pass it to edge redirection, adjust a comment. (copy_body): Release SSAs in id->killed_new_ssa_names. gcc/testsuite/ChangeLog: 2024-01-15 Martin Jambor PR ipa/108007 PR ipa/112616 * gcc.dg/ipa/pr108007.c: New test. * gcc.dg/ipa/pr112616.c: Likewise. (cherry picked from commit a9a8426e534760b8d3a250e9bd3cff4db131a2be) Diff: --- gcc/cgraph.cc | 10 +++- gcc/cgraph.h| 9 ++- gcc/ipa-param-manipulation.cc | 112 +--- gcc/ipa-param-manipulation.h| 5 +- gcc/testsuite/g++.dg/ipa/pr113757.C | 14 + gcc/testsuite/gcc.dg/ipa/pr108007.c | 32 +++ gcc/testsuite/gcc.dg/ipa/pr112616.c | 28 + gcc/tree-inline.cc | 27 - 8 files changed, 193 insertions(+), 44 deletions(-) diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc index ec663d23385..7a14c00b60a 100644 --- a/gcc/cgraph.cc +++ b/gcc/cgraph.cc @@ -1403,11 +1403,17 @@ cgraph_edge::redirect_callee (cgraph_node *n) speculative indirect call, remove "speculative" of the indirect call and also redirect stmt to it's final direct target. + When called from within tree-inline, KILLED_SSAs has to contain the pointer + to killed_new_ssa_names within the copy_body_data structure and SSAs + discovered to be useless (if LHS is removed) will be added to it, otherwise + it needs to be NULL. + It is up to caller to iteratively transform each "speculative" direct call as appropriate. */ gimple * -cgraph_edge::redirect_call_stmt_to_callee (cgraph_edge *e) +cgraph_edge::redirect_call_stmt_to_callee (cgraph_edge *e, + hash_set *killed_ssas) { tree decl = gimple_call_fndecl (e->call_stmt); gcall *new_stmt; @@ -1527,7 +1533,7 @@ cgraph_edge::redirect_call_stmt_to_callee (cgraph_edge *e) remove_stmt_from_eh_lp
[gcc r14-9813] ipa: Force args obtined through pass-through maps to the expected type (PR 113964)
https://gcc.gnu.org/g:8cd0d29270d4ed86c69b80c08de66dcb6c1e22fe commit r14-9813-g8cd0d29270d4ed86c69b80c08de66dcb6c1e22fe Author: Martin Jambor Date: Fri Apr 5 18:18:39 2024 +0200 ipa: Force args obtined through pass-through maps to the expected type (PR 113964) Interactions of IPA-CP and IPA-SRA on the same data is a rather big source of issues, I'm afraid. PR 113964 is a situation where IPA-CP propagates an unsigned short in a union parameter into a function which itself calls a different function which has a same union parameter and both these union parameters are split with IPA-SRA. The leaf function however uses a signed short member of the union. In the calling function, we get the unsigned constant as the replacement for the union and it is then passed in the call without any type compatibility checks. Apparently on riscv64 it matters whether the parameter is signed or unsigned short and so the leaf function can see different values. Fixed by using useless_type_conversion_p at the appropriate place and if it fails, use force_value_to type as elsewhere in similar situations. gcc/ChangeLog: 2024-04-04 Martin Jambor PR ipa/113964 * ipa-param-manipulation.cc (ipa_param_adjustments::modify_call): Force values obtined through pass-through maps to the expected split type. gcc/testsuite/ChangeLog: 2024-04-04 Patrick O'Neill Martin Jambor PR ipa/113964 * gcc.dg/ipa/pr114247.c: New test. Diff: --- gcc/ipa-param-manipulation.cc | 6 ++ gcc/testsuite/gcc.dg/ipa/pr114247.c | 31 +++ 2 files changed, 37 insertions(+) diff --git a/gcc/ipa-param-manipulation.cc b/gcc/ipa-param-manipulation.cc index f4b5e850c2b..ad36b8389c0 100644 --- a/gcc/ipa-param-manipulation.cc +++ b/gcc/ipa-param-manipulation.cc @@ -740,6 +740,12 @@ ipa_param_adjustments::modify_call (cgraph_edge *cs, } if (repl) { + if (!useless_type_conversion_p(apm->type, repl->typed.type)) + { + repl = force_value_to_type (apm->type, repl); + repl = force_gimple_operand_gsi (, repl, + true, NULL, true, GSI_SAME_STMT); + } vargs.quick_push (repl); continue; } diff --git a/gcc/testsuite/gcc.dg/ipa/pr114247.c b/gcc/testsuite/gcc.dg/ipa/pr114247.c new file mode 100644 index 000..60aa2bc0122 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/pr114247.c @@ -0,0 +1,31 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -fsigned-char -fno-strict-aliasing -fwrapv" } */ + +union a { + unsigned short b; + int c; + signed short d; +}; +int e, f = 1, g; +long h; +const int **i; +void j(union a k, int l, unsigned m) { + const int *a[100]; + i = [0]; + h = k.d; +} +static int o(union a k) { + k.d = -1; + while (1) +if (f) + break; + j(k, g, e); + return 0; +} +int main() { + union a n = {1}; + o(n); + if (h != -1) +__builtin_abort(); + return 0; +}
[gcc r14-9794] ipa: Avoid duplicate replacements in IPA-SRA transformation phase
https://gcc.gnu.org/g:ca56b43105fc09021ec445f1978a17cd85ae5e0c commit r14-9794-gca56b43105fc09021ec445f1978a17cd85ae5e0c Author: Martin Jambor Date: Thu Apr 4 22:46:16 2024 +0200 ipa: Avoid duplicate replacements in IPA-SRA transformation phase When the analysis part of IPA-SRA figures out that it would split out a scalar part of an aggregate which is known by IPA-CP to contain a known constant, it skips it knowing that the transformation part looks at IPA-CP aggregate results too and does the right thing (which can include doing the propagation in GIMPLE because that is the last moment the parameter exists). However, when IPA-SRA wants to split out a smaller aggregate out of an aggregate, which happens to be of the same size as a known scalar constant at the same offset, the transformation bit fails to recognize the situation, tries to do both splitting and constant propagation and in PR 111571 testcase creates a nonsensical call statement on which the call redirection then ICEs. Fixed by making sure we don't try to do two replacements of the same part of the same parameter. The look-up among replacements requires these are sorted and this patch just sorts them if they are not already sorted before each new look-up. The worst number of sortings that can happen is number of parameters which are both split and have aggregate constants times param_ipa_max_agg_items (default 16). I don't think complicating the source code to optimize for this unlikely case is worth it but if need be, it can of course be done. gcc/ChangeLog: 2024-03-15 Martin Jambor PR ipa/111571 * ipa-param-manipulation.cc (ipa_param_body_adjustments::common_initialization): Avoid creating duplicate replacement entries. gcc/testsuite/ChangeLog: 2024-03-15 Martin Jambor PR ipa/111571 * gcc.dg/ipa/pr111571.c: New test. Diff: --- gcc/ipa-param-manipulation.cc | 16 gcc/testsuite/gcc.dg/ipa/pr111571.c | 29 + 2 files changed, 45 insertions(+) diff --git a/gcc/ipa-param-manipulation.cc b/gcc/ipa-param-manipulation.cc index 3e0df6a6f77..f4b5e850c2b 100644 --- a/gcc/ipa-param-manipulation.cc +++ b/gcc/ipa-param-manipulation.cc @@ -1525,6 +1525,22 @@ ipa_param_body_adjustments::common_initialization (tree old_fndecl, replacement with a constant (for split aggregates passed by value). */ + if (split[parm_num]) + { + /* We must be careful not to add a duplicate +replacement. */ + sort_replacements (); + ipa_param_body_replacement *pbr + = lookup_replacement_1 (m_oparms[parm_num], + av.unit_offset); + if (pbr) + { + /* Otherwise IPA-SRA should have bailed out. */ + gcc_assert (AGGREGATE_TYPE_P (TREE_TYPE (pbr->repl))); + continue; + } + } + tree repl; if (av.by_ref) repl = av.value; diff --git a/gcc/testsuite/gcc.dg/ipa/pr111571.c b/gcc/testsuite/gcc.dg/ipa/pr111571.c new file mode 100644 index 000..2a4adc608db --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/pr111571.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +struct a { + int b; +}; +struct c { + long d; + struct a e; + long f; +}; +int g, h, i; +int j() {return 0;} +static void k(struct a l, int p) { + if (h) +g = 0; + for (; g; g = j()) +if (l.b) + break; +} +static void m(struct c l) { + k(l.e, l.f); + for (;; --i) +; +} +int main() { + struct c n = {10, 9}; + m(n); +}
[gcc r14-9559] ipa: Fix C++ member ptr indirect inlining (PR 114254, PR 108802)
https://gcc.gnu.org/g:bf838884fac573b4902a21bb82d9b6f777e32cb9 commit r14-9559-gbf838884fac573b4902a21bb82d9b6f777e32cb9 Author: Martin Jambor Date: Tue Mar 19 22:33:27 2024 +0100 ipa: Fix C++ member ptr indirect inlining (PR 114254, PR 108802) Even though we have had code to handle creation of indirect call graph edges (so that these calls can than be made direct as part of IPA-CP and inlining and eventually also inlined) for C++ member pointers for many years, it turns out that it does not work for lambdas and that it has been severely broken since GCC 10 when the base class has virtual functions. Lambdas don't work because the code cannot work with structures representing member function pointers because they are passed by reference instead by value and the code was not ready for that. The presence of virtual methods broke thinks because at some point C++ FE got clever and stopped emitting the check for virtual methods when the base class does not have any and that in turn made our existing testcases not test the necessary pattern matching code. The pattern matcher had a small bug which did not matter before r10-917-g3b47da42de621c but did afterwards. This patch changes the pattern matcher to match both of these cases. gcc/ChangeLog: 2024-03-06 Martin Jambor PR ipa/108802 PR ipa/114254 * ipa-prop.cc (ipa_get_stmt_member_ptr_load_param): Fix case looking at COMPONENT_REFs directly from a PARM_DECL, also recognize loads from a pointer parameter. (ipa_analyze_indirect_call_uses): Also recognize loads from a pointer parameter, also recognize the case when pfn pointer is loaded in its own BB. gcc/testsuite/ChangeLog: 2024-03-06 Martin Jambor PR ipa/108802 PR ipa/114254 * g++.dg/ipa/iinline-4.C: New test. * g++.dg/ipa/pr108802.C: Likewise. Diff: --- gcc/ipa-prop.cc | 110 +-- gcc/testsuite/g++.dg/ipa/iinline-4.C | 61 +++ gcc/testsuite/g++.dg/ipa/pr108802.C | 14 + 3 files changed, 154 insertions(+), 31 deletions(-) diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc index e22c4f78405..e8e4918d5a8 100644 --- a/gcc/ipa-prop.cc +++ b/gcc/ipa-prop.cc @@ -2500,7 +2500,9 @@ static tree ipa_get_stmt_member_ptr_load_param (gimple *stmt, bool use_delta, HOST_WIDE_INT *offset_p) { - tree rhs, rec, ref_field, ref_offset, fld, ptr_field, delta_field; + tree rhs, fld, ptr_field, delta_field; + tree ref_field = NULL_TREE; + tree ref_offset = NULL_TREE; if (!gimple_assign_single_p (stmt)) return NULL_TREE; @@ -2511,35 +2513,53 @@ ipa_get_stmt_member_ptr_load_param (gimple *stmt, bool use_delta, ref_field = TREE_OPERAND (rhs, 1); rhs = TREE_OPERAND (rhs, 0); } - else -ref_field = NULL_TREE; - if (TREE_CODE (rhs) != MEM_REF) -return NULL_TREE; - rec = TREE_OPERAND (rhs, 0); - if (TREE_CODE (rec) != ADDR_EXPR) -return NULL_TREE; - rec = TREE_OPERAND (rec, 0); - if (TREE_CODE (rec) != PARM_DECL - || !type_like_member_ptr_p (TREE_TYPE (rec), _field, _field)) + + if (TREE_CODE (rhs) == MEM_REF) +{ + ref_offset = TREE_OPERAND (rhs, 1); + if (ref_field && integer_nonzerop (ref_offset)) + return NULL_TREE; +} + else if (!ref_field) return NULL_TREE; - ref_offset = TREE_OPERAND (rhs, 1); + + if (TREE_CODE (rhs) == MEM_REF + && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME + && SSA_NAME_IS_DEFAULT_DEF (TREE_OPERAND (rhs, 0))) +{ + rhs = TREE_OPERAND (rhs, 0); + if (TREE_CODE (SSA_NAME_VAR (rhs)) != PARM_DECL + || !type_like_member_ptr_p (TREE_TYPE (TREE_TYPE (rhs)), _field, + _field)) + return NULL_TREE; +} + else +{ + if (TREE_CODE (rhs) == MEM_REF + && TREE_CODE (TREE_OPERAND (rhs, 0)) == ADDR_EXPR) + rhs = TREE_OPERAND (TREE_OPERAND (rhs, 0), 0); + if (TREE_CODE (rhs) != PARM_DECL + || !type_like_member_ptr_p (TREE_TYPE (rhs), _field, + _field)) + return NULL_TREE; +} if (use_delta) fld = delta_field; else fld = ptr_field; - if (offset_p) -*offset_p = int_bit_position (fld); if (ref_field) { - if (integer_nonzerop (ref_offset)) + if (ref_field != fld) return NULL_TREE; - return ref_field == fld ? rec : NULL_TREE; } - else -return tree_int_cst_equal (byte_position (fld), ref_offset) ? rec - : NULL_TREE; + else if (!tree_int_cst_equal (byte_position (fld), ref_offset)) +return NULL_TREE; + + if (offset_p) +*offset_p = int_bit_position (fld); + return rhs; } /* Returns true iff T is an SSA_NAME defined by
[gcc r14-9403] ipa: Avoid excessive removing of SSAs (PR 113757)
https://gcc.gnu.org/g:54e505d0446f86b7ad383acbb8e5501f20872b64 commit r14-9403-g54e505d0446f86b7ad383acbb8e5501f20872b64 Author: Martin Jambor Date: Sat Mar 9 00:47:22 2024 +0100 ipa: Avoid excessive removing of SSAs (PR 113757) PR 113757 shows that the code which was meant to debug-reset and remove SSAs defined by LHSs of calls redirected to __builtin_unreachable can trigger also when speculative devirtualization creates a call to a noreturn function (and since it is noreturn, it does not bother dealing with its return value). What is more, it seems that the code handling this case is not really necessary. I feel slightly idiotic about this because I have a feeling that I added it because of a failing test-case but I can neither find the testcase nor a reason why the code in cgraph_edge::redirect_call_stmt_to_callee would not be sufficient (it turns the SSA name into a default-def, a bit like IPA-SRA, but any code dominated by a call to a noreturn is not dangerous when it comes to its side-effects). So this patch just removes the handling. gcc/ChangeLog: 2024-02-07 Martin Jambor PR ipa/113757 * tree-inline.cc (redirect_all_calls): Remove code adding SSAs to id->killed_new_ssa_names. gcc/testsuite/ChangeLog: 2024-02-07 Martin Jambor PR ipa/113757 * g++.dg/ipa/pr113757.C: New test. Diff: --- gcc/testsuite/g++.dg/ipa/pr113757.C | 14 ++ gcc/tree-inline.cc | 14 ++ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/gcc/testsuite/g++.dg/ipa/pr113757.C b/gcc/testsuite/g++.dg/ipa/pr113757.C new file mode 100644 index 000..885d4010a10 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr113757.C @@ -0,0 +1,14 @@ +// { dg-do compile } +// { dg-options "-O2 -fPIC" } +// { dg-require-effective-target fpic } + +long size(); +struct ll { virtual int hh(); }; +ll *slice_owner; +int ll::hh() { __builtin_exit(0); } +int nn() { + if (size()) +return 0; + return slice_owner->hh(); +} +int (*a)() = nn; diff --git a/gcc/tree-inline.cc b/gcc/tree-inline.cc index f0a067f5812..eebcea8a029 100644 --- a/gcc/tree-inline.cc +++ b/gcc/tree-inline.cc @@ -2984,23 +2984,13 @@ redirect_all_calls (copy_body_data * id, basic_block bb) gimple *stmt = gsi_stmt (si); if (is_gimple_call (stmt)) { - tree old_lhs = gimple_call_lhs (stmt); struct cgraph_edge *edge = id->dst_node->get_edge (stmt); if (edge) { if (!id->killed_new_ssa_names) id->killed_new_ssa_names = new hash_set (16); - gimple *new_stmt - = cgraph_edge::redirect_call_stmt_to_callee (edge, - id->killed_new_ssa_names); - if (old_lhs - && TREE_CODE (old_lhs) == SSA_NAME - && !gimple_call_lhs (new_stmt)) - /* In case of IPA-SRA removing the LHS, the name should have - been already added to the hash. But in case of redirecting - to builtin_unreachable it was not and the name still should - be pruned from debug statements. */ - id->killed_new_ssa_names->add (old_lhs); + cgraph_edge::redirect_call_stmt_to_callee (edge, + id->killed_new_ssa_names); if (stmt == last && id->call_stmt && maybe_clean_eh_stmt (stmt)) gimple_purge_dead_eh_edges (bb);