aboutsummaryrefslogtreecommitdiff
path: root/gcc/lra-constraints.c
diff options
context:
space:
mode:
authorVladimir N. Makarov <vmakarov@redhat.com>2021-10-26 14:03:42 -0400
committerVladimir N. Makarov <vmakarov@redhat.com>2021-10-26 15:17:29 -0400
commit8c59f4118357789cfa8df2cf0d3ecb61be7e9041 (patch)
treec88f788cc7906fb84cbb1da9308d5e12cae80857 /gcc/lra-constraints.c
parentcfcb27cfcb1d32b8cf7bc463cc1fc5cacae8d199 (diff)
downloadgcc-8c59f4118357789cfa8df2cf0d3ecb61be7e9041.zip
gcc-8c59f4118357789cfa8df2cf0d3ecb61be7e9041.tar.gz
gcc-8c59f4118357789cfa8df2cf0d3ecb61be7e9041.tar.bz2
[PR102842] Consider all outputs in generation of matching reloads
Without considering all output insn operands (not only processed before), in rare cases LRA can use the same hard register for different outputs of the insn on different assignment subpasses. The patch fixes the problem. gcc/ChangeLog: PR rtl-optimization/102842 * lra-constraints.c (match_reload): Ignore out in checking values of outs. (curr_insn_transform): Collect outputs before doing reloads of operands. gcc/testsuite/ChangeLog: PR rtl-optimization/102842 * g++.target/arm/pr102842.C: New test.
Diffstat (limited to 'gcc/lra-constraints.c')
-rw-r--r--gcc/lra-constraints.c17
1 files changed, 5 insertions, 12 deletions
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c
index 8f75125..0195b4f 100644
--- a/gcc/lra-constraints.c
+++ b/gcc/lra-constraints.c
@@ -1102,7 +1102,7 @@ match_reload (signed char out, signed char *ins, signed char *outs,
for (i = 0; outs[i] >= 0; i++)
{
rtx other_out_rtx = *curr_id->operand_loc[outs[i]];
- if (REG_P (other_out_rtx)
+ if (outs[i] != out && REG_P (other_out_rtx)
&& (regno_val_use_in (REGNO (in_rtx), other_out_rtx)
!= NULL_RTX))
{
@@ -4382,7 +4382,10 @@ curr_insn_transform (bool check_only_p)
}
n_outputs = 0;
- outputs[0] = -1;
+ for (i = 0; i < n_operands; i++)
+ if (curr_static_id->operand[i].type == OP_OUT)
+ outputs[n_outputs++] = i;
+ outputs[n_outputs] = -1;
for (i = 0; i < n_operands; i++)
{
int regno;
@@ -4457,8 +4460,6 @@ curr_insn_transform (bool check_only_p)
lra-lives.c. */
match_reload (i, goal_alt_matched[i], outputs, goal_alt[i], &before,
&after, TRUE);
- outputs[n_outputs++] = i;
- outputs[n_outputs] = -1;
}
continue;
}
@@ -4636,14 +4637,6 @@ curr_insn_transform (bool check_only_p)
process_alt_operands decides that it is possible. */
gcc_unreachable ();
- /* Memorise processed outputs so that output remaining to be processed
- can avoid using the same register value (see match_reload). */
- if (curr_static_id->operand[i].type == OP_OUT)
- {
- outputs[n_outputs++] = i;
- outputs[n_outputs] = -1;
- }
-
if (optional_p)
{
rtx reg = op;