As the PR shows, there was nothing to prevent the ldp/stp pass from
trying to move throwing insns, which lead to an RTL verification
failure.
This patch fixes that.
gcc/ChangeLog:
PR target/113093
* config/aarch64/aarch64-ldp-fusion.cc (latest_hazard_before):
If the insn is throwing, record the previous insn as a hazard to
prevent moving it from the end of the BB.
gcc/testsuite/ChangeLog:
PR target/113093
* gcc.dg/pr113093.c: New test.
{
insn_info *result = nullptr;
+ // If the insn can throw then it is at the end of a BB and we can't
+ // move it, model this by recording a hazard in the previous insn
+ // which will prevent moving the insn up.
+ if (cfun->can_throw_non_call_exceptions
+ && find_reg_note (insn->rtl (), REG_EH_REGION, NULL_RTX))
+ return insn->prev_nondebug_insn ();
+
// Return true if we registered the hazard.
auto hazard = [&](insn_info *h) -> bool
{
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-Os -fharden-control-flow-redundancy -fnon-call-exceptions" } */
+_Complex long *c;
+void init() { *c = 1.0; }