https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110089
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |uros at gcc dot gnu.org --- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> --- That said, writing it the way the vectorizer currently emits it is void bar (); void foo (unsigned int n, unsigned s) { unsigned oldn; do { bar (n % s); oldn = n; n = n - s; } while (oldn > s); } which results in (on x86): .L2: movl %ebx, %eax xorl %edx, %edx divl %ebp xorl %eax, %eax movl %edx, %edi call bar movl %ebx, %eax subl %ebp, %ebx cmpl %eax, %ebp jb .L2 where the sub and the cmp should be combinable. combine sees the following but it doesn't try 12 -> 13 (since we set 84 in 13 which is used in 12) and thus also not 12 -> 13 -> 15. Also there's no "combine" incentive for this since the 15 doesn't use 84 (12 -> 15 fails). (insn 12 11 13 3 (set (reg/v:SI 83 [ n ]) (reg/v:SI 84 [ n ])) 89 {*movsi_internal} (nil)) (insn 13 12 15 3 (parallel [ (set (reg/v:SI 84 [ n ]) (minus:SI (reg/v:SI 84 [ n ]) (reg/v:SI 85 [ s ]))) (clobber (reg:CC 17 flags)) ]) "t.c":9:9 330 {*subsi_1} (expr_list:REG_UNUSED (reg:CC 17 flags) (nil))) (insn 15 13 16 3 (set (reg:CC 17 flags) (compare:CC (reg/v:SI 85 [ s ]) (reg/v:SI 83 [ n ]))) "t.c":11:15 discrim 1 11 {*cmpsi_1} (expr_list:REG_DEAD (reg/v:SI 83 [ n ]) (nil))) (jump_insn 16 15 17 3 (set (pc) (if_then_else (ltu (reg:CC 17 flags) (const_int 0 [0])) (label_ref:DI 14) (pc))) "t.c":11:15 discrim 1 1002 {*jcc} (expr_list:REG_DEAD (reg:CC 17 flags) (int_list:REG_BR_PROB 955630228 (nil))) cmpelim sees basically the same IL: (insn 12 11 13 3 (set (reg/v:SI 0 ax [orig:83 n ] [83]) (reg/v:SI 3 bx [orig:84 n ] [84])) 89 {*movsi_internal} (nil)) (insn 13 12 15 3 (parallel [ (set (reg/v:SI 3 bx [orig:84 n ] [84]) (minus:SI (reg/v:SI 3 bx [orig:84 n ] [84]) (reg/v:SI 6 bp [orig:85 s ] [85]))) (clobber (reg:CC 17 flags)) ]) "t.c":9:9 330 {*subsi_1} (nil)) (insn 15 13 16 3 (set (reg:CC 17 flags) (compare:CC (reg/v:SI 6 bp [orig:85 s ] [85]) (reg/v:SI 0 ax [orig:83 n ] [83]))) "t.c":11:15 discrim 1 11 {*cmpsi_1} (nil)) (jump_insn 16 15 25 3 (set (pc) (if_then_else (ltu (reg:CC 17 flags) (const_int 0 [0])) (label_ref:DI 14) (pc))) "t.c":11:15 discrim 1 1002 {*jcc}