Hi,

My port, based on (GCC) 4.2.0 20061002 (experimental), is producing
incorrect code for the following test case:

int f(short *p){
  int sum, i;
  sum = 0;
  for(i = 0; i < 256; i++){
    sum += *p++ & 0xFF;    
  }
  return sum;
}


The RTL snippet of interest, before combine, is,

(insn 23 22 24 3 (set (reg:SI 96)
        (sign_extend:SI (mem:HI (post_inc:SI (reg/v/f:SI 89 [ p.38 ]))
[2 S2 A16]))) 178 {extendhisi2} (nil)
    (expr_list:REG_INC (reg/v/f:SI 89 [ p.38 ])
        (nil)))

(insn 24 23 25 3 (set (reg:SI 98)
        (const_int 255 [0xff])) 12 {movsi_real} (nil)
    (nil))

(insn 25 24 26 3 (set (reg:SI 97)
        (and:SI (reg:SI 96)
            (reg:SI 98))) 81 {andsi3} (insn_list:REG_DEP_TRUE 23
(insn_list:REG_DEP_TRUE 24 (nil)))
    (expr_list:REG_DEAD (reg:SI 96)
        (expr_list:REG_DEAD (reg:SI 98)
            (expr_list:REG_EQUAL (and:SI (reg:SI 96)
                    (const_int 255 [0xff]))         
                (nil)))))                  


Combine combines that into the following and it remains that way until greg:

(insn 25 24 26 3 (set (reg:SI 97)  
        (zero_extend:SI (subreg:QI (mem:HI (post_inc:SI (reg/v/f:SI 89 [
p.38 ])) [2 S2 A16]) 0))) 181 {zero_extendqisi
    (expr_list:REG_INC (reg/v/f:SI 89 [ p.38 ])
        (nil)))


After greg, the insn becomes,

(insn:HI 25 29 59 3 (set (reg:SI 0 r0 [97])
        (zero_extend:SI (mem:QI (post_inc:SI (reg/v/f:SI 4 r4 [orig:89
p.38 ] [89])) [2 S1 A16]))) 181 {zero_extendqisi
    (expr_list:REG_INC (reg/v/f:SI 4 r4 [orig:89 p.38 ] [89])          
                                               
        (nil)))


The problem, as I see it, is that "(subreg:QI (mem:HI (post_inc" becomes
"(mem:QI (post_inc".  post_inc has changed meaning.

Experience has taught me that almost all such problems are the fault of
the backend, but I am stumped as to what part of the backend could cause
this problem.  Any ideas?

Does anyone know of any recent 4.2 bug fixes that could fix this?

If this is a bug in the middle end, then where do you think the bug is?
 Is it combine's, greg's, or some other pass's responsibility to ensure
correct code in this case?

Ideally, the post_inc would be replaced with a +2 post_modify, which
this target has.  For targets without post_modify, either the post_inc
could be dropped and a separate add emitted or the mem could remain
"(mem:HI (post_inc" followed by a zero_extend.

Thanks in advance for your help,
Charles J. Tabony

Reply via email to