]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[PR rtl-optimization/123994] Bullet-proof RTL-SSA loop to determine insertion location
authorJeff Law <jeffrey.law@oss.qualcomm.com>
Sat, 21 Feb 2026 18:49:11 +0000 (11:49 -0700)
committerJeff Law <jeffrey.law@oss.qualcomm.com>
Sat, 21 Feb 2026 18:49:11 +0000 (11:49 -0700)
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.

gcc/rtl-ssa/changes.cc
gcc/testsuite/gcc.dg/torture/pr123994.c [new file with mode: 0644]

index e0df982880c73416d999d8b45874c91e8690f874..8afe8ea4eb35c5ab3fe82effcde95c4eec2bb1c4 100644 (file)
@@ -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 (file)
index 0000000..3db7d85
--- /dev/null
@@ -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];
+}