https://gcc.gnu.org/g:efcc06ac1adc833d0b104df038d128031ca85e89
commit r17-5635-gefcc06ac1adc833d0b104df038d128031ca85e89 Author: Richard Earnshaw <[email protected]> Date: Tue Oct 20 18:42:08 2026 +0100 arm: tweak limits on minipool placement [PR127988] My previous patch changed a number of the calculations on pool placement, but this wasn't fully accounted for when inserting a forced barrier. The result was that it was possible to find a barrier in the code that had previously been discarded as being too far away. There was also a small memory leak in the pool dumping code in that we weren't destructing the subpools. gcc/ChangeLog: PR target/127988 * config/arm/minipool.cc (minipool::add_forward_ref): Allow for pool alignment when checking if the current fix will fit. (minipool::create_fix_barrier): Ensure we always have a suitable insertion point and fix off-by-one issue when testing if a insn is in range. (place_minipools): Correctly account for padding and the pool skip instruction before inserting a forced barrier. (minipool::dump): Call the destructor on subpools before freeing them. Diff: --- gcc/config/arm/minipool.cc | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/gcc/config/arm/minipool.cc b/gcc/config/arm/minipool.cc index 8780120afd10..36714a6b1e77 100644 --- a/gcc/config/arm/minipool.cc +++ b/gcc/config/arm/minipool.cc @@ -938,7 +938,12 @@ minipool::add_forward_ref (Mfix *fix, minipool_address loc) alignment. */ align = std::min (align, ARM_DOUBLEWORD_ALIGN ? 8u: 4u); - if (loc > m_max_address) + /* Check that inserting this value will still leave the pool reachable + for all existing entries. We need to consider the case where + the new insertion will increase the alignment of the overall pool. */ + if (loc + std::max (get_alignment_size (), + (HOST_WIDE_INT) align - m_insn_align) + > m_max_address) return NULL; std::list<subpool *>::iterator spi = find_subpool (align, fix, loc, get_alignment_size ()); @@ -1043,6 +1048,7 @@ minipool::dump (rtx_insn *scan) for (spi = m_subpools.begin (); spi != m_subpools.end (); ++spi) { scan = (*spi)->dump (scan); + (*spi)->~subpool (); free (*spi); } @@ -1062,7 +1068,7 @@ minipool::create_fix_barrier (Mfix *fix, minipool_address max_address) rtx_barrier *barrier; rtx_insn *from = fix->insn; /* The instruction after which we will insert the jump. */ - rtx_insn *selected = NULL; + rtx_insn *selected = from; int selected_cost; /* The address at which the jump instruction will be placed. */ HOST_WIDE_INT selected_address; @@ -1071,7 +1077,7 @@ minipool::create_fix_barrier (Mfix *fix, minipool_address max_address) rtx_code_label *label = gen_label_rtx (); selected_cost = barrier_cost (from); - selected_address = fix->address; + selected_address = fix->address + fix->insn_size; while (from && count < max_count) { @@ -1099,8 +1105,7 @@ minipool::create_fix_barrier (Mfix *fix, minipool_address max_address) still put the pool after the table. */ new_cost = barrier_cost (from); - if (count < max_count - && (!selected || new_cost <= selected_cost)) + if (count <= max_count && new_cost <= selected_cost) { selected = tmp; selected_cost = new_cost; @@ -1114,8 +1119,7 @@ minipool::create_fix_barrier (Mfix *fix, minipool_address max_address) new_cost = barrier_cost (from); - if (count < max_count - && (!selected || new_cost <= selected_cost)) + if (count <= max_count && new_cost <= selected_cost) { selected = from; selected_cost = new_cost; @@ -1125,9 +1129,6 @@ minipool::create_fix_barrier (Mfix *fix, minipool_address max_address) from = next_nonnote_nondebug_insn (from); } - /* Make sure that we found a place to insert the jump. */ - gcc_assert (selected); - /* Create a new JUMP_INSN that branches around a barrier. */ from = emit_jump_insn_after (gen_jump (label), selected); JUMP_LABEL (from) = label; @@ -1435,15 +1436,14 @@ place_minipools (void) last_barrier being set. */ gcc_assert (ftmp); - max_address = mpool.forwards (); - /* Check that there isn't another fix that is in range that - we couldn't fit into this pool because the pool was - already too large: we need to put the pool before such an - instruction. The pool itself may come just after the - fix because create_fix_barrier also allows space for a - jump instruction. */ + max_address = (mpool.forwards () + - (mpool.get_alignment_size () + pool_skip)); + gcc_assert (max_address + >= last_added_fix->address + last_added_fix->insn_size); + + /* Ensure the pool comes before ftmp. */ if (ftmp->address < max_address) - max_address = ftmp->address + 1; + max_address = ftmp->address; last_barrier = mpool.create_fix_barrier (last_added_fix, max_address);
