aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/combine.c20
2 files changed, 26 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e8aa3a1..dcd1fb6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2017-12-08 Segher Boessenkool <segher@kernel.crashing.org>
+
+ PR rtl-optimization/83304
+ * combine.c (move_deaths): If we do not know where a register died,
+ search for it.
+
2017-12-08 Richard Biener <rguenther@suse.de>
* gimple-loop-interchange.cc (tree_loop_interchange::interchange):
diff --git a/gcc/combine.c b/gcc/combine.c
index 34c89a1..786a840 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -13876,6 +13876,26 @@ move_deaths (rtx x, rtx maybe_kill_insn, int from_luid, rtx_insn *to_insn,
unsigned int regno = REGNO (x);
rtx_insn *where_dead = reg_stat[regno].last_death;
+ /* If we do not know where the register died, it may still die between
+ FROM_LUID and TO_INSN. If so, find it. This is PR83304. */
+ if (!where_dead)
+ {
+ rtx_insn *insn = prev_real_insn (to_insn);
+ while (insn
+ && BLOCK_FOR_INSN (insn) == BLOCK_FOR_INSN (to_insn)
+ && DF_INSN_LUID (insn) >= from_luid)
+ {
+ if (dead_or_set_regno_p (insn, regno))
+ {
+ if (find_regno_note (insn, REG_DEAD, regno))
+ where_dead = insn;
+ break;
+ }
+
+ insn = prev_real_insn (insn);
+ }
+ }
+
/* Don't move the register if it gets killed in between from and to. */
if (maybe_kill_insn && reg_set_p (x, maybe_kill_insn)
&& ! reg_referenced_p (x, maybe_kill_insn))