Commit f75ebe77 by Richard Henderson

re PR rtl-optimization/69447 (wrong code with -O2 -fno-schedule-insns and mixed…

re PR rtl-optimization/69447 (wrong code with -O2 -fno-schedule-insns and mixed 8/16/32/64bit arithmetics @ armv7a)

PR rtl-opt/69447

  * lra-remat.c (subreg_regs): New.
  (dump_candidates_and_remat_bb_data): Dump it.
  (operand_to_remat): Reject if operand in subreg_regs.
  (set_bb_regs): Collect subreg_regs.
  (lra_remat): Init and free subreg_regs.  Compute
  calculate_local_reg_remat_bb_data before create_cands.

From-SVN: r232905
parent 49847d75
2016-01-27 Richard Henderson <rth@redhat.com>
PR rtl-opt/69447
* lra-remat.c (subreg_regs): New.
(dump_candidates_and_remat_bb_data): Dump it.
(operand_to_remat): Reject if operand in subreg_regs.
(set_bb_regs): Collect subreg_regs.
(lra_remat): Init and free subreg_regs. Compute
calculate_local_reg_remat_bb_data before create_cands.
2016-01-27 H.J. Lu <hongjiu.lu@intel.com> 2016-01-27 H.J. Lu <hongjiu.lu@intel.com>
PR target/68986 PR target/68986
......
...@@ -77,6 +77,9 @@ static int call_used_regs_arr[FIRST_PSEUDO_REGISTER]; ...@@ -77,6 +77,9 @@ static int call_used_regs_arr[FIRST_PSEUDO_REGISTER];
/* Bitmap used for different calculations. */ /* Bitmap used for different calculations. */
static bitmap_head temp_bitmap; static bitmap_head temp_bitmap;
/* Registers accessed via subreg_p. */
static bitmap_head subreg_regs;
typedef struct cand *cand_t; typedef struct cand *cand_t;
typedef const struct cand *const_cand_t; typedef const struct cand *const_cand_t;
...@@ -383,30 +386,30 @@ operand_to_remat (rtx_insn *insn) ...@@ -383,30 +386,30 @@ operand_to_remat (rtx_insn *insn)
return -1; return -1;
/* First find a pseudo which can be rematerialized. */ /* First find a pseudo which can be rematerialized. */
for (reg = id->regs; reg != NULL; reg = reg->next) for (reg = id->regs; reg != NULL; reg = reg->next)
/* True FRAME_POINTER_NEEDED might be because we can not follow {
changing sp offsets, e.g. alloca is used. If the insn contains /* True FRAME_POINTER_NEEDED might be because we can not follow
stack pointer in such case, we can not rematerialize it as we changing sp offsets, e.g. alloca is used. If the insn contains
can not know sp offset at a rematerialization place. */ stack pointer in such case, we can not rematerialize it as we
if (reg->regno == STACK_POINTER_REGNUM && frame_pointer_needed) can not know sp offset at a rematerialization place. */
return -1; if (reg->regno == STACK_POINTER_REGNUM && frame_pointer_needed)
else if (reg->type == OP_OUT && ! reg->subreg_p return -1;
&& find_regno_note (insn, REG_UNUSED, reg->regno) == NULL) else if (reg->type == OP_OUT && ! reg->subreg_p
{ && find_regno_note (insn, REG_UNUSED, reg->regno) == NULL)
/* We permits only one spilled reg. */ {
if (found_reg != NULL) /* We permits only one spilled reg. */
return -1; if (found_reg != NULL)
found_reg = reg; return -1;
} found_reg = reg;
/* IRA calculates conflicts separately for subregs of two words }
pseudo. Even if the pseudo lives, e.g. one its subreg can be /* IRA calculates conflicts separately for subregs of two words
used lately, another subreg hard register can be already used pseudo. Even if the pseudo lives, e.g. one its subreg can be
for something else. In such case, it is not safe to used lately, another subreg hard register can be already used
rematerialize the insn. */ for something else. In such case, it is not safe to
else if (reg->type == OP_IN && reg->subreg_p rematerialize the insn. */
&& reg->regno >= FIRST_PSEUDO_REGISTER if (reg->regno >= FIRST_PSEUDO_REGISTER
&& (GET_MODE_SIZE (PSEUDO_REGNO_MODE (reg->regno)) && bitmap_bit_p (&subreg_regs, reg->regno))
== 2 * UNITS_PER_WORD)) return -1;
return -1; }
if (found_reg == NULL) if (found_reg == NULL)
return -1; return -1;
if (found_reg->regno < FIRST_PSEUDO_REGISTER) if (found_reg->regno < FIRST_PSEUDO_REGISTER)
...@@ -631,6 +634,9 @@ dump_candidates_and_remat_bb_data (void) ...@@ -631,6 +634,9 @@ dump_candidates_and_remat_bb_data (void)
lra_dump_bitmap_with_title ("avout cands in BB", lra_dump_bitmap_with_title ("avout cands in BB",
&get_remat_bb_data (bb)->avout_cands, bb->index); &get_remat_bb_data (bb)->avout_cands, bb->index);
} }
fprintf (lra_dump_file, "subreg regs:");
dump_regset (&subreg_regs, lra_dump_file);
putc ('\n', lra_dump_file);
} }
/* Free all BB data. */ /* Free all BB data. */
...@@ -655,21 +661,24 @@ finish_remat_bb_data (void) ...@@ -655,21 +661,24 @@ finish_remat_bb_data (void)
/* Update changed_regs and dead_regs of BB from INSN. */ /* Update changed_regs, dead_regs, subreg_regs of BB from INSN. */
static void static void
set_bb_regs (basic_block bb, rtx_insn *insn) set_bb_regs (basic_block bb, rtx_insn *insn)
{ {
lra_insn_recog_data_t id = lra_get_insn_recog_data (insn); lra_insn_recog_data_t id = lra_get_insn_recog_data (insn);
remat_bb_data_t bb_info = get_remat_bb_data (bb);
struct lra_insn_reg *reg; struct lra_insn_reg *reg;
for (reg = id->regs; reg != NULL; reg = reg->next) for (reg = id->regs; reg != NULL; reg = reg->next)
if (reg->type != OP_IN) {
bitmap_set_bit (&get_remat_bb_data (bb)->changed_regs, reg->regno); unsigned regno = reg->regno;
else if (reg->type != OP_IN)
{ bitmap_set_bit (&bb_info->changed_regs, regno);
if (find_regno_note (insn, REG_DEAD, (unsigned) reg->regno) != NULL) else if (find_regno_note (insn, REG_DEAD, regno) != NULL)
bitmap_set_bit (&get_remat_bb_data (bb)->dead_regs, reg->regno); bitmap_set_bit (&bb_info->dead_regs, regno);
} if (regno >= FIRST_PSEUDO_REGISTER && reg->subreg_p)
bitmap_set_bit (&subreg_regs, regno);
}
if (CALL_P (insn)) if (CALL_P (insn))
for (int i = 0; i < call_used_regs_arr_len; i++) for (int i = 0; i < call_used_regs_arr_len; i++)
bitmap_set_bit (&get_remat_bb_data (bb)->dead_regs, bitmap_set_bit (&get_remat_bb_data (bb)->dead_regs,
...@@ -1284,10 +1293,11 @@ lra_remat (void) ...@@ -1284,10 +1293,11 @@ lra_remat (void)
if (call_used_regs[i]) if (call_used_regs[i])
call_used_regs_arr[call_used_regs_arr_len++] = i; call_used_regs_arr[call_used_regs_arr_len++] = i;
initiate_cand_table (); initiate_cand_table ();
create_cands ();
create_remat_bb_data (); create_remat_bb_data ();
bitmap_initialize (&temp_bitmap, &reg_obstack); bitmap_initialize (&temp_bitmap, &reg_obstack);
bitmap_initialize (&subreg_regs, &reg_obstack);
calculate_local_reg_remat_bb_data (); calculate_local_reg_remat_bb_data ();
create_cands ();
calculate_livein_cands (); calculate_livein_cands ();
calculate_gen_cands (); calculate_gen_cands ();
bitmap_initialize (&all_blocks, &reg_obstack); bitmap_initialize (&all_blocks, &reg_obstack);
...@@ -1298,6 +1308,7 @@ lra_remat (void) ...@@ -1298,6 +1308,7 @@ lra_remat (void)
result = do_remat (); result = do_remat ();
all_cands.release (); all_cands.release ();
bitmap_clear (&temp_bitmap); bitmap_clear (&temp_bitmap);
bitmap_clear (&subreg_regs);
finish_remat_bb_data (); finish_remat_bb_data ();
finish_cand_table (); finish_cand_table ();
bitmap_clear (&all_blocks); bitmap_clear (&all_blocks);
......
2015-01-27 Paul Thomas <pault@gcc.gnu.org> 2016-01-27 Richard Henderson <rth@redhat.com>
* gcc.c-torture/execute/pr69447.c: New test.
2016-01-27 Paul Thomas <pault@gcc.gnu.org>
PR fortran/69385 PR fortran/69385
* gfortran.dg/alloc_comp_assign_15.f03: New test. * gfortran.dg/alloc_comp_assign_15.f03: New test.
......
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned long long u64;
u64 __attribute__((noinline, noclone))
foo(u8 u8_0, u16 u16_0, u64 u64_0, u8 u8_1, u16 u16_1, u64 u64_1, u64 u64_2, u8 u8_3, u64 u64_3)
{
u64_1 *= 0x7730;
u64_3 *= u64_3;
u16_1 |= u64_3;
u64_3 -= 2;
u8_3 /= u64_2;
u8_0 |= 3;
u64_3 %= u8_0;
u8_0 -= 1;
return u8_0 + u16_0 + u64_0 + u8_1 + u16_1 + u64_1 + u8_3 + u64_3;
}
int main()
{
unsigned x = foo(1, 1, 1, 1, 1, 1, 1, 1, 1);
if (x != 0x7737)
__builtin_abort();
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment