This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] combine: Fix PR83304
- From: Segher Boessenkool <segher at kernel dot crashing dot org>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Segher Boessenkool <segher at kernel dot crashing dot org>
- Date: Fri, 8 Dec 2017 11:04:02 +0000
- Subject: [PATCH] combine: Fix PR83304
- Authentication-results: sourceware.org; auth=none
In PR83304 two insns are combined, where the I2 uses a register that
has a REG_DEAD note on an insn after I2 but before I3. In such a case
move_deaths should move that death note. But move_deaths only looks
at the reg_stat[regno].last_death insn, and that field can be zeroed
out (previously, use_crosses_set_p would prevent the combination in
this case).
If the last_death field is zero it means "unknown", not "no death", so
we have to find if there is a REG_DEAD note.
This patch does that, fixing the Arm PR83304 testcase. Also bootstrapped
and tested on powerpc64-linux {-m32,-m64}.
Committing to trunk.
Segher
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.
---
gcc/combine.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/gcc/combine.c b/gcc/combine.c
index 748c9a8..b12484a 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -13910,6 +13910,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))
--
1.8.3.1