On Fri, Feb 19, 2016 at 11:03:02PM +0100, Bernd Schmidt wrote: > In this PR, we generate unnecessarily bad code for code that > declares a global register var. Since global regs get added to > fixed_regs, IRA never considers them as candidates. However, we do > seem to have proper data flow information for them. In the testcase, > the global reg dies, some operations are done on temporary results, > and the final result stored back in the global reg. We can achieve > the desired code generation by reusing the global reg for those > temporaries. > > Bootstrapped and tested on x86_64-linux. Ok? An argument could be > made not to use this for gcc-6 since global register vars are both > not very important and not very well represented in the testsuite.
> 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. > > PR rtl-optimization/44281 > * gcc.target/i386/pr44281.c: New test. Unfortunately this patch (or whatever got actually committed) has broken the gcc.target/s390/pr679443.c test case, which is a bit fishy (see code snippet below). I assign most registers to global variables and then use some complicated arithmetics with the goal that the pointer stored in the first argument gets saved on the stack and reloaded to a different register. Before this patch the test case just needed three registers to do its work (r2, r3, r4). With the patch it currently causes an error in the reload pass error: unable to find a register to spill -- snip -- /* Block all registers except the first three argument registers. */ register long r0 asm ("r0"); register long r1 asm ("r1"); register long r5 asm ("r5"); register long r6 asm ("r6"); register long r7 asm ("r7"); register long r8 asm ("r8"); register long r9 asm ("r9"); register long r10 asm ("r10"); register long r11 asm ("r11"); ... void foo (struct s_t *ps, int c, int i) { /* Uses r2 as address register. */ ps->f1 = c; /* The calculation of the value is so expensive that it's cheaper to spill ps to the stack and reload it later (into a different register). ==> Uses r4 as address register.*/ ps->f2 = i + i % 3; /* If dead store elimination fails to detect that the address in r2 during the first assignment is an alias of the address in r4 during the second assignment, it eliminates the first assignment and the f1 field is not written (bug). */ } -- snip -- If a fourth register is available, the ICE goes away, but the pointer remains in r2, rendering the test case useless. So, what should be done about this? Ciao Dominik ^_^ ^_^ -- Dominik Vogt IBM Germany