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
This commit is contained in:
Vladimir Makarov 2013-04-24 20:27:33 +00:00 committed by Vladimir Makarov
parent 0db63e7fd0
commit 77bce07cce
4 changed files with 98 additions and 1 deletions

View file

@ -1,3 +1,9 @@
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>
* config/i386/x86-64.h (ASM_SPEC): Support -mx32.

View file

@ -4198,7 +4198,7 @@ split_reg (bool before_p, int original_regno, rtx insn, rtx next_usage_insns)
{
enum reg_class rclass;
rtx original_reg;
int hard_regno;
int hard_regno, nregs;
rtx new_reg, save, restore, usage_insn;
bool after_p;
bool call_save_p;
@ -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)];
hard_regno = original_regno;
call_save_p = false;
nregs = 1;
}
else
{
hard_regno = reg_renumber[original_regno];
nregs = hard_regno_nregs[hard_regno][PSEUDO_REGNO_MODE (original_regno)];
rclass = lra_get_allocno_class (original_regno);
original_reg = regno_reg_rtx[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)
before_p ? NULL_RTX : save,
call_save_p
? "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)
fprintf (lra_dump_file,
" ))))))))))))))))))))))))))))))))))))))))))))))))\n");

View file

@ -1,3 +1,8 @@
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>
* g++.dg/cpp1y/cplusplus.C: New.

View file

@ -0,0 +1,77 @@
/* { 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;
}