]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
rtl-ssa: Fix move range canonicalisation [PR115929]
authorRichard Sandiford <richard.sandiford@arm.com>
Wed, 17 Jul 2024 18:38:12 +0000 (19:38 +0100)
committerRichard Sandiford <richard.sandiford@arm.com>
Wed, 17 Jul 2024 18:38:12 +0000 (19:38 +0100)
In this PR, canonicalize_move_range walked off the end of a list
and triggered a null dereference.  There are multiple ways of fixing
that, but I think the approach taken in the patch should be
relatively efficient.

gcc/
PR rtl-optimization/115929
* rtl-ssa/movement.h (canonicalize_move_range): Check for null prev
and next insns and create an invalid move range for them.

gcc/testsuite/
PR rtl-optimization/115929
* gcc.dg/torture/pr115929-2.c: New test.

gcc/rtl-ssa/movement.h
gcc/testsuite/gcc.dg/torture/pr115929-2.c [new file with mode: 0644]

index 17d31e0b5cbe0ba79c619394e0056055b65cbbaa..ea1f788df49e1fafacbf5b29692c86536b6b5f9b 100644 (file)
@@ -76,9 +76,25 @@ inline bool
 canonicalize_move_range (insn_range_info &move_range, insn_info *insn)
 {
   while (move_range.first != insn && !can_insert_after (move_range.first))
-    move_range.first = move_range.first->next_nondebug_insn ();
+    if (auto *next = move_range.first->next_nondebug_insn ())
+      move_range.first = next;
+    else
+      {
+       // Invalidate the range.  prev_nondebug_insn is always nonnull
+       // if next_nondebug_insn is null.
+       move_range.last = move_range.first->prev_nondebug_insn ();
+       return false;
+      }
   while (move_range.last != insn && !can_insert_after (move_range.last))
-    move_range.last = move_range.last->prev_nondebug_insn ();
+    if (auto *prev = move_range.last->prev_nondebug_insn ())
+      move_range.last = prev;
+    else
+      {
+       // Invalidate the range.  next_nondebug_insn is always nonnull
+       // if prev_nondebug_insn is null.
+       move_range.first = move_range.last->next_nondebug_insn ();
+       return false;
+      }
   return bool (move_range);
 }
 
diff --git a/gcc/testsuite/gcc.dg/torture/pr115929-2.c b/gcc/testsuite/gcc.dg/torture/pr115929-2.c
new file mode 100644 (file)
index 0000000..c8473a7
--- /dev/null
@@ -0,0 +1,22 @@
+/* { dg-additional-options "-fschedule-insns" } */
+
+int a, b, c, d, e, f;
+int main() {
+  if (e && f)
+    while (1)
+      while (a)
+        a = 0;
+  if (c) {
+    if (b)
+      goto g;
+    int h = a;
+  i:
+    b = ~((b ^ h) | 1 % b);
+    if (a)
+    g:
+      b = 0;
+  }
+  if (d)
+    goto i;
+  return 0;
+}