> Am 04.08.2026 um 10:06 schrieb Jakub Jelinek <[email protected]>:
>
> Hi!
>
> 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.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
Ok
Thanks,
Richard
> 2026-08-04 Jakub Jelinek <[email protected]>
>
> 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.
>
> --- gcc/tree-ssa-math-opts.cc.jj 2026-07-10 08:56:56.539168444 +0200
> +++ gcc/tree-ssa-math-opts.cc 2026-08-03 19:12:11.521252398 +0200
> @@ -3761,7 +3761,7 @@ maybe_optimize_guarding_check (vec<gimpl
> 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;
> --- gcc/testsuite/gcc.dg/tree-ssa/pr126601.c.jj 2026-08-03
> 19:19:15.410107311 +0200
> +++ gcc/testsuite/gcc.dg/tree-ssa/pr126601.c 2026-08-03 19:11:56.848430491
> +0200
> @@ -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;
> +}
>
> Jakub
>