This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: [dataflow] partial register handling
- From: Roman Zippel <zippel at linux-m68k dot org>
- To: gcc at gcc dot gnu dot org
- Cc: zadeck at naturalbridge dot com, dberlin at dberlin dot org
- Date: Fri, 11 May 2007 13:54:24 +0200 (CEST)
- Subject: Re: [dataflow] partial register handling
- References: <Pine.LNX.4.64.0705101940450.2958@scrub.home>
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