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.

Reply via email to