This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug middle-end/36753] [4.3/4.4 Regression] Forward propagation interacts badly with global register variable



------- Comment #6 from jakub at gcc dot gnu dot org  2008-07-10 13:34 -------
More self-contained testcase:
register unsigned long *r14 asm ("r14");
extern void abort (void);

__attribute__ ((noinline)) void
test (void)
{
  *++r14 = 31337;
}

int
main ()
{
  unsigned long stack[2];
  stack[0] = 0;
  stack[1] = 0;
  r14 = stack;
  test ();
  if (r14 != stack + 1 || *r14 != 31337)
    abort ();
  return 0;
}

We have:
(insn 5 2 6 2 pr36753.c:7 (parallel [
            (set (reg/f:DI 58 [ r14.1 ])
                (plus:DI (reg/v:DI 43 r14 [ r14 ])
                    (const_int 8 [0x8])))
            (clobber (reg:CC 17 flags))
        ]) 279 {*adddi_1_rex64} (expr_list:REG_DEAD (reg/v:DI 43 r14 [ r14 ])
        (expr_list:REG_UNUSED (reg:CC 17 flags)
            (nil))))

(insn 6 5 7 2 pr36753.c:7 (set (reg/v:DI 43 r14 [ r14 ])
        (reg/f:DI 58 [ r14.1 ])) 89 {*movdi_1_rex64} (nil))

(insn 7 6 0 2 pr36753.c:7 (set (mem:DI (reg/f:DI 58 [ r14.1 ]) [2 S8 A64])
        (const_int 31337 [0x7a69])) 89 {*movdi_1_rex64} (expr_list:REG_DEAD
(reg/f:DI 58 [ r14.1 ])
        (nil)))

before fwprop2, and:
In insn 7, replacing
 (mem:DI (reg/f:DI 58 [ r14.1 ]) [2 S8 A64])
 with (mem:DI (plus:DI (reg/v:DI 43 r14 [ r14 ])
            (const_int 8 [0x8])) [2 S8 A64])
Changed insn 7

Wonder why nothing in fwprop.c checks modified_between_p, that would clearly
say that reg:DI 43 r14 has been modified between the setter and use and thus
the propagation is invalid.

To Andrew: many ABIs have one or more fixed registers reserved, so you can
use those as global register vars, or you can e.g. build with -ffixed-* to make
sure even when you don't have the global register var declaration in some CU,
it isn't randomly clobbered.  Many projects rely heavily on global register
vars,
including the Linux kernel or e.g. glibc (in the latter it is used in
libpthread
for all thread specific stuff).  From what I see, this fwprop bug isn't
specific
to global register vars, any REG, be it hard or pseudo, can be modified between
the setter and user...


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36753


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]