Hi, On Thu, 10 May 2007, I wrote:
> I have a few problems with the m68k mulsidi3 pattern on the dataflow > branch. To illustrate the problem here is what happens during combine: -(insn 7 28 8 2 ../gcc/gcc/testsuite/gcc.c-torture/execute/20001108-1.c:4 (parallel [ - (set (subreg:SI (reg:DI 30 [ D.1547 ]) 4) - (mult:SI (reg/v:SI 33 [ x ]) - (subreg:SI (reg/v:DI 32 [ sum ]) 4))) - (set (subreg:SI (reg:DI 30 [ D.1547 ]) 0) - (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (reg/v:SI 33 [ x ])) - (sign_extend:DI (subreg:SI (reg/v:DI 32 [ sum ]) 4))) - (const_int 32 [0x20])))) - ]) 182 {*m68k.md:2733} (expr_list:REG_DEAD (reg/v:SI 33 [ x ]) - (expr_list:REG_UNUSED (reg:DI 30 [ D.1547 ]) - (nil)))) +(insn 7 28 8 2 ../gcc/gcc/testsuite/gcc.c-torture/execute/20001108-1.c:4 (set (subreg:SI (reg:DI 30 [ D.1547 ]) 4) + (mult:SI (mem/c/i:SI (plus:SI (reg/f:SI 24 %argptr) + (const_int 16 [0x10])) [3 x+0 S4 A32]) + (subreg:SI (reg/v:DI 32 [ sum ]) 4))) 176 {*m68k.md:2643} (expr_list:REG_UNUSED (reg:DI 30 [ D.1547 ]) + (nil))) The REG_UNUSED note is wrong and thus combine is confused. Using strict_low_part doesn't make a difference, as DF_REF_PARTIAL isn't set in this case either, so df thinks the first set is overwritten by second one and generates this note. > Currently incorrect code is generated as the DF_REF_PARTIAL bit isn't > set for its destinations and dataflow thinks both set the register > completely, thus one destination is set to unused. I could change the > pattern to include a strict_low_part, but that still wouldn't help due > to a bug in df_def_record_1(). It may help my understanding of df_def_record_1() to have a few examples of how the flags should be correctly set (for a 32 bit port): (set (subreg:SI (reg:DI) 4) ... DF_REF_READ_WRITE|DF_REF_PARTIAL? (set (subreg:HI (reg:DI) 6) ... DF_REF_READ_WRITE? (set (subreg:HI (reg:SI) 2) ... DF_REF_READ_WRITE? (set (strict_low_part (subreg:HI (reg:DI) 6)) ... DF_REF_READ_WRITE|DF_REF_PARTIAL? (set (strict_low_part (subreg:HI (reg:SI) 2)) ... DF_REF_READ_WRITE|DF_REF_PARTIAL? (set (zero_extract:SI (reg:SI) (const_int 16) (const_int 16)) ...) DF_REF_READ_WRITE|DF_REF_PARTIAL? The basic question is maybe how a partial write should exactly be handled. bye, Roman