On Tue, May 08, 2007 at 07:41:55AM -0700, Ian Lance Taylor wrote: > The issue here is that we have a libcall without the REG_EQUAL note. > That is sensible for a REG_NO_CONFLICT block. Normally gcc will only > build REG_NO_CONFLICT blocks for code which lower-subreg can't pick > apart anyhow. Your backend appears to be an exception.
The way the alignment check in the memcmp() function is coded might make a difference: (((long) s1 | (long) s2) & 3) != 0 with char *s1, s2 because the sign extension of s1 and s2 is not decomposable. > This may be the right patch. I have no good way to test it. > > Ian > > Index: lower-subreg.c > =================================================================== > --- lower-subreg.c (revision 124389) > +++ lower-subreg.c (working copy) > @@ -1128,6 +1128,8 @@ decompose_multiword_subregs (bool update > { > changed = true; > > + remove_retval_note (insn); > + > recog_memoized (insn); > extract_insn (insn); > > @@ -1157,6 +1159,8 @@ decompose_multiword_subregs (bool update > i = apply_change_group (); > gcc_assert (i); > > + remove_retval_note (insn); > + > changed = true; > } > } > Your patch seems to work fine. After jump, we have: (insn 51 50 52 3 memcmp.c:81 (set (reg/f:HI 70 [ s2 ]) (reg/v/f:HI 59 [ s2 ])) 24 {*movhi} (nil) (nil)) (insn 52 51 53 3 memcmp.c:81 (set (reg:SI 69 [ s2 ]) (sign_extend:SI (reg/f:HI 70 [ s2 ]))) 508 {*extendhisi2} (nil) (expr_list:REG_EQUAL (sign_extend:SI (reg/v/f:HI 59 [ s2 ])) (nil))) (insn 53 52 54 3 memcmp.c:81 (set (reg/f:HI 72 [ s1 ]) (reg/v/f:HI 60 [ s1 ])) 24 {*movhi} (nil) (nil)) (insn 54 53 57 3 memcmp.c:81 (set (reg:SI 71 [ s1 ]) (sign_extend:SI (reg/f:HI 72 [ s1 ]))) 508 {*extendhisi2} (nil) (expr_list:REG_EQUAL (sign_extend:SI (reg/v/f:HI 60 [ s1 ])) (nil))) (insn 57 54 55 3 memcmp.c:81 (clobber (reg:SI 73)) -1 (nil) (insn_list:REG_LIBCALL 56 (nil))) (insn 55 57 56 3 memcmp.c:81 (parallel [ (set (subreg:HI (reg:SI 73) 0) (ior:HI (subreg:HI (reg:SI 69 [ s2 ]) 0) (subreg:HI (reg:SI 71 [ s1 ]) 0))) (clobber (reg:CC 13 cc)) ]) 123 {*iorhi3} (nil) (expr_list:REG_NO_CONFLICT (reg:SI 69 [ s2 ]) (expr_list:REG_NO_CONFLICT (reg:SI 71 [ s1 ]) (nil)))) (insn 56 55 60 3 memcmp.c:81 (parallel [ (set (subreg:HI (reg:SI 73) 2) (ior:HI (subreg:HI (reg:SI 69 [ s2 ]) 2) (subreg:HI (reg:SI 71 [ s1 ]) 2))) (clobber (reg:CC 13 cc)) ]) 123 {*iorhi3} (nil) (insn_list:REG_RETVAL 57 (expr_list:REG_NO_CONFLICT (reg:SI 69 [ s2 ]) (expr_list:REG_NO_CONFLICT (reg:SI 71 [ s1 ]) (nil))))) (insn 60 56 58 3 memcmp.c:81 (clobber (reg:SI 74)) -1 (nil) (nil)) (insn 58 60 59 3 memcmp.c:81 (set (subreg:HI (reg:SI 74) 0) (const_int 3 [0x3])) 24 {*movhi} (nil) (nil)) (insn 59 58 63 3 memcmp.c:81 (set (subreg:HI (reg:SI 74) 2) (const_int 0 [0x0])) 24 {*movhi} (nil) (nil)) (insn 63 59 61 3 memcmp.c:81 (clobber (reg:SI 75)) -1 (nil) (insn_list:REG_LIBCALL 62 (nil))) (insn 61 63 62 3 memcmp.c:81 (parallel [ (set (subreg:HI (reg:SI 75) 0) (and:HI (subreg:HI (reg:SI 73) 0) (subreg:HI (reg:SI 74) 0))) (clobber (reg:CC 13 cc)) ]) 121 {*andhi3} (nil) (expr_list:REG_NO_CONFLICT (reg:SI 73) (expr_list:REG_NO_CONFLICT (reg:SI 74) (nil)))) (insn 62 61 64 3 memcmp.c:81 (parallel [ (set (subreg:HI (reg:SI 75) 2) (and:HI (subreg:HI (reg:SI 73) 2) (subreg:HI (reg:SI 74) 2))) (clobber (reg:CC 13 cc)) ]) 121 {*andhi3} (nil) (insn_list:REG_RETVAL 63 (expr_list:REG_NO_CONFLICT (reg:SI 73) (expr_list:REG_NO_CONFLICT (reg:SI 74) (nil))))) (insn 64 62 65 3 memcmp.c:81 (set (reg:HI 76) (subreg:HI (reg:SI 75) 0)) 24 {*movhi} (nil) (nil)) (insn 65 64 66 3 memcmp.c:81 (parallel [ (set (reg:HI 76) (ior:HI (reg:HI 76) (subreg:HI (reg:SI 75) 2))) (clobber (reg:CC 13 cc)) ]) 123 {*iorhi3} (nil) (nil)) (insn 66 65 67 3 memcmp.c:81 (set (reg:CC 13 cc) (compare:CC (reg:HI 76) (const_int 0 [0x0]))) 482 {*cmphi_const0_cc} (nil) (nil)) (jump_insn 67 66 68 3 memcmp.c:81 (set (pc) (if_then_else (ne (reg:CC 13 cc) (const_int 0 [0x0])) (label_ref 93) (pc))) 562 {*bne_cc} (nil) (expr_list:REG_BR_PROB (const_int 5000 [0x1388]) (nil))) After subreg: ;; Function memcmp (memcmp) ; Splitting reg 73 -> 89 90 ; Splitting reg 74 -> 91 92 ; Splitting reg 75 -> 93 94 [snip] (insn 51 50 52 3 memcmp.c:81 (set (reg/f:HI 70 [ s2 ]) (reg/v/f:HI 59 [ s2 ])) 24 {*movhi} (nil) (nil)) (insn 52 51 53 3 memcmp.c:81 (set (reg:SI 69 [ s2 ]) (sign_extend:SI (reg/f:HI 70 [ s2 ]))) 508 {*extendhisi2} (nil) (expr_list:REG_EQUAL (sign_extend:SI (reg/v/f:HI 59 [ s2 ])) (nil))) (insn 53 52 54 3 memcmp.c:81 (set (reg/f:HI 72 [ s1 ]) (reg/v/f:HI 60 [ s1 ])) 24 {*movhi} (nil) (nil)) (insn 54 53 57 3 memcmp.c:81 (set (reg:SI 71 [ s1 ]) (sign_extend:SI (reg/f:HI 72 [ s1 ]))) 508 {*extendhisi2} (nil) (expr_list:REG_EQUAL (sign_extend:SI (reg/v/f:HI 60 [ s1 ])) (nil))) (insn 57 54 150 3 memcmp.c:81 (clobber (reg:HI 89)) -1 (nil) (nil)) (insn 150 57 55 3 memcmp.c:81 (clobber (reg:HI 90 [+2 ])) -1 (nil) (nil)) (insn 55 150 56 3 memcmp.c:81 (parallel [ (set (reg:HI 89) (ior:HI (subreg:HI (reg:SI 69 [ s2 ]) 0) (subreg:HI (reg:SI 71 [ s1 ]) 0))) (clobber (reg:CC 13 cc)) ]) 123 {*iorhi3} (nil) (nil)) (insn 56 55 60 3 memcmp.c:81 (parallel [ (set (reg:HI 90 [+2 ]) (ior:HI (subreg:HI (reg:SI 69 [ s2 ]) 2) (subreg:HI (reg:SI 71 [ s1 ]) 2))) (clobber (reg:CC 13 cc)) ]) 123 {*iorhi3} (nil) (expr_list:REG_NO_CONFLICT (reg:SI 69 [ s2 ]) (expr_list:REG_NO_CONFLICT (reg:SI 71 [ s1 ]) (nil)))) (insn 60 56 151 3 memcmp.c:81 (clobber (reg:HI 91)) -1 (nil) (nil)) (insn 151 60 58 3 memcmp.c:81 (clobber (reg:HI 92 [+2 ])) -1 (nil) (nil)) (insn 58 151 59 3 memcmp.c:81 (set (reg:HI 91) (const_int 3 [0x3])) 24 {*movhi} (nil) (nil)) (insn 59 58 63 3 memcmp.c:81 (set (reg:HI 92 [+2 ]) (const_int 0 [0x0])) 24 {*movhi} (nil) (nil)) (insn 63 59 152 3 memcmp.c:81 (clobber (reg:HI 93)) -1 (nil) (nil)) (insn 152 63 61 3 memcmp.c:81 (clobber (reg:HI 94 [+2 ])) -1 (nil) (nil)) (insn 61 152 62 3 memcmp.c:81 (parallel [ (set (reg:HI 93) (and:HI (reg:HI 89) (reg:HI 91))) (clobber (reg:CC 13 cc)) ]) 121 {*andhi3} (nil) (nil)) (insn 62 61 64 3 memcmp.c:81 (parallel [ (set (reg:HI 94 [+2 ]) (and:HI (reg:HI 90 [+2 ]) (reg:HI 92 [+2 ]))) (clobber (reg:CC 13 cc)) ]) 121 {*andhi3} (nil) (nil)) (insn 64 62 65 3 memcmp.c:81 (set (reg:HI 76) (reg:HI 93)) 24 {*movhi} (nil) (nil)) (insn 65 64 66 3 memcmp.c:81 (parallel [ (set (reg:HI 76) (ior:HI (reg:HI 76) (reg:HI 94 [+2 ]))) (clobber (reg:CC 13 cc)) ]) 123 {*iorhi3} (nil) (nil)) (insn 66 65 67 3 memcmp.c:81 (set (reg:CC 13 cc) (compare:CC (reg:HI 76) (const_int 0 [0x0]))) 482 {*cmphi_const0_cc} (nil) (nil)) (jump_insn 67 66 68 3 memcmp.c:81 (set (pc) (if_then_else (ne (reg:CC 13 cc) (const_int 0 [0x0])) (label_ref 93) (pc))) 562 {*bne_cc} (nil) (expr_list:REG_BR_PROB (const_int 5000 [0x1388]) (nil))) CSE makes a few cleanups: (insn 51 50 52 3 memcmp.c:81 (set (reg/f:HI 70 [ s2 ]) (reg/v/f:HI 59 [ s2 ])) 24 {*movhi} (nil) (nil)) (insn 52 51 53 3 memcmp.c:81 (set (reg:SI 69 [ s2 ]) (sign_extend:SI (reg/v/f:HI 59 [ s2 ]))) 508 {*extendhisi2} (nil) (expr_list:REG_EQUAL (sign_extend:SI (reg/v/f:HI 59 [ s2 ])) (nil))) (insn 53 52 54 3 memcmp.c:81 (set (reg/f:HI 72 [ s1 ]) (reg/v/f:HI 60 [ s1 ])) 24 {*movhi} (nil) (nil)) (insn 54 53 57 3 memcmp.c:81 (set (reg:SI 71 [ s1 ]) (sign_extend:SI (reg/v/f:HI 60 [ s1 ]))) 508 {*extendhisi2} (nil) (expr_list:REG_EQUAL (sign_extend:SI (reg/v/f:HI 60 [ s1 ])) (nil))) (insn 57 54 150 3 memcmp.c:81 (clobber (reg:HI 89)) -1 (nil) (nil)) (insn 150 57 55 3 memcmp.c:81 (clobber (reg:HI 90 [+2 ])) -1 (nil) (nil)) (insn 55 150 56 3 memcmp.c:81 (parallel [ (set (reg:HI 89) (ior:HI (subreg:HI (reg:SI 69 [ s2 ]) 0) (subreg:HI (reg:SI 71 [ s1 ]) 0))) (clobber (reg:CC 13 cc)) ]) 123 {*iorhi3} (nil) (nil)) (insn 56 55 60 3 memcmp.c:81 (parallel [ (set (reg:HI 90 [+2 ]) (ior:HI (subreg:HI (reg:SI 69 [ s2 ]) 2) (subreg:HI (reg:SI 71 [ s1 ]) 2))) (clobber (reg:CC 13 cc)) ]) 123 {*iorhi3} (nil) (expr_list:REG_NO_CONFLICT (reg:SI 69 [ s2 ]) (expr_list:REG_NO_CONFLICT (reg:SI 71 [ s1 ]) (nil)))) (insn 60 56 151 3 memcmp.c:81 (clobber (reg:HI 91)) -1 (nil) (nil)) (insn 151 60 58 3 memcmp.c:81 (clobber (reg:HI 92 [+2 ])) -1 (nil) (nil)) (insn 58 151 59 3 memcmp.c:81 (set (reg:HI 91) (reg:HI 68)) 24 {*movhi} (nil) (expr_list:REG_EQUAL (const_int 3 [0x3]) (nil))) (insn 59 58 63 3 memcmp.c:81 (set (reg:HI 92 [+2 ]) (const_int 0 [0x0])) 24 {*movhi} (nil) (nil)) (insn 63 59 152 3 memcmp.c:81 (clobber (reg:HI 93)) -1 (nil) (nil)) (insn 152 63 61 3 memcmp.c:81 (clobber (reg:HI 94 [+2 ])) -1 (nil) (nil)) (insn 61 152 62 3 memcmp.c:81 (parallel [ (set (reg:HI 93) (and:HI (reg:HI 89) (reg:HI 68))) (clobber (reg:CC 13 cc)) ]) 121 {*andhi3} (nil) (nil)) (insn 62 61 64 3 memcmp.c:81 (set (reg:HI 94 [+2 ]) (reg:HI 92 [+2 ])) 24 {*movhi} (nil) (expr_list:REG_EQUAL (const_int 0 [0x0]) (nil))) (insn 64 62 65 3 memcmp.c:81 (set (reg:HI 76) (reg:HI 93)) 24 {*movhi} (nil) (nil)) (insn 65 64 66 3 memcmp.c:81 (set (reg:HI 76) (reg:HI 93)) 24 {*movhi} (nil) (nil)) (insn 66 65 67 3 memcmp.c:81 (set (reg:CC 13 cc) (compare:CC (reg:HI 93) (const_int 0 [0x0]))) 482 {*cmphi_const0_cc} (nil) (nil)) (jump_insn 67 66 68 3 memcmp.c:81 (set (pc) (if_then_else (ne (reg:CC 13 cc) (const_int 0 [0x0])) (label_ref 93) (pc))) 562 {*bne_cc} (nil) (expr_list:REG_BR_PROB (const_int 5000 [0x1388]) (nil))) Several instructions are deleted by fwprop1: (insn 52 50 54 3 memcmp.c:81 (set (reg:SI 69 [ s2 ]) (sign_extend:SI (reg/v/f:HI 66 [ m2 ]))) 508 {*extendhisi2} (nil) (expr_list:REG_EQUAL (sign_extend:SI (reg/v/f:HI 66 [ m2 ])) (nil))) (insn 54 52 57 3 memcmp.c:81 (set (reg:SI 71 [ s1 ]) (sign_extend:SI (reg/v/f:HI 65 [ m1 ]))) 508 {*extendhisi2} (nil) (expr_list:REG_EQUAL (sign_extend:SI (reg/v/f:HI 65 [ m1 ])) (nil))) (insn 57 54 150 3 memcmp.c:81 (clobber (reg:HI 89)) -1 (nil) (nil)) (insn 150 57 55 3 memcmp.c:81 (clobber (reg:HI 90 [+2 ])) -1 (nil) (nil)) (insn 55 150 60 3 memcmp.c:81 (parallel [ (set (reg:HI 89) (ior:HI (subreg:HI (reg:SI 69 [ s2 ]) 0) (subreg:HI (reg:SI 71 [ s1 ]) 0))) (clobber (reg:CC 13 cc)) ]) 123 {*iorhi3} (nil) (nil)) (insn 60 55 151 3 memcmp.c:81 (clobber (reg:HI 91)) -1 (nil) (nil)) (insn 151 60 63 3 memcmp.c:81 (clobber (reg:HI 92 [+2 ])) -1 (nil) (nil)) (insn 63 151 152 3 memcmp.c:81 (clobber (reg:HI 93)) -1 (nil) (nil)) (insn 152 63 61 3 memcmp.c:81 (clobber (reg:HI 94 [+2 ])) -1 (nil) (nil)) (insn 61 152 66 3 memcmp.c:81 (parallel [ (set (reg:HI 93) (and:HI (reg:HI 89) (const_int 3 [0x3]))) (clobber (reg:CC 13 cc)) ]) 121 {*andhi3} (nil) (nil)) (insn 66 61 67 3 memcmp.c:81 (set (reg:CC 13 cc) (compare:CC (reg:HI 93) (const_int 0 [0x0]))) 482 {*cmphi_const0_cc} (nil) (nil)) (jump_insn 67 66 68 3 memcmp.c:81 (set (pc) (if_then_else (ne (reg:CC 13 cc) (const_int 0 [0x0])) (label_ref 93) (pc))) 562 {*bne_cc} (nil) (expr_list:REG_BR_PROB (const_int 5000 [0x1388]) (nil))) Not much happens until combine produces this: (note 52 50 54 3 NOTE_INSN_DELETED) (note 54 52 55 3 NOTE_INSN_DELETED) (insn 55 54 61 3 memcmp.c:81 (parallel [ (set (reg:HI 89) (ior:HI (reg/v/f:HI 59 [ s2 ]) (reg/v/f:HI 60 [ s1 ]))) (clobber (reg:CC 13 cc)) ]) 123 {*iorhi3} (nil) (expr_list:REG_UNUSED (reg:CC 13 cc) (nil))) (note 61 55 66 3 NOTE_INSN_DELETED) (insn 66 61 67 3 memcmp.c:81 (set (reg:CCZ 13 cc) (compare:CCZ (zero_extract:HI (reg:HI 89) (const_int 2 [0x2]) (const_int 0 [0x0])) (const_int 0 [0x0]))) 506 {*extzvhi_cconly_ccz} (insn_list:REG_DEP_TRUE 55 (nil)) (expr_list:REG_DEAD (reg:HI 89) (nil))) (jump_insn 67 66 68 3 memcmp.c:81 (set (pc) (if_then_else (ne (reg:CCZ 13 cc) (const_int 0 [0x0])) (label_ref 93) (pc))) 556 {*bne_ccz} (insn_list:REG_DEP_TRUE 66 (nil)) (expr_list:REG_DEAD (reg:CC 13 cc) (expr_list:REG_BR_PROB (const_int 5000 [0x1388]) (nil)))) Which looks good. -- Rask Ingemann Lambertsen