I'm seeing miscompilation of newlib's memcmp() for my 16-bit ix86 port. The REG_RETVAL and REG_LIBCALL notes seem to play an important part in the failure. From the first subreg dump:
;; Function memcmp (memcmp) ; Splitting reg 73 -> 89 90 ; Splitting reg 74 -> 91 92 ; Splitting reg 75 -> 93 94 [cut] (insn 58 151 59 3 memcmp.c:81 (set (reg:HI 91) (const_int 3 [0x3])) 23 {*movhi} (nil) (nil)) (insn 59 58 63 3 memcmp.c:81 (set (reg:HI 92 [+2 ]) (const_int 0 [0x0])) 23 {*movhi} (nil) (nil)) (insn 63 59 152 3 memcmp.c:81 (clobber (reg:HI 93)) -1 (nil) (insn_list:REG_LIBCALL 62 (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)) ]) 120 {*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)) ]) 120 {*andhi3} (nil) (insn_list:REG_RETVAL 63 (nil))) (insn 64 62 65 3 memcmp.c:81 (set (reg:HI 76) (reg:HI 93)) 23 {*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)) ]) 122 {*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]))) 481 {*cmphi_const0_cc} (nil) (nil)) CSE comes along, notices that insn 62 just sets reg 94 to zero. Reg 94, btw, isn't used after insn 65. ;; Function memcmp (memcmp) [cut] (insn 58 151 59 3 memcmp.c:81 (set (reg:HI 91) (const_int 3 [0x3])) 23 {*movhi} (nil) (nil)) (insn 59 58 63 3 memcmp.c:81 (set (reg:HI 92 [+2 ]) (const_int 0 [0x0])) 23 {*movhi} (nil) (nil)) (insn 63 59 152 3 memcmp.c:81 (clobber (reg:HI 93)) -1 (nil) (insn_list:REG_LIBCALL 62 (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)) ]) 120 {*andhi3} (nil) (nil)) (insn 62 61 64 3 memcmp.c:81 (set (reg:HI 94 [+2 ]) (reg:HI 92 [+2 ])) 23 {*movhi} (nil) (expr_list:REG_EQUAL (const_int 0 [0x0]) (insn_list:REG_RETVAL 63 (nil)))) (insn 64 62 65 3 memcmp.c:81 (set (reg:HI 76) (reg:HI 93)) 23 {*movhi} (nil) (nil)) (insn 65 64 66 3 memcmp.c:81 (set (reg:HI 76) (reg:HI 93)) 23 {*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]))) 481 {*cmphi_const0_cc} (nil) (nil)) Notice that we now have both a REG_EQUAL and a REG_RETVAL note on insn 62. It isn't until the loop2_done dump that the problem shows up. delete_trivially_dead_insns() is called. It calls dead_libcall_p() on insn 62 and seeing both the REQ_EQUAL and the REG_RETVAL note and successfully replacing reg 92 with const_int 0, determines that the while libcall sequence 63-152-61-62 is dead and can be deleted, without ever checking insns 63, 152 or 61 for liveness. The result is disaster: ;; Function memcmp (memcmp) [cut] Register 91 used 1 times across 0 insns; set 1 time; dies in 0 places. Register 92 used 1 times across 0 insns; set 1 time; dies in 0 places. Register 95 used 1 times across 0 insns; set 1 time; dies in 0 places. Register 96 used 1 times across 0 insns; set 1 time; dies in 0 places. [cut - why is register 93 not listed?] (insn 60 56 151 3 memcmp.c:81 (clobber (reg:HI 91)) -1 (nil) (nil)) (insn 151 60 66 3 memcmp.c:81 (clobber (reg:HI 92 [+2 ])) -1 (nil) (nil)) (insn 66 151 67 3 memcmp.c:81 (set (reg:CC 13 cc) (compare:CC (reg:HI 93) (const_int 0 [0x0]))) 481 {*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))) 561 {*bne_cc} (nil) (expr_list:REG_BR_PROB (const_int 5000 [0x1388]) (nil))) -- Rask Ingemann Lambertsen