------- Comment #1 from steven at gcc dot gnu dot org 2010-02-05 12:42 ------- In the .expand dump there is already something funny about the code generated for the bit field expressions.
For example the code generated for this: D.1966_8 = D.1965_7 & 1; if (D.1966_8 != 0) TER will perform the forward substitution: D.1966_8 replace with --> D.1966_8 = D.1965_7 & 1; The expanders generate the following code for this sequence: ;; if (D.1966_8 != 0) (insn 23 22 24 t.c:10 (set (reg:SI 169) (zero_extend:SI (mem/s:QI (reg/f:SI 164 [ D.1964 ]) [0+0 S1 A32]))) -1 (nil)) (insn 24 23 25 t.c:10 (set (reg:QI 168) (subreg:QI (reg:SI 169) 0)) -1 (nil)) (insn 25 24 26 t.c:10 (set (reg:SI 170) (and:SI (subreg:SI (reg:QI 168) 0) (const_int 1 [0x1]))) -1 (nil)) (insn 26 25 27 t.c:10 (set (reg:QI 171) (subreg:QI (reg:SI 170) 0)) -1 (nil)) (insn 27 26 28 t.c:10 (set (reg:SI 172) (and:SI (subreg:SI (reg:QI 171) 0) (const_int 255 [0xff]))) -1 (nil)) (insn 28 27 29 t.c:10 (set (reg:CC 24 cc) (compare:CC (reg:SI 172) (const_int 0 [0x0]))) -1 (nil)) (jump_insn 29 28 0 t.c:10 (set (pc) (if_then_else (eq (reg:CC 24 cc) (const_int 0 [0x0])) (label_ref 0) (pc))) -1 (expr_list:REG_BR_PROB (const_int 5000 [0x1388]) (nil))) What are insn 26 and insn 27 for? Then the update of p[i].b: ;; D.1964_38->b = D.1973_20; (insn 31 30 32 t.c:11 (set (reg:SI 174) (mem/s:SI (reg/f:SI 164 [ D.1964 ]) [0+0 S4 A32])) -1 (nil)) (insn 32 31 33 t.c:11 (set (reg:SI 173) (lshiftrt:SI (reg:SI 174) (const_int 1 [0x1]))) -1 (nil)) (insn 33 32 34 t.c:11 (set (reg:SI 175) (plus:SI (reg/v:SI 167 [ a ]) (reg:SI 173))) -1 (nil)) (insn 34 33 35 t.c:11 (set (reg:SI 176) (mem/s/j:SI (reg/f:SI 164 [ D.1964 ]) [0+0 S4 A32])) -1 (nil)) (insn 35 34 36 t.c:11 (set (reg:SI 177) (and:SI (reg:SI 175) (const_int 2147483647 [0x7fffffff]))) -1 (nil)) (insn 36 35 37 t.c:11 (set (reg:SI 178) (and:SI (reg:SI 176) (const_int 1 [0x1]))) -1 (nil)) (insn 37 36 38 t.c:11 (set (reg:SI 177) (ashift:SI (reg:SI 177) (const_int 1 [0x1]))) -1 (nil)) (insn 38 37 39 t.c:11 (set (reg:SI 176) (ior:SI (reg:SI 177) (reg:SI 178))) -1 (nil)) (insn 39 38 0 t.c:11 (set (mem/s/j:SI (reg/f:SI 164 [ D.1964 ]) [0+0 S4 A32]) (reg:SI 176)) -1 (nil)) Insns 32, 33, and 37 should use a shifted add instead. The mask of insn 35 looks redundant (the bit is shifted out in insn 37 iiuc) but it is not removed before combine. Combine generates the shifted add, except that it shifts "p[i]->b" one bit to the right, instead of "a" one bit left -- apparently not noticing that everything is shifted back left again in insn 38: (insn 31 30 32 4 t.c:11 (set (reg:SI 174) (mem/s:SI (reg:SI 158 [ ivtmp.16 ]) [0+0 S4 A32])) 166 {*arm_movsi_insn} (insn 33 32 35 4 t.c:11 (set (reg:SI 175) (plus:SI (lshiftrt:SI (reg:SI 174) (const_int 1 [0x1])) (reg/v:SI 167 [ a ]))) 269 {*arith_shiftsi} (nil)) (insn 36 35 37 4 t.c:11 (set (reg:SI 178) (and:SI (reg:SI 174) (const_int 1 [0x1]))) 67 {*arm_andsi3_insn} (expr_list:REG_DEAD (reg:SI 174) (nil))) (insn 38 37 39 4 t.c:11 (set (reg:SI 176) (ior:SI (ashift:SI (reg:SI 175) (const_int 1 [0x1])) (reg:SI 178))) 269 {*arith_shiftsi} (expr_list:REG_DEAD (reg:SI 175) (expr_list:REG_DEAD (reg:SI 178) (nil)))) (insn 39 38 40 4 t.c:11 (set (mem/s/j:SI (reg:SI 158 [ ivtmp.16 ]) [0+0 S4 A32]) (reg:SI 176)) 166 {*arm_movsi_insn} (expr_list:REG_DEAD (reg:SI 176) (nil))) -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42972