https://gcc.gnu.org/g:c93f760922f767f385eeb5bc0d0942cce47dfb27

commit r16-7609-gc93f760922f767f385eeb5bc0d0942cce47dfb27
Author: Jeff Law <[email protected]>
Date:   Sat Feb 21 11:49:11 2026 -0700

    [PR rtl-optimization/123994] Bullet-proof RTL-SSA loop to determine 
insertion location
    
    As discussed in the PR, there's two things we want to do WRT this bug.
    
    First, we want to bullet-proof this loop.  It's trying to find an insertion
    point, but can run off the end of the insn chain in the process.  That's 
enough
    to fix the regression and the purpose of this patch.
    
    For gcc-17 Richard S. has a more invasive change which fixes the underlying
    cause of walking off the end of the insn chain.  This patch has the 
potential
    to trigger more combinations which in turn could trip over latent bugs, so 
we
    agreed to defer that fix until the gcc-17 cycle out of an abundance of 
caution.
    
    My fix has been bootstrapped and regression tested on x86.  Pushing to the
    trunk.
    
            PR rtl-optimization/123994
    gcc/
            * rtl-ssa/changes.cc (function_info::verify_insn_changes): Bullet
            proof loop to not fault if we run off the end of the insn chain.
    
    gcc/testsuite/
            * gcc.dg/torture/pr123994.c: New test.

Diff:
---
 gcc/rtl-ssa/changes.cc                  |  5 +++--
 gcc/testsuite/gcc.dg/torture/pr123994.c | 31 +++++++++++++++++++++++++++++++
 2 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/gcc/rtl-ssa/changes.cc b/gcc/rtl-ssa/changes.cc
index e0df982880c7..8afe8ea4eb35 100644
--- a/gcc/rtl-ssa/changes.cc
+++ b/gcc/rtl-ssa/changes.cc
@@ -110,9 +110,10 @@ function_info::verify_insn_changes 
(array_slice<insn_change *const> changes)
        // Make sure that the changes can be kept in their current order
        // while honoring all of the move ranges.
        min_insn = later_insn (min_insn, change->move_range.first);
-       while (min_insn != change->insn () && !can_insert_after (min_insn))
+       while (min_insn && min_insn != change->insn () && !can_insert_after 
(min_insn))
          min_insn = min_insn->next_nondebug_insn ();
-       if (*min_insn > *change->move_range.last)
+
+       if (!min_insn || *min_insn > *change->move_range.last)
          {
            if (dump_file && (dump_flags & TDF_DETAILS))
              fprintf (dump_file, "no viable insn position assignment\n");
diff --git a/gcc/testsuite/gcc.dg/torture/pr123994.c 
b/gcc/testsuite/gcc.dg/torture/pr123994.c
new file mode 100644
index 000000000000..3db7d85b9d4f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr123994.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-additional-options "-w" } */
+#include <stdint.h>
+#define BS_VEC(type, num) type __attribute__((vector_size(num * sizeof(type))))
+uint8_t backsmith_snippet_141(int16_t, uint64_t);
+int32_t backsmith_snippet_122(uint64_t BS_ARG_0, uint32_t BS_ARG_1)
+{
+    BS_ARG_0 =
+        BS_ARG_1 ? (BS_VEC(uint64_t, 16)){}[BS_ARG_0] : 4054722019416799465;
+    return BS_ARG_0;
+}
+uint16_t backsmith_pure_0(uint64_t BS_ARG_2, uint32_t BS_ARG_3)
+{
+    int64_t BS_VAR_0[6];
+    int8_t BS_VAR_3[80];
+    for (uint16_t BS_INC_0 = 0; BS_INC_0 < 8; BS_INC_0 += 1)
+    {
+        uint64_t BS_TEMP_590 = BS_INC_0;
+        BS_VAR_0[BS_INC_0] = BS_INC_0
+            ? (BS_TEMP_590 ? BS_ARG_2 >> BS_TEMP_590 : 0)
+                ?: backsmith_snippet_141(0, BS_INC_0)
+            : 0;
+        BS_VAR_3[BS_INC_0] =
+            backsmith_snippet_122(BS_VAR_0[6 ? (uint64_t)BS_INC_0 : 0] < 0,
+                                  BS_ARG_3)
+            ?: BS_ARG_3;
+    }
+    if (BS_ARG_2) BS_VAR_3[BS_ARG_3 < 80 ? BS_ARG_3 : 0] = 0;
+    return BS_VAR_3[4];
+}

Reply via email to