[llvm-dev] Why does an LLVM pass based on FunctionPass not get triggered for certain functions?

Dipanjan Das via llvm-dev llvm-dev at lists.llvm.org
Sat Apr 15 15:42:00 PDT 2017

I am learning to write LLVM pass by trying to reproduce [hello world][1]
example. The pass `hello.cpp` looks like:

    #include "llvm/Pass.h"
    #include "llvm/IR/Function.h"
    #include "llvm/Support/raw_ostream.h"

    using namespace llvm;

    namespace {
      struct Hello : public FunctionPass {
        static char ID;
        Hello() : FunctionPass(ID) {}

        bool runOnFunction(Function &F) override {
          errs() << "Hello: ";
          errs().write_escaped(F.getName()) << '\n';
          return false;

    char Hello::ID = 0;9
    static RegisterPass<Hello> X("hello", "Hello World Pass", false, false);

The sample program `world.c` looks like:

    #include <stdio.h>

    int main() {
    printf("Hello World\n");
    return 0;

The program is compiled using the following command line: `clang world.c -c
-emit-llvm -O3 -o world.bc`

The bitcode produced by `llvm-dis` looks like:

    ; ModuleID = 'src/hello.bc'
    target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
    target triple = "x86_64-unknown-linux-gnu"

    @str = private unnamed_addr constant [12 x i8] c"Hello World\00"

    ; Function Attrs: nounwind uwtable
    define i32 @main() #0 {
      %puts = tail call i32 @puts(i8* getelementptr inbounds ([12 x i8],
[12 x i8]* @str, i64 0, i64 0))
      ret i32 0

    ; Function Attrs: nounwind
    declare i32 @puts(i8* nocapture) #1

    attributes #0 = { nounwind uwtable "disable-tail-calls"="false"
"less-precise-fpmad"="false" "no-frame-pointer-elim"="false"
"no-infs-fp-math"="false" "no-nans-fp-math"="false"
"stack-protector-buffer-size"="8" "target-cpu"="x86-64"
"target-features"="+fxsr,+mmx,+sse,+sse2" "unsafe-fp-math"="false"
"use-soft-float"="false" }
    attributes #1 = { nounwind }

    !llvm.ident = !{!0}

    !0 = !{!"clang version 3.8.0 (tags/RELEASE_380/final)"}

When I run the pass on the bitcode: `opt -load hello/libhello.so -hello
src/world.bc > /dev/null`, the output is:

    Hello: main

However, the [tutorial][2] claims that the output should have been:

    Hello: __main
    Hello: puts
    Hello: main

Why does my pass not get triggered for the first two functions?



Thanks & Regards,
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170415/19c0cfb7/attachment.html>

More information about the llvm-dev mailing list