commit:     160884cda0c273ff197b29a311dfaf6ae49a9663
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Sat Feb  7 01:15:46 2026 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sat Feb  7 01:15:46 2026 +0000
URL:        https://gitweb.gentoo.org/proj/gcc-patches.git/commit/?id=160884cd

16.0.0: add various ICE fixes:

Bug: https://gcc.gnu.org/PR117217
Bug: https://gcc.gnu.org/PR122856
Bug: https://gcc.gnu.org/PR123958
Signed-off-by: Sam James <sam <AT> gentoo.org>

 16.0.0/gentoo/87_all_PR123958.patch | 135 ++++++++++++++++++++++++++++++
 16.0.0/gentoo/88_all_PR122856.patch | 147 +++++++++++++++++++++++++++++++++
 16.0.0/gentoo/89_all_PR117217.patch | 158 ++++++++++++++++++++++++++++++++++++
 16.0.0/gentoo/README.history        |   3 +
 4 files changed, 443 insertions(+)

diff --git a/16.0.0/gentoo/87_all_PR123958.patch 
b/16.0.0/gentoo/87_all_PR123958.patch
new file mode 100644
index 0000000..f4a5779
--- /dev/null
+++ b/16.0.0/gentoo/87_all_PR123958.patch
@@ -0,0 +1,135 @@
+From 21df24467146291e38e64baec6eb2deb5c143010 Mon Sep 17 00:00:00 2001
+Message-ID: 
<21df24467146291e38e64baec6eb2deb5c143010.1770426893.git....@gentoo.org>
+From: Roger Sayle <[email protected]>
+Date: Fri, 6 Feb 2026 20:49:55 +0000
+Subject: [PATCH 1/3] PR tree-optimization/123958: FMA vs pow(x,2.0) [vs errno]
+
+---
+ gcc/testsuite/g++.target/i386/pr124002.C | 15 ++++++++++
+ gcc/testsuite/gcc.dg/errno-4.c           | 35 ++++++++++++++++++++++++
+ gcc/testsuite/gcc.target/i386/pr123958.c | 18 ++++++++++++
+ gcc/tree-ssa-math-opts.cc                | 19 -------------
+ 4 files changed, 68 insertions(+), 19 deletions(-)
+ create mode 100644 gcc/testsuite/g++.target/i386/pr124002.C
+ create mode 100644 gcc/testsuite/gcc.dg/errno-4.c
+ create mode 100644 gcc/testsuite/gcc.target/i386/pr123958.c
+
+diff --git a/gcc/testsuite/g++.target/i386/pr124002.C 
b/gcc/testsuite/g++.target/i386/pr124002.C
+new file mode 100644
+index 000000000000..033cd3de870e
+--- /dev/null
++++ b/gcc/testsuite/g++.target/i386/pr124002.C
+@@ -0,0 +1,15 @@
++/* { dg-do compile } */
++/* { dg-options "-O2 -march=znver3" } */
++
++extern "C" double pow(double, double);
++double sigmoid_x;
++double sigmoid() {
++  if (sigmoid_x)
++    return sigmoid_x;
++  return 0;
++}
++double der_sigmoid() {
++  double tmp = sigmoid();
++  return tmp - pow(tmp, 2);
++}
++
+diff --git a/gcc/testsuite/gcc.dg/errno-4.c b/gcc/testsuite/gcc.dg/errno-4.c
+new file mode 100644
+index 000000000000..d7b80c1ca418
+--- /dev/null
++++ b/gcc/testsuite/gcc.dg/errno-4.c
+@@ -0,0 +1,35 @@
++/* PR middle-end/123826 */
++/* { dg-do run } */
++/* { dg-options "-O2" } */
++
++#ifdef __NO_MATH_ERRNO__
++int main() { return 0; }
++#else
++#include <errno.h>
++#include <float.h>
++#include <math.h>
++
++double foo(double x)
++{
++  return x + pow(x, 2.0);
++}
++
++int main()
++{
++#ifdef math_errhandling
++#ifdef MATH_ERRNO
++  if ((math_errhandling & MATH_ERRNO) == 0)
++    return 0;
++#else
++  if ((math_errhandling & 1) == 0)
++    return 0;
++#endif
++#endif
++
++  errno = 0;
++  double x = foo(DBL_MAX);
++  if (errno != ERANGE)
++    __builtin_abort ();
++  return 0;
++}
++#endif
+diff --git a/gcc/testsuite/gcc.target/i386/pr123958.c 
b/gcc/testsuite/gcc.target/i386/pr123958.c
+new file mode 100644
+index 000000000000..75064e880b4f
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/pr123958.c
+@@ -0,0 +1,18 @@
++/* { dg-do compile } */
++/* { dg-options "-O3 -march=znver3" } */
++
++float fnk00xX_rae1_1;
++double pow(double, double);
++double sqrt(double);
++void write_r4(float *);
++void fnk00xX() {
++  int i;
++  float rs2;
++  double ds2;
++  for (; i; i += 1) {
++    sqrt(i);
++    ds2 = ds2 + pow(fnk00xX_rae1_1, 2.0);
++    rs2 = ds2;
++  }
++  write_r4(&rs2);
++}
+diff --git a/gcc/tree-ssa-math-opts.cc b/gcc/tree-ssa-math-opts.cc
+index 1655b68cb9c6..6d69711fffbd 100644
+--- a/gcc/tree-ssa-math-opts.cc
++++ b/gcc/tree-ssa-math-opts.cc
+@@ -6623,25 +6623,6 @@ math_opts_dom_walker::after_dom_children (basic_block 
bb)
+       {
+         switch (gimple_call_combined_fn (stmt))
+           {
+-          CASE_CFN_POW:
+-            if (gimple_call_lhs (stmt)
+-                && TREE_CODE (gimple_call_arg (stmt, 1)) == REAL_CST
+-                && real_equal (&TREE_REAL_CST (gimple_call_arg (stmt, 1)),
+-                               &dconst2)
+-                && convert_mult_to_fma (stmt,
+-                                        gimple_call_arg (stmt, 0),
+-                                        gimple_call_arg (stmt, 0),
+-                                        &fma_state))
+-              {
+-                unlink_stmt_vdef (stmt);
+-                if (gsi_remove (&gsi, true)
+-                    && gimple_purge_dead_eh_edges (bb))
+-                  *m_cfg_changed_p = true;
+-                release_defs (stmt);
+-                continue;
+-              }
+-            break;
+-
+           case CFN_COND_MUL:
+             if (convert_mult_to_fma (stmt,
+                                      gimple_call_arg (stmt, 1),
+-- 
+2.53.0
+

diff --git a/16.0.0/gentoo/88_all_PR122856.patch 
b/16.0.0/gentoo/88_all_PR122856.patch
new file mode 100644
index 0000000..0475444
--- /dev/null
+++ b/16.0.0/gentoo/88_all_PR122856.patch
@@ -0,0 +1,147 @@
+From 80dbdf1dbe811385a0a75758143a6367c1fe542d Mon Sep 17 00:00:00 2001
+Message-ID: 
<80dbdf1dbe811385a0a75758143a6367c1fe542d.1770426893.git....@gentoo.org>
+In-Reply-To: 
<21df24467146291e38e64baec6eb2deb5c143010.1770426893.git....@gentoo.org>
+References: 
<21df24467146291e38e64baec6eb2deb5c143010.1770426893.git....@gentoo.org>
+From: Martin Jambor <[email protected]>
+Date: Fri, 6 Feb 2026 23:14:13 +0100
+Subject: [PATCH 2/3] ipa-cp: Also look at self-recursive ancestor jump
+ functions (PR122856)
+
+Hi,
+
+PR 122856 shows that when looking at self recursive calls with
+self-feeding jump functions, we did consider pass-through functions
+but not ancestor functions with zero offsets.  This then leads to the
+fact that constants which were collected from IPA-CP lattices were not
+among those collected from available edges, triggering a verification
+assert.
+
+This patch fixes that by also detecting self-feeding ancestor jump
+functions.
+
+Bootstrapped and tested on x86_64-linux.  OK for master and affected
+release branches?
+
+Thanks,
+
+Martin
+
+gcc/ChangeLog:
+
+2026-02-06  Martin Jambor  <[email protected]>
+
+       PR ipa/122856
+       * ipa-cp.cc (self_recursive_pass_through_p): Test jump function type 
first.
+       (self_recursive_ancestor_p): New function.
+       (find_scalar_values_for_callers_subset): Test also for self-recursive
+       ancestor jump functions.
+       (push_agg_values_for_index_from_edge): Likewise.
+
+gcc/testsuite/ChangeLog:
+
+2026-02-06  Martin Jambor  <[email protected]>
+
+PR ipa/122856
+       * g++.dg/ipa/pr122856.C: New test.
+---
+ gcc/ipa-cp.cc                       | 28 +++++++++++++++++++++++++---
+ gcc/testsuite/g++.dg/ipa/pr122856.C | 26 ++++++++++++++++++++++++++
+ 2 files changed, 51 insertions(+), 3 deletions(-)
+ create mode 100644 gcc/testsuite/g++.dg/ipa/pr122856.C
+
+diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc
+index 339d306251c5..5b7cb3cdb434 100644
+--- a/gcc/ipa-cp.cc
++++ b/gcc/ipa-cp.cc
+@@ -5259,9 +5259,9 @@ self_recursive_pass_through_p (cgraph_edge *cs, 
ipa_jump_func *jfunc, int i,
+                              bool simple = true)
+ {
+   enum availability availability;
+-  if (cs->caller == cs->callee->function_symbol (&availability)
++  if (jfunc->type == IPA_JF_PASS_THROUGH
++      && cs->caller == cs->callee->function_symbol (&availability)
+       && availability > AVAIL_INTERPOSABLE
+-      && jfunc->type == IPA_JF_PASS_THROUGH
+       && (!simple || ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
+       && ipa_get_jf_pass_through_formal_id (jfunc) == i
+       && ipa_node_params_sum->get (cs->caller)
+@@ -5270,6 +5270,25 @@ self_recursive_pass_through_p (cgraph_edge *cs, 
ipa_jump_func *jfunc, int i,
+   return false;
+ }
+ 
++/* Return true if JFUNC, which describes the i-th parameter of call CS, is an
++   ancestor function with zero offset to itself when the cgraph_node involved
++   is not an IPA-CP clone.  */
++
++static bool
++self_recursive_ancestor_p (cgraph_edge *cs, ipa_jump_func *jfunc, int i)
++{
++  enum availability availability;
++  if (jfunc->type == IPA_JF_ANCESTOR
++      && cs->caller == cs->callee->function_symbol (&availability)
++      && availability > AVAIL_INTERPOSABLE
++      && ipa_get_jf_ancestor_offset (jfunc) == 0
++      && ipa_get_jf_ancestor_formal_id (jfunc) == i
++      && ipa_node_params_sum->get (cs->caller)
++      && !ipa_node_params_sum->get (cs->caller)->ipcp_orig_node)
++    return true;
++  return false;
++}
++
+ /* Return true if JFUNC, which describes a part of an aggregate represented or
+    pointed to by the i-th parameter of call CS, is a pass-through function to
+    itself when the cgraph_node involved is not an IPA-CP clone..  When
+@@ -5361,6 +5380,8 @@ find_scalar_values_for_callers_subset (vec<tree> 
&known_csts,
+                               op_type);
+             t = ipacp_value_safe_for_type (type, t);
+           }
++        else if (self_recursive_ancestor_p (cs, jump_func, i))
++          continue;
+         else
+           t = ipa_value_from_jfunc (ipa_node_params_sum->get (cs->caller),
+                                     jump_func, type);
+@@ -5515,7 +5536,8 @@ push_agg_values_for_index_from_edge (struct cgraph_edge 
*cs, int index,
+             && !src_plats->aggs_bottom
+             && (agg_jf_preserved || !src_plats->aggs_by_ref))
+           {
+-            if (interim && self_recursive_pass_through_p (cs, jfunc, index))
++            if (interim && (self_recursive_pass_through_p (cs, jfunc, index)
++                            || self_recursive_ancestor_p (cs, jfunc, index)))
+               {
+                 interim->push_adjusted_values (src_idx, index, unit_delta,
+                                                res);
+diff --git a/gcc/testsuite/g++.dg/ipa/pr122856.C 
b/gcc/testsuite/g++.dg/ipa/pr122856.C
+new file mode 100644
+index 000000000000..b634e6280095
+--- /dev/null
++++ b/gcc/testsuite/g++.dg/ipa/pr122856.C
+@@ -0,0 +1,26 @@
++/* { dg-do compile } */
++/* { dg-options "-O3 -std=gnu++11" } */
++
++template <typename T>
++class Base {
++public:
++    virtual int get();
++    virtual ~Base() = default;
++};
++
++template <typename T>
++class Derived : public Base<T> {
++public:
++    int get() override { return Base<T>::get(); }
++};
++
++template <typename T>
++int Base<T>::get() {
++
++    return static_cast<Derived<int>*>(this)->get();
++}
++
++int main() {
++    Derived<int> d;
++    return d.get();
++}
+-- 
+2.53.0
+

diff --git a/16.0.0/gentoo/89_all_PR117217.patch 
b/16.0.0/gentoo/89_all_PR117217.patch
new file mode 100644
index 0000000..6acbc26
--- /dev/null
+++ b/16.0.0/gentoo/89_all_PR117217.patch
@@ -0,0 +1,158 @@
+From 0f09d09f2445658e302e4c98284d7b7b7a911b4b Mon Sep 17 00:00:00 2001
+Message-ID: 
<0f09d09f2445658e302e4c98284d7b7b7a911b4b.1770426893.git....@gentoo.org>
+In-Reply-To: 
<21df24467146291e38e64baec6eb2deb5c143010.1770426893.git....@gentoo.org>
+References: 
<21df24467146291e38e64baec6eb2deb5c143010.1770426893.git....@gentoo.org>
+From: Martin Jambor <[email protected]>
+Date: Fri, 6 Feb 2026 23:18:43 +0100
+Subject: [PATCH 3/3] tree-sra: Do not propagate bit-field accesses across
+ assignments (PR 117217)
+
+Hi,
+
+on master at least, this is a bug which no longer reproduces with the
+provided test-cases because after r15-5747-gfd62fdc5e1b3c4:(Jakub
+Jelinek: c++: Small initial fixes for zeroing of padding bits
+[PR117256]), the input to SRA looks very different and SRA does not do
+anything.
+
+However, before that commit, SRA sees the following input and if it
+encountered something similar now, it could still misbehave in the
+same way:
+
+  D.2908.i = 0;
+  D.2908.b = 0;
+  e ={v} {CLOBBER(bob)};
+  e.b = MEM[(const struct B &)&D.2908];
+  D.2908 ={v} {CLOBBER(eos)};
+
+(Where the "e" in "e.b" is actually a MEM_REF of the union type into
+&e so that is why the "data" field is missing.)
+
+Field D.2908.b is a SRA candidate of boolean type and has size 1 bit
+because its decl has size 1 bit even though its type has size 8 bits.
+
+The SRA access representing the store to D.2908.b is then propagated
+across the assignment to e and in the process
+build_user_friendly_ref_for_offset tries to find a nice expression for
+it to possibly use in warnings.  It finds types_compatible_p
+e.data.a.b which however has size 8 bits and so the verifier screams
+when it discovers the discrepancy from the copied-over size of 1 bit.
+
+This patch avoids the situation by refusing to propagate
+non-byte-sized accesses across assignments.
+
+The patch has passed bootstrap and test on x86_64 on master, I am now
+running the same on top of the gcc-14 branch.  OK for master and all
+active release branches if it passes there as well?
+
+Thanks,
+
+Martin
+
+gcc/ChangeLog:
+
+2026-02-06  Martin Jambor  <[email protected]>
+
+       PR tree-optimization/117217
+       * tree-sra.cc (propagate_subaccesses_from_rhs): Do not propagate
+       bit-field children.
+       (propagate_subaccesses_from_lhs): Likewise.
+
+gcc/testsuite/ChangeLog:
+
+2026-02-06  Martin Jambor  <[email protected]>
+
+PR tree-optimization/117217
+       * g++.dg/torture/pr117217-1.C: New test.
+       * g++.dg/torture/pr117217-2.C: Likewise.
+---
+ gcc/testsuite/g++.dg/torture/pr117217-1.C | 24 +++++++++++++++++++++++
+ gcc/testsuite/g++.dg/torture/pr117217-2.C | 24 +++++++++++++++++++++++
+ gcc/tree-sra.cc                           |  2 ++
+ 3 files changed, 50 insertions(+)
+ create mode 100644 gcc/testsuite/g++.dg/torture/pr117217-1.C
+ create mode 100644 gcc/testsuite/g++.dg/torture/pr117217-2.C
+
+diff --git a/gcc/testsuite/g++.dg/torture/pr117217-1.C 
b/gcc/testsuite/g++.dg/torture/pr117217-1.C
+new file mode 100644
+index 000000000000..887ab6945359
+--- /dev/null
++++ b/gcc/testsuite/g++.dg/torture/pr117217-1.C
+@@ -0,0 +1,24 @@
++struct [[gnu::packed]] A {
++  int i;
++  bool b;
++};
++
++struct [[gnu::packed]] B {
++  int i;
++  bool b : 1;
++};
++
++struct E {
++  union Data {
++    A a;
++    B b;
++    Data(const B &b) : b(b) {}
++  } data;
++};
++
++extern B copy;
++
++int main() {
++  E e{{B()}};
++  copy = e.data.b; // NEEDED FOR ICE
++}
+diff --git a/gcc/testsuite/g++.dg/torture/pr117217-2.C 
b/gcc/testsuite/g++.dg/torture/pr117217-2.C
+new file mode 100644
+index 000000000000..19390212b48c
+--- /dev/null
++++ b/gcc/testsuite/g++.dg/torture/pr117217-2.C
+@@ -0,0 +1,24 @@
++struct a {
++  int b;
++  long c;
++  long d;
++  bool f;
++};
++struct g {
++  int b;
++  long c;
++  long d;
++  bool : 1;
++} h;
++struct l {
++  union i {
++    a j;
++    g k;
++    i(g m) : k(m) {}
++  } data;
++};
++int main() {
++  l e{g()};
++  h = e.data.k;
++  return 0;
++}
+diff --git a/gcc/tree-sra.cc b/gcc/tree-sra.cc
+index edb03fe237b8..65ae5c99a0ba 100644
+--- a/gcc/tree-sra.cc
++++ b/gcc/tree-sra.cc
+@@ -3265,6 +3265,7 @@ propagate_subaccesses_from_rhs (struct access *lacc, 
struct access *racc)
+       }
+ 
+       if (rchild->grp_unscalarizable_region
++        || (rchild->size % BITS_PER_UNIT) != 0
+         || !budget_for_propagation_access (lacc->base))
+       {
+         if (!lacc->grp_write && access_or_its_child_written (rchild))
+@@ -3324,6 +3325,7 @@ propagate_subaccesses_from_lhs (struct access *lacc, 
struct access *racc)
+       HOST_WIDE_INT norm_offset = lchild->offset + norm_delta;
+ 
+       if (lchild->grp_unscalarizable_region
++        || (lchild->size % BITS_PER_UNIT) != 0
+         || child_would_conflict_in_acc (racc, norm_offset, lchild->size,
+                                         &matching_acc)
+         || !budget_for_propagation_access (racc->base))
+-- 
+2.53.0
+

diff --git a/16.0.0/gentoo/README.history b/16.0.0/gentoo/README.history
index 63c4f67..7ed0d4a 100644
--- a/16.0.0/gentoo/README.history
+++ b/16.0.0/gentoo/README.history
@@ -1,6 +1,9 @@
 36     ????
 
        - 84_all_PR116975-GDCFLAGS.patch
+       + 87_all_PR123958.patch
+       + 88_all_PR122856.patch
+       + 89_all_PR117217.patch
 
 35     2 February 2026
 

Reply via email to