commit: 46883551fe0614e80638fa08805e1f1bc7710a96 Author: Sam James <sam <AT> gentoo <DOT> org> AuthorDate: Wed Sep 17 03:04:26 2025 +0000 Commit: Sam James <sam <AT> gentoo <DOT> org> CommitDate: Wed Sep 17 03:04:26 2025 +0000 URL: https://gitweb.gentoo.org/proj/gcc-patches.git/commit/?id=46883551
16.0.0: add a prereq patch for the forwprop hang Signed-off-by: Sam James <sam <AT> gentoo.org> .../87_all_PR121962-forwprop-hang-prereq.patch | 244 +++++++++++++++++++++ ...g.patch => 88_all_PR121962-forwprop-hang.patch} | 0 16.0.0/gentoo/README.history | 3 +- 3 files changed, 246 insertions(+), 1 deletion(-) diff --git a/16.0.0/gentoo/87_all_PR121962-forwprop-hang-prereq.patch b/16.0.0/gentoo/87_all_PR121962-forwprop-hang-prereq.patch new file mode 100644 index 0000000..245a78b --- /dev/null +++ b/16.0.0/gentoo/87_all_PR121962-forwprop-hang-prereq.patch @@ -0,0 +1,244 @@ +From 41dc015782a42cb64680a55f6766ed5504c4ca53 Mon Sep 17 00:00:00 2001 +Message-ID: <41dc015782a42cb64680a55f6766ed5504c4ca53.1758078219.git....@gentoo.org> +From: Andrew Pinski <[email protected]> +Date: Mon, 15 Sep 2025 10:19:13 -0700 +Subject: [PATCH] forwprop: Handle memcpy for arguments with respect to copies + +This moves the code used in optimize_agr_copyprop_1 (r16-3887-g597b50abb0d) +to handle this same case into its new function and use it inside +optimize_agr_copyprop_arg. This allows to remove more copies that show up only +in arguments. + +Bootstrapped and tested on x86_64-linux-gnu. + +gcc/ChangeLog: + + * tree-ssa-forwprop.cc (optimize_agr_copyprop_1): Split out + the case where `operand_equal_p (dest, src2)` is false into ... + (new_src_based_on_copy): This. New function. + (optimize_agr_copyprop_arg): Use new_src_based_on_copy + instead of operand_equal_p to find the new src. + +gcc/testsuite/ChangeLog: + + * gcc.dg/tree-ssa/copy-prop-aggregate-arg-2.c: New test. + +Signed-off-by: Andrew Pinski <[email protected]> +--- + .../tree-ssa/copy-prop-aggregate-arg-2.c | 33 +++++ + gcc/tree-ssa-forwprop.cc | 135 ++++++++++-------- + 2 files changed, 106 insertions(+), 62 deletions(-) + create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/copy-prop-aggregate-arg-2.c + +diff --git a/gcc/testsuite/gcc.dg/tree-ssa/copy-prop-aggregate-arg-2.c b/gcc/testsuite/gcc.dg/tree-ssa/copy-prop-aggregate-arg-2.c +new file mode 100644 +index 000000000000..11f0768c1112 +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/tree-ssa/copy-prop-aggregate-arg-2.c +@@ -0,0 +1,33 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O1 -fdump-tree-forwprop1-details -fdump-tree-optimized" } */ ++ ++ ++struct s1 ++{ ++ int t[1024]; ++}; ++ ++struct s2 { ++ struct s1 t; ++}; ++ ++struct s3 ++{ ++ struct s2 t; ++}; ++ ++void g(struct s3); ++ ++void f(struct s1 s) ++{ ++ struct s2 removeme; ++ removeme.t = s; ++ struct s3 removeme2; ++ removeme2.t = removeme; ++ g(removeme2); ++} ++ ++ ++/* { dg-final { scan-tree-dump-times "after previous" 2 "forwprop1" } } */ ++/* { dg-final { scan-tree-dump-not "removeme " "optimized" } } */ ++/* { dg-final { scan-tree-dump-not "removeme2 " "optimized" } } */ +diff --git a/gcc/tree-ssa-forwprop.cc b/gcc/tree-ssa-forwprop.cc +index 1eacff01587c..f58a7b8c591d 100644 +--- a/gcc/tree-ssa-forwprop.cc ++++ b/gcc/tree-ssa-forwprop.cc +@@ -1458,6 +1458,72 @@ split_core_and_offset_size (tree expr, + return core; + } + ++/* Returns a new src based on the ++ copy `DEST = SRC` and for the old SRC2. ++ Returns null if SRC2 is not related to DEST. */ ++ ++static tree ++new_src_based_on_copy (tree src2, tree dest, tree src) ++{ ++ /* If the second src is not exactly the same as dest, ++ try to handle it seperately; see it is address/size equivalent. ++ Handles `a` and `a.b` and `MEM<char[N]>(&a)` which all have ++ the same size and offsets as address/size equivalent. ++ This allows copying over a memcpy and also one for copying ++ where one field is the same size as the whole struct. */ ++ if (operand_equal_p (dest, src2)) ++ return src; ++ /* A VCE can't be used with imag/real or BFR so reject them early. */ ++ if (TREE_CODE (src) == IMAGPART_EXPR ++ || TREE_CODE (src) == REALPART_EXPR ++ || TREE_CODE (src) == BIT_FIELD_REF) ++ return NULL_TREE; ++ tree core1, core2; ++ poly_int64 bytepos1, bytepos2; ++ poly_int64 bytesize1, bytesize2; ++ tree toffset1, toffset2; ++ int reversep1 = 0; ++ int reversep2 = 0; ++ poly_int64 diff = 0; ++ core1 = split_core_and_offset_size (dest, &bytesize1, &bytepos1, ++ &toffset1, &reversep1); ++ core2 = split_core_and_offset_size (src2, &bytesize2, &bytepos2, ++ &toffset2, &reversep2); ++ if (!core1 || !core2) ++ return NULL_TREE; ++ if (reversep1 != reversep2) ++ return NULL_TREE; ++ /* The sizes of the 2 accesses need to be the same. */ ++ if (!known_eq (bytesize1, bytesize2)) ++ return NULL_TREE; ++ if (!operand_equal_p (core1, core2, 0)) ++ return NULL_TREE; ++ ++ if (toffset1 && toffset2) ++ { ++ tree type = TREE_TYPE (toffset1); ++ if (type != TREE_TYPE (toffset2)) ++ toffset2 = fold_convert (type, toffset2); ++ ++ tree tdiff = fold_build2 (MINUS_EXPR, type, toffset1, toffset2); ++ if (!cst_and_fits_in_hwi (tdiff)) ++ return NULL_TREE; ++ ++ diff = int_cst_value (tdiff); ++ } ++ else if (toffset1 || toffset2) ++ { ++ /* If only one of the offsets is non-constant, the difference cannot ++ be a constant. */ ++ return NULL_TREE; ++ } ++ diff += bytepos1 - bytepos2; ++ /* The offset between the 2 need to be 0. */ ++ if (!known_eq (diff, 0)) ++ return NULL_TREE; ++ return fold_build1 (VIEW_CONVERT_EXPR,TREE_TYPE (src2), src); ++} ++ + /* Helper function for optimize_agr_copyprop. + For aggregate copies in USE_STMT, see if DEST + is on the lhs of USE_STMT and replace it with SRC. */ +@@ -1474,66 +1540,9 @@ optimize_agr_copyprop_1 (gimple *stmt, gimple *use_stmt, + /* If the new store is `src2 = src2;` skip over it. */ + if (operand_equal_p (src2, dest2, 0)) + return false; +- /* If the second src is not exactly the same as dest, +- try to handle it seperately; see it is address/size equivalent. +- Handles `a` and `a.b` and `MEM<char[N]>(&a)` which all have +- the same size and offsets as address/size equivalent. +- This allows copying over a memcpy and also one for copying +- where one field is the same size as the whole struct. */ +- if (!operand_equal_p (dest, src2, 0)) +- { +- /* A VCE can't be used with imag/real or BFR so reject them early. */ +- if (TREE_CODE (src) == IMAGPART_EXPR +- || TREE_CODE (src) == REALPART_EXPR +- || TREE_CODE (src) == BIT_FIELD_REF) +- return false; +- tree core1, core2; +- poly_int64 bytepos1, bytepos2; +- poly_int64 bytesize1, bytesize2; +- tree toffset1, toffset2; +- int reversep1 = 0; +- int reversep2 = 0; +- poly_int64 diff = 0; +- core1 = split_core_and_offset_size (dest, &bytesize1, &bytepos1, +- &toffset1, &reversep1); +- core2 = split_core_and_offset_size (src2, &bytesize2, &bytepos2, +- &toffset2, &reversep2); +- if (!core1 || !core2) +- return false; +- if (reversep1 != reversep2) +- return false; +- /* The sizes of the 2 accesses need to be the same. */ +- if (!known_eq (bytesize1, bytesize2)) +- return false; +- if (!operand_equal_p (core1, core2, 0)) +- return false; +- +- if (toffset1 && toffset2) +- { +- tree type = TREE_TYPE (toffset1); +- if (type != TREE_TYPE (toffset2)) +- toffset2 = fold_convert (type, toffset2); +- +- tree tdiff = fold_build2 (MINUS_EXPR, type, toffset1, toffset2); +- if (!cst_and_fits_in_hwi (tdiff)) +- return false; +- +- diff = int_cst_value (tdiff); +- } +- else if (toffset1 || toffset2) +- { +- /* If only one of the offsets is non-constant, the difference cannot +- be a constant. */ +- return false; +- } +- diff += bytepos1 - bytepos2; +- /* The offset between the 2 need to be 0. */ +- if (!known_eq (diff, 0)) +- return false; +- src = fold_build1_loc (gimple_location (use_stmt), +- VIEW_CONVERT_EXPR, +- TREE_TYPE (src2), src); +- } ++ src = new_src_based_on_copy (src2, dest, src); ++ if (!src) ++ return false; + /* For 2 memory refences and using a temporary to do the copy, + don't remove the temporary as the 2 memory references might overlap. + Note t does not need to be decl as it could be field. +@@ -1634,8 +1643,10 @@ optimize_agr_copyprop_arg (gimple *defstmt, gcall *call, + || is_gimple_min_invariant (*argptr) + || TYPE_VOLATILE (TREE_TYPE (*argptr))) + continue; +- if (!operand_equal_p (*argptr, dest, 0)) ++ tree newsrc = new_src_based_on_copy (*argptr, dest, src); ++ if (!newsrc) + continue; ++ + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "Simplified\n "); +@@ -1643,7 +1654,7 @@ optimize_agr_copyprop_arg (gimple *defstmt, gcall *call, + fprintf (dump_file, "after previous\n "); + print_gimple_stmt (dump_file, defstmt, 0, dump_flags); + } +- *argptr = unshare_expr (src); ++ *argptr = unshare_expr (newsrc); + changed = true; + if (dump_file && (dump_flags & TDF_DETAILS)) + { + +base-commit: e690b97761e18daccb4fff0151c97c1d0115b55f +-- +2.51.0 + diff --git a/16.0.0/gentoo/87_all_PR121962-forwprop-hang.patch b/16.0.0/gentoo/88_all_PR121962-forwprop-hang.patch similarity index 100% rename from 16.0.0/gentoo/87_all_PR121962-forwprop-hang.patch rename to 16.0.0/gentoo/88_all_PR121962-forwprop-hang.patch diff --git a/16.0.0/gentoo/README.history b/16.0.0/gentoo/README.history index 7db3c43..023c43f 100644 --- a/16.0.0/gentoo/README.history +++ b/16.0.0/gentoo/README.history @@ -1,6 +1,7 @@ 15 ???? - + 87_all_PR121962-forwprop-hang.patch + + 87_all_PR121962-forwprop-hang-prereq.patch + + 88_all_PR121962-forwprop-hang.patch 14 7 September 2025
