Question about the example of link time optimization

Hi all!

I played around with the LLVM LTO
example(https://llvm.org/docs/LinkTimeOptimization.html#example-of-link-time-optimization),
but got some questions.

As the document says, the function foo4 should be removed. However,
under my test, function foo4 is not removed.
I have tried both gnu ld with LLVMgold.so and lld, neither of them
removes function foo4.

I compile and run the example as instructed:
% clang -flto -c a.c -o a.o # <-- a.o is LLVM bitcode file
% clang -c main.c -o main.o # <-- main.o is native object file
% clang -flto a.o main.o -o main # <-- standard link command with -flto
% readelf -sW ./main | awk '$4 == "FUNC"'
     1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND
printf@GLIBC_2.2.5 (2)
     2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND
__libc_start_main@GLIBC_2.2.5 (2)
    27: 0000000000400440 0 FUNC LOCAL DEFAULT 13 deregister_tm_clones
    28: 0000000000400470 0 FUNC LOCAL DEFAULT 13 register_tm_clones
    29: 00000000004004b0 0 FUNC LOCAL DEFAULT 13 __do_global_dtors_aux
    32: 00000000004004e0 0 FUNC LOCAL DEFAULT 13 frame_dummy
    43: 00000000004005c0 2 FUNC GLOBAL DEFAULT 13 __libc_csu_fini
    46: 00000000004005c4 0 FUNC GLOBAL DEFAULT 14 _fini
    47: 0000000000000000 0 FUNC GLOBAL DEFAULT UND printf@@GLIBC_2.2.5
    48: 0000000000400510 23 FUNC GLOBAL DEFAULT 13 foo4
    49: 0000000000000000 0 FUNC GLOBAL DEFAULT UND
__libc_start_main@@GLIBC_2.2.5
    54: 0000000000400550 101 FUNC GLOBAL DEFAULT 13 __libc_csu_init
    56: 0000000000400430 2 FUNC GLOBAL HIDDEN 13
_dl_relocate_static_pie
    57: 0000000000400400 43 FUNC GLOBAL DEFAULT 13 _start
    59: 0000000000400530 26 FUNC GLOBAL DEFAULT 13 main
    60: 00000000004004f0 25 FUNC GLOBAL DEFAULT 13 foo1
    62: 00000000004003c8 0 FUNC GLOBAL DEFAULT 11 _init

Is there something that I'm doing wrong?

Here is the source code of a.c and main.c:
--- a.h ---
extern int foo1(void);
extern void foo2(void);
extern void foo4(void);

--- a.c ---
#include "a.h"

static signed int i = 0;

void foo2(void) {
  i = -1;
}

static int foo3() {
  foo4();
  return 10;
}

int foo1(void) {
  int data = 0;

  if (i < 0)
    data = foo3();

  data = data + 42;
  return data;
}

--- main.c ---
#include <stdio.h>
#include "a.h"

void foo4(void) {
  printf("Hi\n");
}

int main() {
  return foo1();
}

Thanks!
Xu Mingjie

I think you also need to build main.c with -flto.

Cheers,
Florian

More details: main.o is a regular object file. The symbols referenced
(foo4) need to be exported by LTO: the 'VisibileToRegularObj' property
of foo4 is true because foo4's isUsedInRegularObj is true.