From 74855d080d0657185317ae63bac158040908c3fe Mon Sep 17 00:00:00 2001 From: vmakarov Date: Wed, 24 Apr 2013 20:27:33 +0000 Subject: [PATCH] 2013-04-24 Vladimir Makarov PR rtl-optimizations/57046 * lra-constraints (split_reg): Set up lra_risky_transformations_p for multi-reg splits. 2013-04-24 Vladimir Makarov PR rtl-optimizations/57046 * gcc.target/i386/pr57046.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@198263 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 6 +++ gcc/lra-constraints.c | 11 ++++- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gcc.target/i386/pr57046.c | 77 +++++++++++++++++++++++++++++++++ 4 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr57046.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 875a7479e4b..b812431d1d4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2013-04-24 Vladimir Makarov + + PR rtl-optimizations/57046 + * lra-constraints (split_reg): Set up lra_risky_transformations_p + for multi-reg splits. + 2013-04-24 H.J. Lu * config/i386/x86-64.h (ASM_SPEC): Support -mx32. diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c index 24782dcdec7..d364ef3407f 100644 --- a/gcc/lra-constraints.c +++ b/gcc/lra-constraints.c @@ -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"); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e3b4a56f73a..2eaa45366e0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-04-24 Vladimir Makarov + + PR rtl-optimizations/57046 + * gcc.target/i386/pr57046.c: New test. + 2013-04-24 Paolo Carlini * g++.dg/cpp1y/cplusplus.C: New. diff --git a/gcc/testsuite/gcc.target/i386/pr57046.c b/gcc/testsuite/gcc.target/i386/pr57046.c new file mode 100644 index 00000000000..0aa43f9df6a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr57046.c @@ -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; +} -- 2.11.4.GIT