Commit f80041ef by Bernd Schmidt Committed by Bernd Schmidt

Fix PR44281, bad RA with global regs.

	PR rtl-optimization/44281
	* hard-reg-set.h (struct target_hard_regs): New field
	x_fixed_nonglobal_reg_set.
	(fixed_nonglobal_reg_set): New macro.
	* reginfo.c (init_reg_sets_1): Initialize it.
	* ira.c (setup_alloc_regs): Use fixed_nonglobal_reg_set instead
	of fixed_reg_set.
	* df-scan.c (df_insn_refs_collect): Asms may reference global regs.

testsuite/
	PR rtl-optimization/44281
	* gcc.target/i386/pr44281.c: New test.

From-SVN: r235809
parent 1cfcd39e
2016-05-03 Bernd Schmidt <bschmidt@redhat.com>
PR rtl-optimization/44281
* hard-reg-set.h (struct target_hard_regs): New field
x_fixed_nonglobal_reg_set.
(fixed_nonglobal_reg_set): New macro.
* reginfo.c (init_reg_sets_1): Initialize it.
* ira.c (setup_alloc_regs): Use fixed_nonglobal_reg_set instead
of fixed_reg_set.
* df-scan.c (df_insn_refs_collect): Asms may reference global regs.
2016-05-03 bin cheng <bin.cheng@arm.com> 2016-05-03 bin cheng <bin.cheng@arm.com>
PR tree-optimization/56541 PR tree-optimization/56541
......
...@@ -3223,11 +3223,22 @@ df_insn_refs_collect (struct df_collection_rec *collection_rec, ...@@ -3223,11 +3223,22 @@ df_insn_refs_collect (struct df_collection_rec *collection_rec,
} }
} }
int flags = (is_cond_exec) ? DF_REF_CONDITIONAL : 0;
/* For CALL_INSNs, first record DF_REF_BASE register defs, as well as /* For CALL_INSNs, first record DF_REF_BASE register defs, as well as
uses from CALL_INSN_FUNCTION_USAGE. */ uses from CALL_INSN_FUNCTION_USAGE. */
if (CALL_P (insn_info->insn)) if (CALL_P (insn_info->insn))
df_get_call_refs (collection_rec, bb, insn_info, df_get_call_refs (collection_rec, bb, insn_info, flags);
(is_cond_exec) ? DF_REF_CONDITIONAL : 0);
if (asm_noperands (PATTERN (insn_info->insn)) >= 0)
for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (global_regs[i])
{
/* As with calls, asm statements reference all global regs. */
df_ref_record (DF_REF_BASE, collection_rec, regno_reg_rtx[i],
NULL, bb, insn_info, DF_REF_REG_USE, flags);
df_ref_record (DF_REF_BASE, collection_rec, regno_reg_rtx[i],
NULL, bb, insn_info, DF_REF_REG_DEF, flags);
}
/* Record other defs. These should be mostly for DF_REF_REGULAR, so /* Record other defs. These should be mostly for DF_REF_REGULAR, so
that a qsort on the defs is unnecessary in most cases. */ that a qsort on the defs is unnecessary in most cases. */
......
...@@ -660,6 +660,12 @@ struct target_hard_regs { ...@@ -660,6 +660,12 @@ struct target_hard_regs {
across calls even if we are willing to save and restore them. */ across calls even if we are willing to save and restore them. */
HARD_REG_SET x_call_fixed_reg_set; HARD_REG_SET x_call_fixed_reg_set;
/* Contains registers that are fixed use -- i.e. in fixed_reg_set -- but
only if they are not merely part of that set because they are global
regs. Global regs that are not otherwise fixed can still take part
in register allocation. */
HARD_REG_SET x_fixed_nonglobal_reg_set;
/* Contains 1 for registers that are set or clobbered by calls. */ /* Contains 1 for registers that are set or clobbered by calls. */
/* ??? Ideally, this would be just call_used_regs plus global_regs, but /* ??? Ideally, this would be just call_used_regs plus global_regs, but
for someone's bright idea to have call_used_regs strictly include for someone's bright idea to have call_used_regs strictly include
...@@ -722,6 +728,8 @@ extern struct target_hard_regs *this_target_hard_regs; ...@@ -722,6 +728,8 @@ extern struct target_hard_regs *this_target_hard_regs;
(this_target_hard_regs->x_fixed_regs) (this_target_hard_regs->x_fixed_regs)
#define fixed_reg_set \ #define fixed_reg_set \
(this_target_hard_regs->x_fixed_reg_set) (this_target_hard_regs->x_fixed_reg_set)
#define fixed_nonglobal_reg_set \
(this_target_hard_regs->x_fixed_nonglobal_reg_set)
#define call_used_regs \ #define call_used_regs \
(this_target_hard_regs->x_call_used_regs) (this_target_hard_regs->x_call_used_regs)
#define call_really_used_regs \ #define call_really_used_regs \
......
...@@ -512,7 +512,7 @@ setup_alloc_regs (bool use_hard_frame_p) ...@@ -512,7 +512,7 @@ setup_alloc_regs (bool use_hard_frame_p)
#ifdef ADJUST_REG_ALLOC_ORDER #ifdef ADJUST_REG_ALLOC_ORDER
ADJUST_REG_ALLOC_ORDER; ADJUST_REG_ALLOC_ORDER;
#endif #endif
COPY_HARD_REG_SET (no_unit_alloc_regs, fixed_reg_set); COPY_HARD_REG_SET (no_unit_alloc_regs, fixed_nonglobal_reg_set);
if (! use_hard_frame_p) if (! use_hard_frame_p)
SET_HARD_REG_BIT (no_unit_alloc_regs, HARD_FRAME_POINTER_REGNUM); SET_HARD_REG_BIT (no_unit_alloc_regs, HARD_FRAME_POINTER_REGNUM);
setup_class_hard_regs (); setup_class_hard_regs ();
......
...@@ -449,6 +449,7 @@ init_reg_sets_1 (void) ...@@ -449,6 +449,7 @@ init_reg_sets_1 (void)
} }
COPY_HARD_REG_SET (call_fixed_reg_set, fixed_reg_set); COPY_HARD_REG_SET (call_fixed_reg_set, fixed_reg_set);
COPY_HARD_REG_SET (fixed_nonglobal_reg_set, fixed_reg_set);
/* Preserve global registers if called more than once. */ /* Preserve global registers if called more than once. */
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
......
2016-05-03 Bernd Schmidt <bschmidt@redhat.com>
PR rtl-optimization/44281
* gcc.target/i386/pr44281.c: New test.
2016-05-03 bin cheng <bin.cheng@arm.com> 2016-05-03 bin cheng <bin.cheng@arm.com>
PR tree-optimization/56541 PR tree-optimization/56541
......
/* { dg-do compile } */
/* { dg-require-effective-target lp64 } */
/* { dg-options "-std=gnu99 -O2" } */
/* { dg-final { scan-assembler "salq\[ \\t\]+\\\$8, %rbx" } } */
#include <stdint.h>
register uint64_t global_flag_stack __asm__("rbx");
void push_flag_into_global_reg_var(uint64_t a, uint64_t b) {
uint64_t flag = (a==b);
global_flag_stack <<= 8;
global_flag_stack |= flag;
}
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