Skip to content

Commit de25f17

Browse files
committed
range-cache: Fix ranger ICE if number of bbs increases [PR116899]
Ranger cache during initialization reserves number of basic block slots in the m_workback vector (in an inefficient way by doing create (0) and safe_grow_cleared (n) and truncate (0) rather than say create (n) or reserve (n) after create). The problem is that some passes split bbs and/or create new basic blocks and so when one is unlucky, the quick_push into that vector can ICE. The following patch replaces those 4 quick_push calls with safe_push. I've also gathered some statistics from compiling 63 gcc sources (picked those that dependent on gimple-range-cache.h just because I had to rebuild them once for the instrumentation), and that showed that in 81% of cases nothing has been pushed into the vector at all (and note, not everything was small, there were even cases with 10000+ basic blocks), another 18.5% of cases had just 1-4 elements in the vector at most, 0.08% had 5-8 and 19 out of 305386 cases had at most 9-11 elements, nothing more. So, IMHO reserving number of basic block in the vector is a waste of compile time memory and with the safe_push calls, the patch just initializes the vector to vNULL. 2024-10-01 Jakub Jelinek <[email protected]> PR middle-end/116899 * gimple-range-cache.cc (ranger_cache::ranger_cache): Set m_workback to vNULL instead of creating it, growing and then truncating. (ranger_cache::fill_block_cache): Use safe_push rather than quick_push on m_workback. (ranger_cache::range_from_dom): Likewise. * gcc.dg/bitint-111.c: New test.
1 parent bdbd060 commit de25f17

File tree

2 files changed

+21
-7
lines changed

2 files changed

+21
-7
lines changed

gcc/gimple-range-cache.cc

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -997,9 +997,7 @@ update_list::pop ()
997997

998998
ranger_cache::ranger_cache (int not_executable_flag, bool use_imm_uses)
999999
{
1000-
m_workback.create (0);
1001-
m_workback.safe_grow_cleared (last_basic_block_for_fn (cfun));
1002-
m_workback.truncate (0);
1000+
m_workback = vNULL;
10031001
m_temporal = new temporal_cache;
10041002

10051003
// If DOM info is available, spawn an oracle as well.
@@ -1560,7 +1558,7 @@ ranger_cache::fill_block_cache (tree name, basic_block bb, basic_block def_bb)
15601558
// Visit each block back to the DEF. Initialize each one to UNDEFINED.
15611559
// m_visited at the end will contain all the blocks that we needed to set
15621560
// the range_on_entry cache for.
1563-
m_workback.quick_push (bb);
1561+
m_workback.safe_push (bb);
15641562
undefined.set_undefined ();
15651563
m_on_entry.set_bb_range (name, bb, undefined);
15661564
gcc_checking_assert (m_update->empty_p ());
@@ -1634,7 +1632,7 @@ ranger_cache::fill_block_cache (tree name, basic_block bb, basic_block def_bb)
16341632
// the list.
16351633
gcc_checking_assert (!m_on_entry.bb_range_p (name, pred));
16361634
m_on_entry.set_bb_range (name, pred, undefined);
1637-
m_workback.quick_push (pred);
1635+
m_workback.safe_push (pred);
16381636
}
16391637
}
16401638

@@ -1729,7 +1727,7 @@ ranger_cache::range_from_dom (vrange &r, tree name, basic_block start_bb,
17291727

17301728
// This block has an outgoing range.
17311729
if (gori ().has_edge_range_p (name, bb))
1732-
m_workback.quick_push (prev_bb);
1730+
m_workback.safe_push (prev_bb);
17331731
else
17341732
{
17351733
// Normally join blocks don't carry any new range information on
@@ -1753,7 +1751,7 @@ ranger_cache::range_from_dom (vrange &r, tree name, basic_block start_bb,
17531751
break;
17541752
}
17551753
if (all_dom)
1756-
m_workback.quick_push (prev_bb);
1754+
m_workback.safe_push (prev_bb);
17571755
}
17581756
}
17591757

gcc/testsuite/gcc.dg/bitint-111.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/* PR middle-end/116899 */
2+
/* { dg-do compile { target bitint575 } } */
3+
/* { dg-options "-O2" } */
4+
5+
float f;
6+
_BitInt(255) b;
7+
8+
void
9+
foo (signed char c)
10+
{
11+
for (;;)
12+
{
13+
c %= (unsigned _BitInt(512)) 0; /* { dg-warning "division by zero" } */
14+
f /= b >= c;
15+
}
16+
}

0 commit comments

Comments
 (0)