------- Comment #5 from jakub at gcc dot gnu dot org 2010-03-17 21:44 ------- Argh, seems ARM is very badly abusing PRE_DEC: (insn/f 72 41 73 2 /opt/trunk/libgcc/../gcc/libgcc2.c:553 (parallel [ (set (mem/c:BLK (pre_dec:BLK (reg/f:SI 13 sp)) [6 A8]) (unspec:BLK [ (reg:SI 4 r4) ] 2)) ]) 326 {*push_multi} (expr_list:REG_DEAD (reg:SI 4 r4) (expr_list:REG_FRAME_RELATED_EXPR (sequence [ (set/f (reg/f:SI 13 sp) (plus:SI (reg/f:SI 13 sp) (const_int -4 [0xfffffffffffffffc]))) (set/f (mem/c:SI (reg/f:SI 13 sp) [6 S4 A32]) (reg:SI 4 r4)) ]) (nil)))) This violates PRE_DEC documentation in 2 ways: 1) PRE_DEC's mode is not a machine mode for pointers 2) the decrement size is not equal to the size of the mode (as BLKmode size is 0).
@item (pre_dec:@var{m} @var{x}) Represents the side effect of decrementing @var{x} by a standard amount and represents also the value that @var{x} has after being decremented. @var{x} must be a @code{reg} or @code{mem}, but most machines allow only a @code{reg}. @var{m} must be the machine mode for pointers on the machine in use. The amount @var{x} is decremented by is the length in bytes of the machine mode of the containing memory reference of which this expression serves as the address. I think var-tracking isn't the only one which can be significantly confused by this (what should it do?), so can DSE, cselib, ... I'd say the best fix would be actually stop emitting this bogosity by the ARM backend. Either you can look at e.g. what s390 does for its load/store multiple patterns, or even just use PRE_MODIFY instead of PRE_DEC and make the stack pointer adjustment there explicit and obvious. -- jakub at gcc dot gnu dot org changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |ramana at gcc dot gnu dot | |org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43399