[gcc r12-10475] ipa: Compare jump functions in ICF (PR 113907)

2024-05-28 Thread Martin Jambor via Gcc-cvs
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)

2024-05-23 Thread Martin Jambor via Gcc-cvs
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]

2024-05-21 Thread Martin Jambor via Gcc-cvs
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)

2024-05-15 Thread Martin Jambor via Gcc-cvs
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)

2024-05-15 Thread Martin Jambor via Gcc-cvs
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)

2024-05-14 Thread Martin Jambor via Gcc-cvs
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

2024-05-14 Thread Martin Jambor via Gcc-cvs
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)

2024-05-09 Thread Martin Jambor via Gcc-cvs
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

2024-05-03 Thread Martin Jambor via Gcc-cvs-wwwdocs
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

2024-05-02 Thread Martin Jambor via Gcc-cvs-wwwdocs
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)

2024-04-19 Thread Martin Jambor via Gcc-cvs
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

2024-04-19 Thread Martin Jambor via Gcc-cvs
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

2024-04-11 Thread Martin Jambor via Gcc-cvs
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

2024-04-10 Thread Martin Jambor via Gcc-cvs-wwwdocs
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

2024-04-08 Thread Martin Jambor via Gcc-cvs
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)

2024-04-08 Thread Martin Jambor via Gcc-cvs
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)

2024-04-08 Thread Martin Jambor via Gcc-cvs
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)

2024-04-05 Thread Martin Jambor via Gcc-cvs
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

2024-04-04 Thread Martin Jambor via Gcc-cvs
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)

2024-03-19 Thread Martin Jambor via Gcc-cvs
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)

2024-03-08 Thread Martin Jambor via Gcc-cvs
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);