The following patch fixes
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81572
The patch was successfully bootstrapped and tested on ppc64.
Committed as rev. 257915.
Index: ChangeLog
===
--- ChangeLog (revision 257901)
+++ ChangeLog (working copy)
@@ -1,3 +1,19 @@
+2018-02-22 Vladimir Makarov
+
+ PR target/81572
+ * lra-int.h (LRA_UNKNOWN_ALT, LRA_NON_CLOBBERED_ALT): New macros.
+ * lra.c (lra_set_insn_recog_data, lra_update_insn_recog_data): Use
+ LRA_UNKNOWN_ALT.
+ * lra-constraints.c (curr_insn_transform): Set up
+ LRA_NON_CLOBBERED_ALT for moves processed on the fast path. Use
+ LRA_UNKNOWN_ALT.
+ (remove_inheritance_pseudos): Use LRA_UNKNOWN_ALT.
+ * lra-eliminations.c (spill_pseudos): Ditto.
+ (process_insn_for_elimination): Ditto.
+ * lra-lives.c (reg_early_clobber_p): Use the new macros.
+ * lra-spills.c (spill_pseudos): Use LRA_UNKNOWN_ALT and
+ LRA_NON_CLOBBERED_ALT.
+
2018-02-22 Martin Liska
PR driver/83193
Index: lra-constraints.c
===
--- lra-constraints.c (revision 257901)
+++ lra-constraints.c (working copy)
@@ -3730,7 +3730,13 @@ curr_insn_transform (bool check_only_p)
curr_insn_set = single_set (curr_insn);
if (curr_insn_set != NULL_RTX && simple_move_p ())
-return false;
+{
+ /* We assume that the corresponding insn alternative has no
+ earlier clobbers. If it is not the case, don't define move
+ cost equal to 2 for the corresponding register classes. */
+ lra_set_used_insn_alternative (curr_insn, LRA_NON_CLOBBERED_ALT);
+ return false;
+}
no_input_reloads_p = no_output_reloads_p = false;
goal_alt_number = -1;
@@ -3838,7 +3844,7 @@ curr_insn_transform (bool check_only_p)
if (change_p)
/* If we've changed the instruction then any alternative that
we chose previously may no longer be valid. */
-lra_set_used_insn_alternative (curr_insn, -1);
+lra_set_used_insn_alternative (curr_insn, LRA_UNKNOWN_ALT);
if (! check_only_p && curr_insn_set != NULL_RTX
&& check_and_process_move (&change_p, &sec_mem_p))
@@ -3846,7 +3852,7 @@ curr_insn_transform (bool check_only_p)
try_swapped:
- reused_alternative_num = check_only_p ? -1 : curr_id->used_insn_alternative;
+ reused_alternative_num = check_only_p ? LRA_UNKNOWN_ALT : curr_id->used_insn_alternative;
if (lra_dump_file != NULL && reused_alternative_num >= 0)
fprintf (lra_dump_file, "Reusing alternative %d for insn #%u\n",
reused_alternative_num, INSN_UID (curr_insn));
@@ -6752,7 +6758,7 @@ remove_inheritance_pseudos (bitmap remov
}
lra_push_insn_and_update_insn_regno_info (curr_insn);
lra_set_used_insn_alternative_by_uid
- (INSN_UID (curr_insn), -1);
+ (INSN_UID (curr_insn), LRA_UNKNOWN_ALT);
done_p = true;
if (lra_dump_file != NULL)
{
@@ -6791,7 +6797,7 @@ remove_inheritance_pseudos (bitmap remov
constraints pass. */
lra_push_insn_and_update_insn_regno_info (curr_insn);
lra_set_used_insn_alternative_by_uid
- (INSN_UID (curr_insn), -1);
+ (INSN_UID (curr_insn), LRA_UNKNOWN_ALT);
}
else if (restored_regs_p)
/* The instruction has been restored to the form that
Index: lra-eliminations.c
===
--- lra-eliminations.c (revision 257901)
+++ lra-eliminations.c (working copy)
@@ -1175,7 +1175,7 @@ spill_pseudos (HARD_REG_SET set)
if (bitmap_bit_p (&to_process, INSN_UID (insn)))
{
lra_push_insn (insn);
- lra_set_used_insn_alternative (insn, -1);
+ lra_set_used_insn_alternative (insn, LRA_UNKNOWN_ALT);
}
bitmap_clear (&to_process);
}
@@ -1408,7 +1408,7 @@ process_insn_for_elimination (rtx_insn *
}
lra_update_insn_regno_info (insn);
lra_push_insn (insn);
- lra_set_used_insn_alternative (insn, -1);
+ lra_set_used_insn_alternative (insn, LRA_UNKNOWN_ALT);
}
}
Index: lra-int.h
===
--- lra-int.h (revision 257901)
+++ lra-int.h (working copy)
@@ -202,15 +202,20 @@ struct lra_static_insn_data
const struct operand_alternative *operand_alternative;
};
+/* Negative insn alternative numbers used for special cases. */
+#define LRA_UNKNOWN_ALT -1
+#define LRA_NON_CLOBBERED_ALT -2
+
/* LRA internal info about an insn (LRA internal insn
representation). */
struct lra_insn_recog_data
{
/* The insn code. */
int icode;
- /* The alternative should be used for the insn, -1 if invalid, or we
- should try to use any alternative, or the insn is a debug
- insn. */
+ /* The alternative should be used for the insn, LRA_UNKNOWN_ALT if
+ unknown, or we should assume any alternative, or the insn is a
+ debug insn. LRA_NON_CLOBBERED_ALT means ignoring any earlier
+ clobbers for the insn. */
int used_insn_alternative;
/*