<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - llc removes instrumented function call"
   href="https://bugs.llvm.org/show_bug.cgi?id=50395">50395</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>llc removes instrumented function call
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>tools
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>11.0
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>llc
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>peterrong96@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Created <span class=""><a href="attachment.cgi?id=24871" name="attach_24871" title="Example code for bug reproduce, may also find in https://github.com/DataCorrupted/llc-func-removal-report">attachment 24871</a> <a href="attachment.cgi?id=24871&action=edit" title="Example code for bug reproduce, may also find in https://github.com/DataCorrupted/llc-func-removal-report">[details]</a></span>
Example code for bug reproduce, may also find in
<a href="https://github.com/DataCorrupted/llc-func-removal-report">https://github.com/DataCorrupted/llc-func-removal-report</a>

This doc and reproduce code can be found
[here](<a href="https://github.com/DataCorrupted/llc-func-removal-report">https://github.com/DataCorrupted/llc-func-removal-report</a>)

# llc function call removal bug

## Summary

When instrumenting function calls, all of them are instrumented correctly in
LLVM IR.
But __SOME__ of the function calls are removed when generating assembly(before
linking).
These function calls are in 3rd party library and are not present until
linking, therefore, they shouldn't be optimized out.
I couldn't figure out what is the criteria for such removal.

## Scope

The bug can be reproduced in Ubuntu 1604 and 1804, using any LLVM > 10.0.0.

The demo included uses a docker environment for easier debugging, it runs in
Ubuntu 1604 and LLVM 11.1.0.

## Reproduce

To reproduce, you may run `./scripts/reproduce.sh`.
It would compile a docker image and run the code.

Or you can do 

```sh
# If you don't have llvm in your local machine
./scripts/install_llvm.sh
./scripts/build.sh
cd src
make test
```

The final lines of output should look like this:

```
llvm-dis ./build/bin/main.0.5.precodegen.bc 
dummy_func calls in bitcode before assembly generation: 
  %11 = call i8 @dummy_func_getc()
  %19 = call i8 @dummy_func_getc()
  %25 = call i8 @dummy_func_icmp()
declare i8 @dummy_func_icmp() #3
declare i8 @dummy_func_getc() #3

llc ./build/bin/main.0.5.precodegen.bc 
dummy_func calls after assembly generation: 
        callq   dummy_func_getc

When executing main: 
dummy_func called before _IO_getc().

When executing main-pm: 
dummy_func called before _IO_getc().
```

Indicating that 3 function calls are inserted to LLVM IR, only one remains in
assembly and binary.

## Code description

The example code here shows one example.
The pass is fairly simple, for each ICMP instruction, instrument a function
call to `dummy_func_icmp` beforehand; for `getc` function call, instrument a
call to `dummy_func_getc`.

Both `char dummy_func_*()` functions are copmiled into a 3rd library and linked
to the program later.
These functions, as name suggests, does nothing except printing out a statement
saying that it is executed.
(I think having IO in these functions makes them impossible to be optimized
out.)

The `main.c` only gets two bytes from `stdin`, allocate a buffer and does some
ICMP.

When instrumenting code in `src`, LLVM IR shows that two `dummy_func_getc` and
one `dummy_func_icmp` are instrumented correctly.
But when generating assembly using `llc` and executing final binary, only one
`dummy_func_getc` is preserved.

## Thoughts

Here are some possible reasons that I have ruled as impossible.

1. It's the asssembler's optimizer. However, the assembler hasn't seen what
`dummy_func*` looks like, so there is no reason it should remove a 3rd library
function call.
2. It's LTO. I used LTO for easier bitcode and assembly generation, as shown in
`make main-pm`, even use legacy pass mamager in earlier stages, the generated
binray still only have ONE instrumented function instead of three.</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>