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.