]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
widening_mul: Fix up ICE in maybe_optimize_guarding_check [PR126601]
authorJakub Jelinek <jakub@redhat.com>
Tue, 4 Aug 2026 08:37:09 +0000 (10:37 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 4 Aug 2026 08:37:09 +0000 (10:37 +0200)
The following testcase ICEs, because we try to quick_push into an already
full vector.
The caller (match_arith_overflow) has
  auto_vec<gimple *, 8> mul_stmts;
and 0-6 mul_stmts.quick_push (...); calls (none of that in a loop), and then
call to that maybe_optimize_guarding_check function which does one
quick_push, but the function is called in a
  FOR_EACH_IMM_USE_STMT (use_stmt, iter, cast_lhs ? cast_lhs : lhs)
loop, so if we are unlucky  as on the attached testcase, it is called more
than twice and either triggers ICE, or worse with checking disabled buffer
overflow.

The following patch fixes that by using safe_push in that spot instead.

2026-08-04  Jakub Jelinek  <jakub@redhat.com>

PR tree-optimization/126601
* tree-ssa-math-opts.cc (maybe_optimize_guarding_check): Use safe_push
on mul_stmts rather than quick_push.

* gcc.dg/tree-ssa/pr126601.c: New test.

Reviewed-by: Richard Biener <rguenth@suse.de>
gcc/testsuite/gcc.dg/tree-ssa/pr126601.c [new file with mode: 0644]
gcc/tree-ssa-math-opts.cc

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr126601.c b/gcc/testsuite/gcc.dg/tree-ssa/pr126601.c
new file mode 100644 (file)
index 0000000..971ccba
--- /dev/null
@@ -0,0 +1,29 @@
+/* PR tree-optimization/126601 */
+/* { dg-do compile } */
+/* { dg-options "-Os" } */
+
+volatile int c[16];
+
+[[gnu::noipa]] int
+foo (unsigned x, unsigned y)
+{
+  unsigned r = x * y;
+  int t = 0;
+  if (c[0]) { int u = 0; if (x != 0) u = (r / x != y); t += u; }
+  if (c[1]) { int u = 0; if (x != 0) u = (r / x != y); t += u; }
+  if (c[2]) { int u = 0; if (x != 0) u = (r / x != y); t += u; }
+  if (c[3]) { int u = 0; if (x != 0) u = (r / x != y); t += u; }
+  if (c[4]) { int u = 0; if (x != 0) u = (r / x != y); t += u; }
+  if (c[5]) { int u = 0; if (x != 0) u = (r / x != y); t += u; }
+  if (c[6]) { int u = 0; if (x != 0) u = (r / x != y); t += u; }
+  if (c[7]) { int u = 0; if (x != 0) u = (r / x != y); t += u; }
+  if (c[8]) { int u = 0; if (x != 0) u = (r / x != y); t += u; }
+  if (c[9]) { int u = 0; if (x != 0) u = (r / x != y); t += u; }
+  if (c[10]) { int u = 0; if (x != 0) u = (r / x != y); t += u; }
+  if (c[11]) { int u = 0; if (x != 0) u = (r / x != y); t += u; }
+  if (c[12]) { int u = 0; if (x != 0) u = (r / x != y); t += u; }
+  if (c[13]) { int u = 0; if (x != 0) u = (r / x != y); t += u; }
+  if (c[14]) { int u = 0; if (x != 0) u = (r / x != y); t += u; }
+  if (c[15]) { int u = 0; if (x != 0) u = (r / x != y); t += u; }
+  return t;
+}
index c4a1d7bcf0bdacd207d74828816ffa6d11984c85..0df1909ebc436ec8bd3d42522959c37d867c067c 100644 (file)
@@ -3761,7 +3761,7 @@ maybe_optimize_guarding_check (vec<gimple *> &mul_stmts, gimple *cond_stmt,
        return;
     }
   gimple_stmt_iterator gsi = gsi_after_labels (bb);
-  mul_stmts.quick_push (div_stmt);
+  mul_stmts.safe_push (div_stmt);
   if (is_gimple_debug (gsi_stmt (gsi)))
     gsi_next_nondebug (&gsi);
   unsigned cast_count = 0;