Roman Zippel wrote: > 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. > > Roman,
There was a debate several months ago on this issue: how much should the df scanner be a theorem prover with respect to how many bits survive an operation. For instance, I could easily add to your list, anding and oring operations which also preserve bits. The decision was made that what is done in the dataflow scanner was sufficient and that the machine descriptions should conform to this. If you have a pattern that cannot be made to conform to what the df scanner currently does, then we will certainly reopen this issue. But the consensus was at the time that this was sufficient and that we did not want to further burden the scanner. While I could be argued that this is an arbitrary decision, it is important to keep the scanning fast and there is a lot of downstream benefit to imposing some consistency on the md's coding style. Kenny >> 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 >