All CallInsts mayHaveSideEffects


All CallInsts should return true for Instruction::mayHaveSideEffects() because functions are not guaranteed to halt.

Inliner::runOnSCC calls isInstructionTriviallyDead to determine whether code can be dead code eliminated. isInstructionTriviallyDead returns true if Instruction::mayHaveSideEffects() returns false. A function that potentially runs forever based on its input but does not write to memory will be dead code eliminated when the Inliner runs.

Here is a simple example of how things can go horribly wrong:

#include <stdio.h>
#include <stdlib.h>

void inf(void) {

int main(int argc, char **argv) {
  return 0;

void foo(void) {
  printf("Hello world!\n");

For recent versions of clang (svn rev 102637) when compiled with -O1 or higher the result is:
Hello world!

The reason is that LLVM annotates inf as noreturn, so the ret instruction at the end of main is replaced with unreachable. Then the inf function is dead-code eliminated by the Inliner pass. Thus main will consist of a single unreachable instruction, which allows control to fall through to the foo function.

My suggested patch is as follows:

Index: include/llvm/Instruction.h

This is a known bug:

There has been some discussion about it and similar problems, and the
desire is to perform some analysis on functions to determine if they
are known to halt trivially, ie they have no loops and call no other
functions that are not known to halt.

LLVM still wants to be able to delete calls to trivial read-only functions.