Commit 77bce07c by Vladimir Makarov Committed by Vladimir Makarov

re PR rtl-optimization/57046 (wrong code generated by gcc 4.8.0 on i686)

2013-04-24  Vladimir Makarov  <vmakarov@redhat.com>

	PR rtl-optimizations/57046
	* lra-constraints (split_reg): Set up lra_risky_transformations_p
	for multi-reg splits.

2013-04-24  Vladimir Makarov  <vmakarov@redhat.com>

	PR rtl-optimizations/57046
	* gcc.target/i386/pr57046.c: New test.

From-SVN: r198263
parent 0db63e7f
2013-04-24 Vladimir Makarov <vmakarov@redhat.com>
PR rtl-optimizations/57046
* lra-constraints (split_reg): Set up lra_risky_transformations_p
for multi-reg splits.
2013-04-24 H.J. Lu <hongjiu.lu@intel.com> 2013-04-24 H.J. Lu <hongjiu.lu@intel.com>
* config/i386/x86-64.h (ASM_SPEC): Support -mx32. * config/i386/x86-64.h (ASM_SPEC): Support -mx32.
......
...@@ -4198,7 +4198,7 @@ split_reg (bool before_p, int original_regno, rtx insn, rtx next_usage_insns) ...@@ -4198,7 +4198,7 @@ split_reg (bool before_p, int original_regno, rtx insn, rtx next_usage_insns)
{ {
enum reg_class rclass; enum reg_class rclass;
rtx original_reg; rtx original_reg;
int hard_regno; int hard_regno, nregs;
rtx new_reg, save, restore, usage_insn; rtx new_reg, save, restore, usage_insn;
bool after_p; bool after_p;
bool call_save_p; bool call_save_p;
...@@ -4208,10 +4208,12 @@ split_reg (bool before_p, int original_regno, rtx insn, rtx next_usage_insns) ...@@ -4208,10 +4208,12 @@ split_reg (bool before_p, int original_regno, rtx insn, rtx next_usage_insns)
rclass = ira_allocno_class_translate[REGNO_REG_CLASS (original_regno)]; rclass = ira_allocno_class_translate[REGNO_REG_CLASS (original_regno)];
hard_regno = original_regno; hard_regno = original_regno;
call_save_p = false; call_save_p = false;
nregs = 1;
} }
else else
{ {
hard_regno = reg_renumber[original_regno]; hard_regno = reg_renumber[original_regno];
nregs = hard_regno_nregs[hard_regno][PSEUDO_REGNO_MODE (original_regno)];
rclass = lra_get_allocno_class (original_regno); rclass = lra_get_allocno_class (original_regno);
original_reg = regno_reg_rtx[original_regno]; original_reg = regno_reg_rtx[original_regno];
call_save_p = need_for_call_save_p (original_regno); call_save_p = need_for_call_save_p (original_regno);
...@@ -4324,6 +4326,13 @@ split_reg (bool before_p, int original_regno, rtx insn, rtx next_usage_insns) ...@@ -4324,6 +4326,13 @@ split_reg (bool before_p, int original_regno, rtx insn, rtx next_usage_insns)
before_p ? NULL_RTX : save, before_p ? NULL_RTX : save,
call_save_p call_save_p
? "Add save<-reg" : "Add split<-reg"); ? "Add save<-reg" : "Add split<-reg");
if (nregs > 1)
/* If we are trying to split multi-register. We should check
conflicts on the next assignment sub-pass. IRA can allocate on
sub-register levels, LRA do this on pseudos level right now and
this discrepancy may create allocation conflicts after
splitting. */
lra_risky_transformations_p = true;
if (lra_dump_file != NULL) if (lra_dump_file != NULL)
fprintf (lra_dump_file, fprintf (lra_dump_file,
" ))))))))))))))))))))))))))))))))))))))))))))))))\n"); " ))))))))))))))))))))))))))))))))))))))))))))))))\n");
......
2013-04-24 Vladimir Makarov <vmakarov@redhat.com>
PR rtl-optimizations/57046
* gcc.target/i386/pr57046.c: New test.
2013-04-24 Paolo Carlini <paolo.carlini@oracle.com> 2013-04-24 Paolo Carlini <paolo.carlini@oracle.com>
* g++.dg/cpp1y/cplusplus.C: New. * g++.dg/cpp1y/cplusplus.C: New.
......
/* { dg-do run } */
/* { dg-options "-O2" } */
struct emac {
unsigned reg[23];
};
struct mop {
unsigned long long addr;
unsigned int size;
};
unsigned int __attribute__((__noinline__))
level(const struct emac *obj)
{
return 0;
}
void __attribute__((__noinline__))
info(struct emac *dev, unsigned long long addr)
{
asm("" : : : "memory");
}
unsigned long long __attribute__((__noinline__))
get_value(const struct mop *mop)
{
return 0x1234567890abcdefull;
}
int __attribute__((__noinline__))
emac_operation(struct emac *obj, struct mop *mop)
{
unsigned long long addr = mop->addr;
int index = addr >> 2;
unsigned int value, old_value;
if (mop->size != 4)
return 0;
if (index >= 23) {
if (level(obj) >= 1)
info(obj, addr);
return 0;
}
value = get_value(mop);
old_value = obj->reg[index];
info(obj, 0);
switch (index) {
case 0:
obj->reg[0] = old_value;
break;
case 7:
case 8:
obj->reg[index] = value;
break;
}
return 0;
}
int main(void)
{
struct emac e = { { 0 } };
struct mop mop = { 32, 4 };
e.reg[8] = 0xdeadbeef;
emac_operation(&e, &mop);
if (e.reg[8] != 0x90abcdef)
__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