https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106078
Richard Biener <rguenth at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Summary|Invalid loop invariant |RTL PRE with
|motion with |non-call-exceptions
|non-call-exceptions |
Assignee|rguenth at gcc dot gnu.org |unassigned at gcc dot
gnu.org
Component|middle-end |rtl-optimization
Status|ASSIGNED |NEW
--- Comment #6 from Richard Biener <rguenth at gcc dot gnu.org> ---
Note it is RTL PRE hoisting the load from b, not invariant motion. On the
testcase w/o -fnon-call-exceptions it's tree PRE (or if disabled, RTL PRE
again)
doing the hoisting.
For some reason for the non-call-exception PRE case the following does not
help.
diff --git a/gcc/gcse-common.cc b/gcc/gcse-common.cc
index e86d4c4f477..16f804d13f9 100644
--- a/gcc/gcse-common.cc
+++ b/gcc/gcse-common.cc
@@ -82,7 +82,8 @@ record_last_mem_set_info_common (rtx_insn *insn,
modify_mem_list[bb].safe_push (insn);
bitmap_set_bit (modify_mem_list_set, bb);
- if (CALL_P (insn))
+ if (CALL_P (insn)
+ || can_throw_external (insn))
bitmap_set_bit (blocks_with_calls, bb);
else
{
diff --git a/gcc/gcse.cc b/gcc/gcse.cc
index f06278a5534..b138e1e501c 100644
--- a/gcc/gcse.cc
+++ b/gcc/gcse.cc
@@ -1535,13 +1535,14 @@ compute_hash_table_work (struct gcse_hash_table_d
*table)
= insn_callee_abi (insn).full_and_partial_reg_clobbers ();
EXECUTE_IF_SET_IN_HARD_REG_SET (callee_clobbers, 0, regno, hrsi)
record_last_reg_set_info (insn, regno);
-
- if (! RTL_CONST_OR_PURE_CALL_P (insn)
- || RTL_LOOPING_CONST_OR_PURE_CALL_P (insn)
- || can_throw_external (insn))
- record_last_mem_set_info (insn);
}
+ if ((CALL_P (insn)
+ && (! RTL_CONST_OR_PURE_CALL_P (insn)
+ || RTL_LOOPING_CONST_OR_PURE_CALL_P (insn)))
+ || can_throw_external (insn))
+ record_last_mem_set_info (insn);
+
note_stores (insn, record_last_set_info, insn);
}