commit: f21e135a23cad5ff1b7e608d783104bd62784586 Author: Sam James <sam <AT> gentoo <DOT> org> AuthorDate: Wed Nov 19 19:13:13 2025 +0000 Commit: Sam James <sam <AT> gentoo <DOT> org> CommitDate: Wed Nov 19 19:14:33 2025 +0000 URL: https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=f21e135a
sys-devel/gcc: backport two fixes to 16.0.0_p20251116-r1 Bug: https://bugs.gentoo.org/966242 Bug: https://gcc.gnu.org/PR122733 Bug: https://gcc.gnu.org/PR122745 Bug: https://gcc.gnu.org/PR122756 Closes: https://bugs.gentoo.org/966243 Signed-off-by: Sam James <sam <AT> gentoo.org> .../gcc/files/gcc-16.0.0_p20251116-pr122733.patch | 264 +++++++++++++++++++++ .../gcc/files/gcc-16.0.0_p20251116-pr122756.patch | 82 +++++++ sys-devel/gcc/gcc-16.0.0_p20251116-r1.ebuild | 58 +++++ 3 files changed, 404 insertions(+) diff --git a/sys-devel/gcc/files/gcc-16.0.0_p20251116-pr122733.patch b/sys-devel/gcc/files/gcc-16.0.0_p20251116-pr122733.patch new file mode 100644 index 000000000000..97f7e26c2548 --- /dev/null +++ b/sys-devel/gcc/files/gcc-16.0.0_p20251116-pr122733.patch @@ -0,0 +1,264 @@ +From cf82d18b90fff0e7f40f646fb22a9b95283f0a06 Mon Sep 17 00:00:00 2001 +Message-ID: <cf82d18b90fff0e7f40f646fb22a9b95283f0a06.1763579001.git....@gentoo.org> +From: Dhruv Chawla <[email protected]> +Date: Wed, 19 Nov 2025 04:55:08 -0800 +Subject: [PATCH] PR tree-optimization/122733: Remove patterns for (y << x) + {<,<=,>,>=} x + +These patterns should not be in match.pd as they require range +information checks that ideally belong in VRP. They were also causing +breakages as the checks weren't tight enough. + +Bootstrapped and regtested on aarch64-linux-gnu. + +Signed-off-by: Dhruv Chawla <[email protected]> + + PR tree-optimization/122733 + +gcc/ChangeLog: + + * match.pd: Remove patterns. Also call constant_boolean_node instead of + build_one_cst and build_zero_cst and simplify equality checking + to one pattern. + +gcc/testsuite/ChangeLog: + +* gcc.dg/match-shift-cmp-1.c: Update test to only check + equality. + * gcc.dg/match-shift-cmp-2.c: Likewise. + * gcc.dg/match-shift-cmp-3.c: Likewise. + * gcc.dg/match-shift-cmp-4.c: Removed. +--- + gcc/match.pd | 32 ++------------- + gcc/testsuite/gcc.dg/match-shift-cmp-1.c | 11 +---- + gcc/testsuite/gcc.dg/match-shift-cmp-2.c | 23 ++--------- + gcc/testsuite/gcc.dg/match-shift-cmp-3.c | 27 ++++++------- + gcc/testsuite/gcc.dg/match-shift-cmp-4.c | 51 ------------------------ + 5 files changed, 22 insertions(+), 122 deletions(-) + delete mode 100644 gcc/testsuite/gcc.dg/match-shift-cmp-4.c + +diff --git a/gcc/match.pd b/gcc/match.pd +index 63d56b081925..db774eaf696c 100644 +--- a/gcc/match.pd ++++ b/gcc/match.pd +@@ -1339,37 +1339,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) + (if (INTEGRAL_TYPE_P (type)) + (rshift (op @0 @2) @1)))) + +-/* (y << x) == x -> 0 when y != 0. */ +-(simplify +- (eq:c (nop_convert1? (lshift @0 @1)) (nop_convert2? @1)) +- (if (INTEGRAL_TYPE_P (TREE_TYPE (@1)) +- && tree_expr_nonzero_p (@0)) +- { build_zero_cst (type); })) +- +-/* (y << x) {<,<=} x -> 0 when y > 0. */ +-(for cmp (lt le) +- (simplify +- (cmp:c (nop_convert1? (lshift @0 @1)) (nop_convert2? @1)) +- (if (INTEGRAL_TYPE_P (TREE_TYPE (@1)) +- && tree_expr_nonzero_p (@0) +- && tree_expr_nonnegative_p (@0)) +- { build_zero_cst (type); }))) +- +-/* (y << x) != x -> 1 when y != 0. */ +-(simplify +- (ne:c (nop_convert1? (lshift @0 @1)) (nop_convert2? @1)) +- (if (INTEGRAL_TYPE_P (TREE_TYPE (@1)) +- && tree_expr_nonzero_p (@0)) +- { build_one_cst (type); })) +- +-/* (y << x) {>,>=} x -> 1 when y > 0. */ +-(for cmp (gt ge) ++/* (y << x) == x -> false and (y << x) != x -> true when y != 0. */ ++(for cmp (eq ne) + (simplify + (cmp:c (nop_convert1? (lshift @0 @1)) (nop_convert2? @1)) + (if (INTEGRAL_TYPE_P (TREE_TYPE (@1)) +- && tree_expr_nonzero_p (@0) +- && tree_expr_nonnegative_p (@0)) +- { build_one_cst (type); }))) ++ && tree_expr_nonzero_p (@0)) ++ { constant_boolean_node (cmp != EQ_EXPR, type); }))) + + /* Fold (1 << (C - x)) where C = precision(type) - 1 + into ((1 << C) >> x). */ +diff --git a/gcc/testsuite/gcc.dg/match-shift-cmp-1.c b/gcc/testsuite/gcc.dg/match-shift-cmp-1.c +index b22d57d370f1..7a69cd194376 100644 +--- a/gcc/testsuite/gcc.dg/match-shift-cmp-1.c ++++ b/gcc/testsuite/gcc.dg/match-shift-cmp-1.c +@@ -34,17 +34,8 @@ typedef enum + + TEST_OP_CST (eq, ==, 1) + TEST_OP_CST (ne, !=, 2) +-TEST_OP_CST (lt, <, 3) +-TEST_OP_CST (gt, >, 4) +-TEST_OP_CST (le, <=, 5) +-TEST_OP_CST (ge, >=, 6) + + TEST_OP (eq, ==) + TEST_OP (ne, !=) +-TEST_OP (lt, <) +-TEST_OP (gt, >) +-TEST_OP (le, <=) +-TEST_OP (ge, >=) + +-/* FIXME: The lt, le, gt and ge cases for int and enum don't get optimized. */ +-/* { dg-final { scan-tree-dump-times "<<" 8 optimized } } */ ++/* { dg-final { scan-tree-dump-not "<<" optimized } } */ +diff --git a/gcc/testsuite/gcc.dg/match-shift-cmp-2.c b/gcc/testsuite/gcc.dg/match-shift-cmp-2.c +index 96a2fd954f63..3d514ba1ee1b 100644 +--- a/gcc/testsuite/gcc.dg/match-shift-cmp-2.c ++++ b/gcc/testsuite/gcc.dg/match-shift-cmp-2.c +@@ -36,27 +36,12 @@ typedef enum + + TEST_OP_CST (eq, ==, 0) + TEST_OP_CST (ne, !=, 0) +-TEST_OP_CST (lt, <, 0) +-TEST_OP_CST (gt, >, 0) +-TEST_OP_CST (le, <=, 0) +-TEST_OP_CST (ge, >=, 0) + + TEST_OP (eq, ==) + TEST_OP (ne, !=) +-TEST_OP (lt, <) +-TEST_OP (gt, >) +-TEST_OP (le, <=) +-TEST_OP (ge, >=) + + /* These end up getting folded by other patterns. */ +-/* { dg-final { scan-tree-dump-times "x_\\d\\(D\\) == 0" 8 optimized } } */ +-/* { dg-final { scan-tree-dump-times "x_\\d\\(D\\) != 0" 8 optimized } } */ +-/* { dg-final { scan-tree-dump-times "x_\\d\\(D\\) > 0" 4 optimized } } */ +-/* { dg-final { scan-tree-dump-times "x_\\d\\(D\\) < 0" 4 optimized } } */ +-/* { dg-final { scan-tree-dump-times "x_\\d\\(D\\) >= 0" 4 optimized } } */ +-/* { dg-final { scan-tree-dump-times "x_\\d\\(D\\) <= 0" 4 optimized } } */ +-/* { dg-final { scan-tree-dump-times "~x_\\d\\(D\\)" 4 optimized } } */ +-/* { dg-final { scan-tree-dump-times "return x_\\d\\(D\\);" 4 optimized } } */ +-/* { dg-final { scan-tree-dump-times "return 0;" 4 optimized } } */ +-/* { dg-final { scan-tree-dump-times "return 1;" 4 optimized } } */ +-/* Total: 48. */ ++/* { dg-final { scan-tree-dump-times "x_\\d\\(D\\) == 0" 6 optimized } } */ ++/* { dg-final { scan-tree-dump-times "x_\\d\\(D\\) != 0" 6 optimized } } */ ++/* { dg-final { scan-tree-dump-times "~x_\\d\\(D\\)" 2 optimized } } */ ++/* { dg-final { scan-tree-dump-times "return x_\\d\\(D\\);" 2 optimized } } */ +diff --git a/gcc/testsuite/gcc.dg/match-shift-cmp-3.c b/gcc/testsuite/gcc.dg/match-shift-cmp-3.c +index 34380cfeb969..e46ac30b905f 100644 +--- a/gcc/testsuite/gcc.dg/match-shift-cmp-3.c ++++ b/gcc/testsuite/gcc.dg/match-shift-cmp-3.c +@@ -1,25 +1,27 @@ + /* { dg-do compile } */ + /* { dg-options "-O2 -fdump-tree-optimized" } */ + +-/* The fold (y << x) <op> x -> 0|1 shouldn't trigger when y is negative or +- zero unsigned (except for == and !=). */ ++/* The fold (y << x) <op> x -> 0|1 should trigger when y is negative ++ unsigned. */ + + #define TEST_ONE_CST(n, op, type, cst) \ +- bool lshift_cst_##type##_##n (type x) { return ((cst << x) op x); } ++ bool lshift_cst_##type##_##n (type x) { return ((unsigned) (cst) << x) op x; } + + #define TEST_OP_CST(n, op, cst) \ ++ TEST_ONE_CST (n, op, unsigned, cst) \ + TEST_ONE_CST (n, op, int, cst) \ + TEST_ONE_CST (n, op, test_enum, cst) + + #define TEST_ONE(n, op, type) \ + bool lshift_##type##_##n (type x, type y) \ + { \ +- if (y > 0) \ ++ if ((int) y <= 0) \ + __builtin_unreachable (); \ +- return ((y << x) op x); \ ++ return ((unsigned) (y) << x) op x; \ + } + + #define TEST_OP(n, op) \ ++ TEST_ONE (n, op, unsigned) \ + TEST_ONE (n, op, int) \ + TEST_ONE (n, op, test_enum) + +@@ -31,14 +33,11 @@ typedef enum + TWO = 2 + } test_enum; + +-TEST_OP_CST (lt, <, -1) +-TEST_OP_CST (gt, >, -2) +-TEST_OP_CST (le, <=, -3) +-TEST_OP_CST (ge, >=, -4) ++TEST_OP_CST (eq, ==, -1) ++TEST_OP_CST (ne, !=, -2) + +-TEST_OP (lt, <) +-TEST_OP (gt, >) +-TEST_OP (le, <=) +-TEST_OP (ge, >=) ++TEST_OP (eq, ==) ++TEST_OP (ne, !=) + +-/* { dg-final { scan-tree-dump-times "<<" 16 optimized } } */ ++/* { dg-final { scan-tree-dump-times "return 0;" 6 optimized } } */ ++/* { dg-final { scan-tree-dump-times "return 1;" 6 optimized } } */ +diff --git a/gcc/testsuite/gcc.dg/match-shift-cmp-4.c b/gcc/testsuite/gcc.dg/match-shift-cmp-4.c +deleted file mode 100644 +index 629e2a376d11..000000000000 +--- a/gcc/testsuite/gcc.dg/match-shift-cmp-4.c ++++ /dev/null +@@ -1,51 +0,0 @@ +-/* { dg-do compile } */ +-/* { dg-options "-O2 -fdump-tree-optimized" } */ +- +-/* The fold (y << x) <op> x -> 0|1 should trigger when y is negative +- unsigned. */ +- +-#define TEST_ONE_CST(n, op, type, cst) \ +- bool lshift_cst_##type##_##n (type x) { return ((unsigned) (cst) << x) op x; } +- +-#define TEST_OP_CST(n, op, cst) \ +- TEST_ONE_CST (n, op, unsigned, cst) \ +- TEST_ONE_CST (n, op, int, cst) \ +- TEST_ONE_CST (n, op, test_enum, cst) +- +-#define TEST_ONE(n, op, type) \ +- bool lshift_##type##_##n (type x, type y) \ +- { \ +- if ((int) y <= 0) \ +- __builtin_unreachable (); \ +- return ((unsigned) (y) << x) op x; \ +- } +- +-#define TEST_OP(n, op) \ +- TEST_ONE (n, op, unsigned) \ +- TEST_ONE (n, op, int) \ +- TEST_ONE (n, op, test_enum) +- +-typedef enum +-{ +- MONE = -1, +- ZERO = 0, +- ONE = 1, +- TWO = 2 +-} test_enum; +- +-TEST_OP_CST (eq, ==, -1) +-TEST_OP_CST (ne, !=, -2) +-TEST_OP_CST (lt, <, -3) +-TEST_OP_CST (gt, >, -4) +-TEST_OP_CST (le, <=, -5) +-TEST_OP_CST (ge, >=, -6) +- +-TEST_OP (eq, ==) +-TEST_OP (ne, !=) +-TEST_OP (lt, <) +-TEST_OP (gt, >) +-TEST_OP (le, <=) +-TEST_OP (ge, >=) +- +-/* { dg-final { scan-tree-dump-times "return 0;" 18 optimized } } */ +-/* { dg-final { scan-tree-dump-times "return 1;" 18 optimized } } */ + +base-commit: 00c16753875ddd9fcc9a6484717a1fc6dc95b691 +-- +2.52.0 + diff --git a/sys-devel/gcc/files/gcc-16.0.0_p20251116-pr122756.patch b/sys-devel/gcc/files/gcc-16.0.0_p20251116-pr122756.patch new file mode 100644 index 000000000000..fc0bc6fc5718 --- /dev/null +++ b/sys-devel/gcc/files/gcc-16.0.0_p20251116-pr122756.patch @@ -0,0 +1,82 @@ +https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=00c16753875ddd9fcc9a6484717a1fc6dc95b691 + +From 00c16753875ddd9fcc9a6484717a1fc6dc95b691 Mon Sep 17 00:00:00 2001 +From: Andrew MacLeod <[email protected]> +Date: Wed, 19 Nov 2025 11:31:16 -0500 +Subject: [PATCH] Avoid recursion with SCEV + +Ranger should not invoke SCEV if its already in the middle of a SCEV call. + + PR tree-optimization/122756 + gcc/ + * gimple-range-fold.cc (range_of_ssa_name_with_loop_info): Do + not invoke SCEV if already in a SCEV call. + + gcc/testsuite/ + * gcc.dg/pr122756.c: New. +--- + gcc/gimple-range-fold.cc | 15 ++++++++++++--- + gcc/testsuite/gcc.dg/pr122756.c | 15 +++++++++++++++ + 2 files changed, 27 insertions(+), 3 deletions(-) + create mode 100644 gcc/testsuite/gcc.dg/pr122756.c + +diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc +index 63e114e4d044..bd5e53516b79 100644 +--- a/gcc/gimple-range-fold.cc ++++ b/gcc/gimple-range-fold.cc +@@ -1252,11 +1252,15 @@ fold_using_range::range_of_ssa_name_with_loop_info (vrange &r, tree name, + class loop *l, gphi *phi, + fur_source &src) + { ++ static bool in_scev_call = false; + gcc_checking_assert (TREE_CODE (name) == SSA_NAME); ++ // Avoid SCEV callbacks causing infinite recursion. ++ if (in_scev_call) ++ r.set_varying (TREE_TYPE (name)); + // SCEV currently invokes get_range_query () for values. If the query + // being passed in is not the same SCEV will use, do not invoke SCEV. + // This can be remove if/when SCEV uses a passed in range-query. +- if (src.query () != get_range_query (cfun)) ++ else if (src.query () != get_range_query (cfun)) + { + r.set_varying (TREE_TYPE (name)); + // Report the msmatch if SRC is not the global query. The cache +@@ -1266,8 +1270,13 @@ fold_using_range::range_of_ssa_name_with_loop_info (vrange &r, tree name, + fprintf (dump_file, + "fold_using-range:: SCEV not invoked due to mismatched queries\n"); + } +- else if (!range_of_var_in_loop (r, name, l, phi, src.query ())) +- r.set_varying (TREE_TYPE (name)); ++ else ++ { ++ in_scev_call = true; ++ if (!range_of_var_in_loop (r, name, l, phi, src.query ())) ++ r.set_varying (TREE_TYPE (name)); ++ in_scev_call = false; ++ } + } + + // ----------------------------------------------------------------------- +diff --git a/gcc/testsuite/gcc.dg/pr122756.c b/gcc/testsuite/gcc.dg/pr122756.c +new file mode 100644 +index 000000000000..62994696ac88 +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/pr122756.c +@@ -0,0 +1,15 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O3" } */ ++/* { dg-additional-options "-march=rv64gcv -mabi=lp64d" { target { rv64 } } } */ ++ ++long a; ++void b() { ++ unsigned long c, d; ++ for (;; c = d + 2000) { ++ d = c; ++ for (; d < a; d += 2) ++ if (d % 2) ++ for (;;) ++ ; ++ } ++} +-- +2.43.7 diff --git a/sys-devel/gcc/gcc-16.0.0_p20251116-r1.ebuild b/sys-devel/gcc/gcc-16.0.0_p20251116-r1.ebuild new file mode 100644 index 000000000000..09da684b6eef --- /dev/null +++ b/sys-devel/gcc/gcc-16.0.0_p20251116-r1.ebuild @@ -0,0 +1,58 @@ +# Copyright 1999-2025 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI=8 + +# Maintenance notes and explanations of GCC handling are on the wiki: +# https://wiki.gentoo.org/wiki/Project:Toolchain/sys-devel/gcc + +TOOLCHAIN_PATCH_DEV="sam" +TOOLCHAIN_HAS_TESTS=1 +PATCH_GCC_VER="16.0.0" +PATCH_VER="23" +MUSL_VER="1" +MUSL_GCC_VER="16.0.0" +PYTHON_COMPAT=( python3_{11..14} ) + +if [[ -n ${TOOLCHAIN_GCC_RC} ]] ; then + # Cheesy hack for RCs + MY_PV=$(ver_cut 1).$((($(ver_cut 2) + 1))).$((($(ver_cut 3) - 1)))-RC-$(ver_cut 5) + MY_P=${PN}-${MY_PV} + GCC_TARBALL_SRC_URI="mirror://gcc/snapshots/${MY_PV}/${MY_P}.tar.xz" + TOOLCHAIN_SET_S=no + S="${WORKDIR}"/${MY_P} +fi + +inherit toolchain + +if tc_is_live ; then + # Needs to be after inherit (for now?), bug #830908 + EGIT_BRANCH=master +elif [[ -z ${TOOLCHAIN_USE_GIT_PATCHES} ]] ; then + # Don't keyword live ebuilds + #KEYWORDS="~alpha ~amd64 ~arm ~arm64 ~hppa ~loong ~m68k ~mips ~ppc ~ppc64 ~riscv ~s390 ~sparc ~x86" + :; +fi + +if [[ ${CATEGORY} != cross-* ]] ; then + # Technically only if USE=hardened *too* right now, but no point in complicating it further. + # If GCC is enabling CET by default, we need glibc to be built with support for it. + # bug #830454 + RDEPEND="elibc_glibc? ( sys-libs/glibc[cet(-)?] )" + DEPEND="${RDEPEND}" +fi + +src_prepare() { + local p upstreamed_patches=( + # add them here + ) + for p in "${upstreamed_patches[@]}"; do + rm -v "${WORKDIR}/patch/${p}" || die + done + + toolchain_src_prepare + eapply "${FILESDIR}"/${PN}-13-fix-cross-fixincludes.patch + eapply "${FILESDIR}"/${P}-pr122733.patch + eapply "${FILESDIR}"/${P}-pr122756.patch + eapply_user +}
