The following patch fixes PR83252 and PR80818.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83252
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80818
The patch was successfully tested and bootstrapped on ppc64 and x86_64.
Committed as rev. 255471.
Jakub, the patch does not include a test case for PR83252. Could you
add your test to the trunk.
Index: ChangeLog
===================================================================
--- ChangeLog (revision 255470)
+++ ChangeLog (working copy)
@@ -1,3 +1,12 @@
+2017-12-07 Vladimir Makarov <vmaka...@redhat.com>
+
+ PR target/83252
+ PR rtl-optimization/80818
+ * lra.c (add_regs_to_insn_regno_info): Make a hard reg in CLOBBER
+ always early clobbered.
+ * lra-lives.c (process_bb_lives): Check input hard regs for early
+ clobbered non-operand hard reg.
+
2017-12-07 Jakub Jelinek <ja...@redhat.com>
PR middle-end/83164
Index: lra.c
===================================================================
--- lra.c (revision 255470)
+++ lra.c (working copy)
@@ -1476,15 +1476,11 @@ add_regs_to_insn_regno_info (lra_insn_re
add_regs_to_insn_regno_info (data, SET_SRC (x), insn, OP_IN, false, 0);
break;
case CLOBBER:
- {
- int code = INSN_CODE (insn);
-
- /* We treat clobber of non-operand hard registers as early
- clobber (the behavior is expected from asm). */
- add_regs_to_insn_regno_info (data, XEXP (x, 0), insn, OP_OUT,
- code < 0, code < 0 ? ALL_ALTERNATIVES : 0);
- break;
- }
+ /* We treat clobber of non-operand hard registers as early
+ clobber. */
+ add_regs_to_insn_regno_info (data, XEXP (x, 0), insn, OP_OUT,
+ true, ALL_ALTERNATIVES);
+ break;
case PRE_INC: case PRE_DEC: case POST_INC: case POST_DEC:
add_regs_to_insn_regno_info (data, XEXP (x, 0), insn, OP_INOUT, false, 0);
break;
Index: lra-lives.c
===================================================================
--- lra-lives.c (revision 255470)
+++ lra-lives.c (working copy)
@@ -928,7 +928,18 @@ process_bb_lives (basic_block bb, int &c
for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next)
if (reg->type == OP_OUT
&& reg_early_clobber_p (reg, n_alt) && ! reg->subreg_p)
- make_hard_regno_dead (reg->regno);
+ {
+ struct lra_insn_reg *reg2;
+
+ /* We can have early clobbered non-operand hard reg and
+ the same hard reg as an insn input. Don't make hard
+ reg dead before the insns. */
+ for (reg2 = curr_id->regs; reg2 != NULL; reg2 = reg2->next)
+ if (reg2->type != OP_OUT && reg2->regno == reg->regno)
+ break;
+ if (reg2 == NULL)
+ make_hard_regno_dead (reg->regno);
+ }
if (need_curr_point_incr)
next_program_point (curr_point, freq);