Bug 99373 - unused static function not being removed in some cases after optimization
Summary: unused static function not being removed in some cases after optimization
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: ipa (show other bugs)
Version: 11.0
: P3 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: missed-optimization
Depends on:
Blocks:
 
Reported: 2021-03-03 23:11 UTC by Zhendong Su
Modified: 2023-01-10 18:25 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2021-03-04 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Zhendong Su 2021-03-03 23:11:23 UTC
[538] % gcctk -v
Using built-in specs.
COLLECT_GCC=gcctk
COLLECT_LTO_WRAPPER=/local/suz-local/software/local/gcc-trunk/libexec/gcc/x86_64-pc-linux-gnu/11.0.1/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ../gcc-trunk/configure --disable-bootstrap --prefix=/local/suz-local/software/local/gcc-trunk --enable-languages=c,c++ --disable-werror --enable-multilib --with-system-zlib
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 11.0.1 20210303 (experimental) [master revision d97a92dca90:bc15d73426f:9b2084db9f9917eb9b19b1eb5ec03cdcb05f349e] (GCC) 
[539] % 
[539] % gcctk -O3 -S -o small.s small.c
[540] % 
[540] % cat small.c
extern void foo();

struct a {
  int b;
  long c;
} g;
static int d = 1;
int e, *f, *h;
long *i;

static long j() {
  struct a k;
  struct a *m = &g;
  struct a **n[] = {&m};
  long **l = 0;
  int o[42];
  foo();
  int p[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
  int *d[] = {&p[3]};
  i = &k.c;
  long ***a[] = {&l};
  int b[5];
  f = &b[3];
  if (e)
    while (1)
      h = &o[7];
  return 0;
}
int main() {
  d || j();
  return 0;
}
[541] % 
[541] % cat small.s
	.file	"small.c"
	.text
	.p2align 4
	.type	j.isra.0, @function
j.isra.0:
.LFB2:
	.cfi_startproc
	subq	$56, %rsp
	.cfi_def_cfa_offset 64
	xorl	%eax, %eax
	call	foo
	leaq	8(%rsp), %rax
	movq	%rax, i(%rip)
	leaq	28(%rsp), %rax
	movq	%rax, f(%rip)
	movl	e(%rip), %eax
	testl	%eax, %eax
	jne	.L3
	addq	$56, %rsp
	.cfi_remember_state
	.cfi_def_cfa_offset 8
	ret
.L3:
	.cfi_restore_state
	jmp	.L3
	.cfi_endproc
.LFE2:
	.size	j.isra.0, .-j.isra.0
	.section	.text.startup,"ax",@progbits
	.p2align 4
	.globl	main
	.type	main, @function
main:
.LFB1:
	.cfi_startproc
	xorl	%eax, %eax
	ret
	.cfi_endproc
.LFE1:
	.size	main, .-main
	.globl	i
	.bss
	.align 8
	.type	i, @object
	.size	i, 8
i:
	.zero	8
	.globl	h
	.align 8
	.type	h, @object
	.size	h, 8
h:
	.zero	8
	.globl	f
	.align 8
	.type	f, @object
	.size	f, 8
f:
	.zero	8
	.globl	e
	.align 4
	.type	e, @object
	.size	e, 4
e:
	.zero	4
	.globl	g
	.align 16
	.type	g, @object
	.size	g, 16
g:
	.zero	16
	.ident	"GCC: (GNU) 11.0.1 20210303 (experimental) [master revision d97a92dca90:bc15d73426f:9b2084db9f9917eb9b19b1eb5ec03cdcb05f349e]"
	.section	.note.GNU-stack,"",@progbits
Comment 1 Richard Biener 2021-03-04 08:44:26 UTC
The issue is only IPA reference promotes 'd' constant and thus only late optimization elides the call to 'j'.  That's too late to eliminate the function.
Note we process 'j' first duing late opts (to make the late local IPA pure-const
useful).

We'd need another IPA phase before RTL expansion to collect unreachable functions again (IIRC the original parallel compilation GSoC project added one).

I'm also quite sure we have a duplicate of this PR.
Comment 2 Zhendong Su 2021-03-05 00:00:46 UTC
The following might be the same/related. The dead call is eliminated if b is changed to:

static int b(int *c) {
    foo();
    d++;
}

[623] % gcctk -O3 -S small.c
[624] %
[624] % cat small.c
extern void foo(void);

static int a, d;

static int b(int *c) {
  while (1) {
    foo();
    d++;
  }
}

int main () {
  a && b(&a);
  return 0;
}
[625] %
[625] % cat small.s
        .file   "small.c"
        .text
        .section        .text.startup,"ax",@progbits
        .p2align 4
        .globl  main
        .type   main, @function
main:
.LFB1:  
        .cfi_startproc
        movl    a(%rip), %edx
        testl   %edx, %edx
        jne     .L7
        xorl    %eax, %eax
        ret
.L7:
        pushq   %rax
        .cfi_def_cfa_offset 16
.L3:
        call    foo
        addl    $1, d(%rip)
        jmp     .L3
        .cfi_endproc
.LFE1:  
        .size   main, .-main
        .local  d
        .comm   d,4,4
        .local  a
        .comm   a,4,4
        .ident  "GCC: (GNU) 11.0.1 20210304 (experimental) [master revision cdfc2f6a6dc:ab3cea6cccd:f3641ac70eb0ae9f8983b7ddb1660c92439565de]"
        .section        .note.GNU-stack,"",@progbits
Comment 3 Andrew Pinski 2023-01-10 18:25:18 UTC
*** Bug 108361 has been marked as a duplicate of this bug. ***