diff --git a/gcc/config/aarch64/aarch64-ldp-fusion.cc b/gcc/config/aarch64/aarch64-ldp-fusion.cc index 25f9b2d01c582b8f020ac4d3ec6b158faa8541db..2fe1b1d4d84e8a240b8373fadf1473f8a9f82f51 100644 --- a/gcc/config/aarch64/aarch64-ldp-fusion.cc +++ b/gcc/config/aarch64/aarch64-ldp-fusion.cc @@ -2195,6 +2195,15 @@ ldp_bb_info::try_fuse_pair (bool load_p, unsigned access_size, if (base->hazards[0]) range.last = base->hazards[0]->prev_nondebug_insn (); + // If the second insn can throw, narrow the move range to exactly that insn. + // This prevents us trying to move the second insn from the end of the BB. + if (cfun->can_throw_non_call_exceptions + && find_reg_note (insns[1]->rtl (), REG_EH_REGION, NULL_RTX)) + { + gcc_assert (range.includes (insns[1])); + range = insn_range_info (insns[1]); + } + // Placement strategy: push loads down and pull stores up, this should // help register pressure by reducing live ranges. if (load_p) diff --git a/gcc/testsuite/g++.dg/pr113217.C b/gcc/testsuite/g++.dg/pr113217.C new file mode 100644 index 0000000000000000000000000000000000000000..ec861543930d9b86e5bb673e22dbeb90db44b57c --- /dev/null +++ b/gcc/testsuite/g++.dg/pr113217.C @@ -0,0 +1,15 @@ +// { dg-do compile } +// { dg-options "-O -g -fnon-call-exceptions" } +struct _Vector_base { + int _M_end_of_storage; +}; +struct vector : _Vector_base { + vector() : _Vector_base() {} + ~vector(); +}; +struct LoadGraph { + LoadGraph(); + vector colors; + vector data_block; +}; +LoadGraph::LoadGraph() {}