- ICE verify_vssa exceeds stack space for big functions [PR124805]
Checks
| Context |
Check |
Description |
| linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 |
success
|
Build passed
|
| linaro-tcwg-bot/tcwg_gcc_build--master-arm |
success
|
Build passed
|
| linaro-tcwg-bot/tcwg_gcc_check--master-arm |
success
|
Test passed
|
| linaro-tcwg-bot/tcwg_gcc_check--master-aarch64 |
fail
|
Test failed
|
Commit Message
The source from PR124561 led to an ICE with --enable-checking, caused by a stack overflow.
The recursive verification code verify_vssa in tree-ssa.cc could not handle the extreme
number of basic blocks within the typical limits of stack space.
As for PR124561 the recursive code was transformed into an iterative version, which
avoided the recursive calls.
A worklist is used, which has as entries a pair of a basic_block and a tree (vdef).
The logic of verification steps for each basic_block is unchanged, although the order
of basic_blocks is changed.
This fixes PR124805.
Reg tested OK.
2026-04-07 Heiko Eißfeldt <heiko@hexco.de>
PR middle-end/124805
* tree-ssa.cc (verify_vssa):
replace recursive calls with iteration for lower stack usage
Comments
On Wed, Apr 8, 2026 at 11:32 PM Heiko Eißfeldt <heiko.Eissfeldt@hexco.de> wrote:
>
> The source from PR124561 led to an ICE with --enable-checking, caused by a stack overflow.
> The recursive verification code verify_vssa in tree-ssa.cc could not handle the extreme
> number of basic blocks within the typical limits of stack space.
>
> As for PR124561 the recursive code was transformed into an iterative version, which
> avoided the recursive calls.
>
> A worklist is used, which has as entries a pair of a basic_block and a tree (vdef).
> The logic of verification steps for each basic_block is unchanged, although the order
> of basic_blocks is changed.
>
> This fixes PR124805.
>
> Reg tested OK.
This is OK for stage1.
Thanks,
Richard.
> 2026-04-07 Heiko Eißfeldt <heiko@hexco.de>
>
> PR middle-end/124805
> * tree-ssa.cc (verify_vssa):
> replace recursive calls with iteration for lower stack usage
Thanks for your review!
I just got a notification regarding three new regressions with my patch
(https://patchwork.sourceware.org/patch/132826)
on aarch64-linux-gnu in
libstdc++:libstdc++-prettyprinters/prettyprinters.exp
Produces 3 regressions:
|
| regressions.sum:
| Running libstdc++:libstdc++-prettyprinters/prettyprinters.exp ...
| FAIL: libstdc++-prettyprinters/debug.cc print redirected
| FAIL: libstdc++-prettyprinters/simple.cc print redirected
| FAIL: libstdc++-prettyprinters/simple11.cc print redirected
Note: the arm 32 bit build was without any regressions.
Now I need to understand what causes these regressions...
Any hints to accelerate my understanding would be very much appreciated.
At first I would like to understand how verify_vssa() can be invoked without
--enable-checking (which seems the configuration being used by Linaro CI).
Then I fail to see any connection to libc++ prettyprinters tests
(which also involve python and gdb).
Finally there should follow a V2 patch.
Thanks,
Heiko
On 4/9/26 2:08 PM, Richard Biener wrote:
> On Wed, Apr 8, 2026 at 11:32 PM Heiko Eißfeldt<heiko.Eissfeldt@hexco.de> wrote:
>> The source from PR124561 led to an ICE with --enable-checking, caused by a stack overflow.
>> The recursive verification code verify_vssa in tree-ssa.cc could not handle the extreme
>> number of basic blocks within the typical limits of stack space.
>>
>> As for PR124561 the recursive code was transformed into an iterative version, which
>> avoided the recursive calls.
>>
>> A worklist is used, which has as entries a pair of a basic_block and a tree (vdef).
>> The logic of verification steps for each basic_block is unchanged, although the order
>> of basic_blocks is changed.
>>
>> This fixes PR124805.
>>
>> Reg tested OK.
> This is OK for stage1.
>
> Thanks,
> Richard.
>
>> 2026-04-07 Heiko Eißfeldt<heiko@hexco.de>
>>
>> PR middle-end/124805
>> * tree-ssa.cc (verify_vssa):
>> replace recursive calls with iteration for lower stack usage
On Mon, Apr 13, 2026 at 5:29 PM Heiko Eißfeldt <heiko.Eissfeldt@hexco.de> wrote:
>
> Thanks for your review!
>
> I just got a notification regarding three new regressions with my patch
> (https://patchwork.sourceware.org/patch/132826)
> on aarch64-linux-gnu in
>
> libstdc++:libstdc++-prettyprinters/prettyprinters.exp
>
> Produces 3 regressions:
> |
> | regressions.sum:
> | Running libstdc++:libstdc++-prettyprinters/prettyprinters.exp ...
> | FAIL: libstdc++-prettyprinters/debug.cc print redirected
> | FAIL: libstdc++-prettyprinters/simple.cc print redirected
> | FAIL: libstdc++-prettyprinters/simple11.cc print redirected
>
> Note: the arm 32 bit build was without any regressions.
I'm pretty sure those are not caused by your patch - you'd have to
reach out to linaro folks to assess what goes wrong here.
> Now I need to understand what causes these regressions...
>
> Any hints to accelerate my understanding would be very much appreciated.
>
> At first I would like to understand how verify_vssa() can be invoked without
> --enable-checking (which seems the configuration being used by Linaro CI).
>
> Then I fail to see any connection to libc++ prettyprinters tests
> (which also involve python and gdb).
>
> Finally there should follow a V2 patch.
>
> Thanks,
> Heiko
>
> On 4/9/26 2:08 PM, Richard Biener wrote:
>
> On Wed, Apr 8, 2026 at 11:32 PM Heiko Eißfeldt <heiko.Eissfeldt@hexco.de> wrote:
>
> The source from PR124561 led to an ICE with --enable-checking, caused by a stack overflow.
> The recursive verification code verify_vssa in tree-ssa.cc could not handle the extreme
> number of basic blocks within the typical limits of stack space.
>
> As for PR124561 the recursive code was transformed into an iterative version, which
> avoided the recursive calls.
>
> A worklist is used, which has as entries a pair of a basic_block and a tree (vdef).
> The logic of verification steps for each basic_block is unchanged, although the order
> of basic_blocks is changed.
>
> This fixes PR124805.
>
> Reg tested OK.
>
> This is OK for stage1.
>
> Thanks,
> Richard.
>
> 2026-04-07 Heiko Eißfeldt <heiko@hexco.de>
>
> PR middle-end/124805
> * tree-ssa.cc (verify_vssa):
> replace recursive calls with iteration for lower stack usage
On Thu, Apr 9, 2026 at 5:10 AM Richard Biener
<richard.guenther@gmail.com> wrote:
>
> On Wed, Apr 8, 2026 at 11:32 PM Heiko Eißfeldt <heiko.Eissfeldt@hexco.de> wrote:
> >
> > The source from PR124561 led to an ICE with --enable-checking, caused by a stack overflow.
> > The recursive verification code verify_vssa in tree-ssa.cc could not handle the extreme
> > number of basic blocks within the typical limits of stack space.
> >
> > As for PR124561 the recursive code was transformed into an iterative version, which
> > avoided the recursive calls.
> >
> > A worklist is used, which has as entries a pair of a basic_block and a tree (vdef).
> > The logic of verification steps for each basic_block is unchanged, although the order
> > of basic_blocks is changed.
> >
> > This fixes PR124805.
> >
> > Reg tested OK.
>
> This is OK for stage1.
I have now pushed this.
>
> Thanks,
> Richard.
>
> > 2026-04-07 Heiko Eißfeldt <heiko@hexco.de>
> >
> > PR middle-end/124805
> > * tree-ssa.cc (verify_vssa):
> > replace recursive calls with iteration for lower stack usage
@@ -636,96 +636,119 @@ release_defs_bitset (bitmap toremove)
/* Verify virtual SSA form. */
bool
-verify_vssa (basic_block bb, tree current_vdef, sbitmap visited)
+verify_vssa (basic_block bb_start, tree current_vdef, sbitmap visited)
{
bool err = false;
- if (!bitmap_set_bit (visited, bb->index))
- return false;
+ struct state_t {
+ basic_block bb;
+ tree vdef;
+ } state;
+
+ auto_vec<state_t, 3> worklist;
+ state.bb = bb_start;
+ state.vdef = current_vdef;
+ worklist.safe_push (state);
- /* Pick up the single virtual PHI def. */
- gphi *phi = NULL;
- for (gphi_iterator si = gsi_start_phis (bb); !gsi_end_p (si);
- gsi_next (&si))
+ while (!worklist.is_empty ())
{
- tree res = gimple_phi_result (si.phi ());
- if (virtual_operand_p (res))
+ const auto &state = worklist.pop ();
+ const auto &bb = state.bb;
+ current_vdef = state.vdef;
+
+ if (!bitmap_set_bit (visited, bb->index))
+ continue;
+
+ /* Pick up the single virtual PHI def. */
+ gphi *phi = NULL;
+ for (gphi_iterator si = gsi_start_phis (bb); !gsi_end_p (si);
+ gsi_next (&si))
+ {
+ tree res = gimple_phi_result (si.phi ());
+ if (virtual_operand_p (res))
+ {
+ if (phi)
+ {
+ error ("multiple virtual PHI nodes in BB %d", bb->index);
+ print_gimple_stmt (stderr, phi, 0);
+ print_gimple_stmt (stderr, si.phi (), 0);
+ err = true;
+ }
+ else
+ phi = si.phi ();
+ }
+ }
+ if (phi)
{
- if (phi)
+ current_vdef = gimple_phi_result (phi);
+ if (TREE_CODE (current_vdef) != SSA_NAME)
{
- error ("multiple virtual PHI nodes in BB %d", bb->index);
+ error ("virtual definition is not an SSA name");
print_gimple_stmt (stderr, phi, 0);
- print_gimple_stmt (stderr, si.phi (), 0);
err = true;
}
- else
- phi = si.phi ();
}
- }
- if (phi)
- {
- current_vdef = gimple_phi_result (phi);
- if (TREE_CODE (current_vdef) != SSA_NAME)
+
+ /* Verify stmts. */
+ for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
+ gsi_next (&gsi))
{
- error ("virtual definition is not an SSA name");
- print_gimple_stmt (stderr, phi, 0);
- err = true;
+ gimple *stmt = gsi_stmt (gsi);
+ tree vuse = gimple_vuse (stmt);
+ if (vuse)
+ {
+ if (vuse != current_vdef)
+ {
+ error ("stmt with wrong VUSE");
+ print_gimple_stmt (stderr, stmt, 0, TDF_VOPS);
+ fprintf (stderr, "expected ");
+ print_generic_expr (stderr, current_vdef);
+ fprintf (stderr, "\n");
+ err = true;
+ }
+ tree vdef = gimple_vdef (stmt);
+ if (vdef)
+ {
+ current_vdef = vdef;
+ if (TREE_CODE (current_vdef) != SSA_NAME)
+ {
+ error ("virtual definition is not an SSA name");
+ print_gimple_stmt (stderr, phi, 0);
+ err = true;
+ }
+ }
+ }
}
- }
- /* Verify stmts. */
- for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
- gsi_next (&gsi))
- {
- gimple *stmt = gsi_stmt (gsi);
- tree vuse = gimple_vuse (stmt);
- if (vuse)
+ /* Verify destination PHI uses and add successors to worklist. */
+ edge_iterator ei;
+ edge e;
+ FOR_EACH_EDGE (e, ei, bb->succs)
{
- if (vuse != current_vdef)
+ gphi *phi = get_virtual_phi (e->dest);
+ if (phi
+ && PHI_ARG_DEF_FROM_EDGE (phi, e) != current_vdef)
{
- error ("stmt with wrong VUSE");
- print_gimple_stmt (stderr, stmt, 0, TDF_VOPS);
+ error ("PHI node with wrong VUSE on edge from BB %d",
+ e->src->index);
+ print_gimple_stmt (stderr, phi, 0, TDF_VOPS);
fprintf (stderr, "expected ");
print_generic_expr (stderr, current_vdef);
fprintf (stderr, "\n");
err = true;
}
- tree vdef = gimple_vdef (stmt);
- if (vdef)
+
+ /* Add successor BB along with current vdef to worklist. */
+ if (!bitmap_bit_p (visited, e->dest->index))
{
- current_vdef = vdef;
- if (TREE_CODE (current_vdef) != SSA_NAME)
- {
- error ("virtual definition is not an SSA name");
- print_gimple_stmt (stderr, phi, 0);
- err = true;
- }
- }
- }
- }
+ state_t new_state;
+ new_state.bb = e->dest;
+ new_state.vdef = current_vdef;
- /* Verify destination PHI uses and recurse. */
- edge_iterator ei;
- edge e;
- FOR_EACH_EDGE (e, ei, bb->succs)
- {
- gphi *phi = get_virtual_phi (e->dest);
- if (phi
- && PHI_ARG_DEF_FROM_EDGE (phi, e) != current_vdef)
- {
- error ("PHI node with wrong VUSE on edge from BB %d",
- e->src->index);
- print_gimple_stmt (stderr, phi, 0, TDF_VOPS);
- fprintf (stderr, "expected ");
- print_generic_expr (stderr, current_vdef);
- fprintf (stderr, "\n");
- err = true;
+ worklist.safe_push (new_state);
+ }
}
-
- /* Recurse. */
- err |= verify_vssa (e->dest, current_vdef, visited);
}
-
return err;
}