Sanjiv Kumar Gupta <[EMAIL PROTECTED]> writes: > >>I couldn't understand why the insns 620 and 621 are > >>being generated here as DI moves. > > I'm not sure specifically why it got a DI move here, but it doesn't > > look wrong. It's treating the struct named parts as DImode. > > > >>This is creating problem since insn 621 gets splitted > >>after reload into two SI moves,i.e. @(r21, -8) and > >>@(r21, -4). > >>This renders insns 619 as dead and hence insns 618 and > >>insn 429 as dead, which are eliminated by flow2. > > It does look rather suspicious, but it's hard to know whether it is > > wrong without seeing the value in r1. > > > r1 looks unrelated to struct members, and is being used by the > ifcvt pass to expand some comparison insns.
In your .23 file, this is insn 431: (insn 431 430 432 39 0x1002f420 (set (subreg:SI (reg/v:DI 153) 0) (reg/v:SI 77)) 6 {*movsi} (insn_list 429 (nil)) (expr_list:REG_DEAD (reg/v:SI 77) (nil))) So it is setting the first SI subreg of a DI value. reload decides to do an output reload for register 153. Since register 153 is DImode, it does a DImode reload. It winds up copying the DImode value to r2, and then writing r2 to memory. The double move is because there is a secondary reload involved. That implies that SECONDARY_OUTPUT_RELOAD_CLASS is defined and is returning something other than NO_REGS for this case. I see that insn 429 is setting the high part of register 153. Insn 429 looks like this: (insn 429 428 430 39 0x1002f420 (set (subreg:SI (reg/v:DI 153) 4) (plus:SI (reg/v:SI 79) (reg/v:SI 82))) 12 {addsi3} (insn_list 422 (nil)) (expr_list:REG_DEAD (reg/v:SI 82) (expr_list:REG_DEAD (reg/v:SI 79) (nil)))) But note that a set to a subreg is explicitly defined to set the other parts of the register to garbage. Therefore the value set by insn 429 is destroyed by insn 431. I would guess that you need a strict_low_part in insns 429 and 431. See the RTL documentation. Ian