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
+}

Reply via email to