aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladimir N. Makarov <vmakarov@redhat.com>2024-11-29 14:58:47 -0500
committerVladimir N. Makarov <vmakarov@redhat.com>2024-11-29 14:59:12 -0500
commite79583cef924f5fb5de551bd61da7b5fdee5c690 (patch)
tree27c43c2fc3fe81aab12609a161806bcc217440aa
parent75ade6106bbe010d06e5dddf719c22d4dadd9411 (diff)
downloadgcc-e79583cef924f5fb5de551bd61da7b5fdee5c690.zip
gcc-e79583cef924f5fb5de551bd61da7b5fdee5c690.tar.gz
gcc-e79583cef924f5fb5de551bd61da7b5fdee5c690.tar.bz2
[PR117770][LRA]: Check hard regs corresponding insn operands for hard reg clobbers
When LRA processes early clobbered hard regs explicitly present in the insn description, it checks that the hard reg is also used as input. If the hard reg is not an input also, it is marked as dying. For the check LRA processed only input hard reg also explicitly present in the insn description. For given PR, the hard reg is used as input as the operand and is not present explicitly in the insn description and therefore LRA marked the hard reg as dying. This results in wrong allocation and wrong code. The patch solves the problem by processing hard regs used as the insn operand. gcc/ChangeLog: PR rtl-optimization/117770 * lra-lives.cc: Include ira-int.h. (process_bb_lives): Check hard regs corresponding insn operands for dying hard wired reg clobbers.
-rw-r--r--gcc/lra-lives.cc14
1 files changed, 14 insertions, 0 deletions
diff --git a/gcc/lra-lives.cc b/gcc/lra-lives.cc
index 66c6577..49134ad 100644
--- a/gcc/lra-lives.cc
+++ b/gcc/lra-lives.cc
@@ -38,6 +38,7 @@ along with GCC; see the file COPYING3. If not see
#include "insn-config.h"
#include "regs.h"
#include "ira.h"
+#include "ira-int.h"
#include "recog.h"
#include "cfganal.h"
#include "sparseset.h"
@@ -990,6 +991,19 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p)
for (reg2 = curr_static_id->hard_regs; reg2 != NULL; reg2 = reg2->next)
if (reg2->type != OP_OUT && reg2->regno == reg->regno)
break;
+ if (reg2 != NULL)
+ continue;
+
+ HARD_REG_SET clobbered_regset;
+ CLEAR_HARD_REG_SET (clobbered_regset);
+ SET_HARD_REG_BIT (clobbered_regset, reg->regno);
+
+ for (reg2 = curr_id->regs; reg2 != NULL; reg2 = reg2->next)
+ if (reg2->type != OP_OUT && reg2->regno < FIRST_PSEUDO_REGISTER
+ && ira_hard_reg_set_intersection_p (reg2->regno,
+ reg2->biggest_mode,
+ clobbered_regset))
+ break;
if (reg2 == NULL)
make_hard_regno_dead (reg->regno);
}