http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60802
Bug ID: 60802 Summary: jump2 pass fails to do cfgcleanup Product: gcc Version: 4.9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: manjian2006 at gmail dot com problem source: int foo (int *a, int s, int predicate) { if (predicate > 0) { for (int i = 0; i < s; ++i) { a[i] = 0xfafafafa; } } else if (predicate == 0) { for (int i = 0; i < s; ++i) { a[i] = 0xfcfcfcfc; } } else { for (int i = 0; i < s; ++i) { a[i] = 0xf2f2f2f2; } } return predicate; } compiles with -O3 -S output assembly: .L2: .cfi_restore_state jne .L10 testl %esi, %esi jle .L7 subl $1, %esi leaq 4(,%rsi,4), %rdx movl $252, %esi => call memset movl %ebx, %eax popq %rbx .cfi_remember_state .cfi_def_cfa_offset 8 ret .p2align 4,,10 .p2align 3 .L10: .cfi_restore_state testl %esi, %esi jle .L7 subl $1, %esi leaq 4(,%rsi,4), %rdx movl $242, %esi => call memset movl %ebx, %eax popq %rbx .cfi_def_cfa_offset 8 as we can see duplicate call memset and return assembly has been generated. And I take a look at the output from jump2 pass,and examine the call site of memset: (call_insn 30 28 85 4 (set (reg:DI 0 ax) (call (mem:QI (symbol_ref:DI ("memset") [flags 0x41] <function_decl 0x7fd0daa91d00 __builtin_memset>) [0 memsetD.998 S1 A8]) (const_int 0 [0]))) 649 {*call_value} (expr_list:REG_DEAD (reg:DI 5 di) (expr_list:REG_DEAD (reg:SI 4 si) (expr_list:REG_DEAD (reg:DI 1 dx) (expr_list:REG_UNUSED (reg:DI 0 ax) (expr_list:REG_EH_REGION (const_int 0 [0]) (nil)))))) (expr_list:DI (set (reg:DI 0 ax) (reg:DI 5 di)) (expr_list:DI (use (reg:DI 5 di)) (expr_list:SI (use (reg:SI 4 si)) (expr_list:DI (use (reg:DI 1 dx)) (nil)))))) (jump_insn 85 30 86 4 (set (pc) (label_ref 84)) 636 {jump} (nil) -> 84) (call_insn 60 58 90 9 (set (reg:DI 0 ax) (call (mem:QI (symbol_ref:DI ("memset") [flags 0x41] <function_decl 0x7fd0daa91d00 __builtin_memset>) [0 memsetD.998 S1 A8]) (const_int 0 [0]))) 649 {*call_value} (expr_list:REG_DEAD (reg:DI 5 di) (expr_list:REG_DEAD (reg:SI 4 si) (expr_list:REG_DEAD (reg:DI 1 dx) (expr_list:REG_UNUSED (reg:DI 0 ax) (expr_list:REG_EH_REGION (const_int 0 [0]) (nil)))))) (expr_list:DI (set (reg:DI 0 ax) (reg:DI 5 di)) (expr_list:DI (use (reg:DI 5 di)) (expr_list:SI (use (reg:SI 4 si)) (expr_list:DI (use (reg:DI 1 dx)) (nil)))))) (jump_insn 90 60 91 9 (set (pc) (label_ref 84)) 636 {jump} (nil) -> 84) (call_insn 76 74 84 10 (set (reg:DI 0 ax) (call (mem:QI (symbol_ref:DI ("memset") [flags 0x41] <function_decl 0x7fd0daa91d00 __builtin_memset>) [0 memsetD.998 S1 A8]) (const_int 0 [0]))) 649 {*call_value} (expr_list:REG_DEAD (reg:DI 5 di) (expr_list:REG_DEAD (reg:SI 4 si) (expr_list:REG_DEAD (reg:DI 1 dx) (expr_list:REG_UNUSED (reg:DI 0 ax) (expr_list:REG_EH_REGION (const_int 0 [0]) (nil)))))) (expr_list:DI (set (reg:DI 0 ax) (reg:DI 5 di)) (expr_list:DI (use (reg:DI 5 di)) (expr_list:SI (use (reg:SI 4 si)) (expr_list:DI (use (reg:DI 1 dx)) (nil)))))) three call sites have the identical content,and jump to the same basic block after calls.So it may be combine as one.