strict aliasing and LLVM

2010/10/29 Rafael Espíndola <rafael.espindola@gmail.com>

clang -x c foo.c -emit-llvm-bc -o /tmp/llvm_JnS1o8/foo.bc
(.text+0x20): undefined reference to `main’
collect2: ld returned 1 exit status
clang: error: linker (via gcc) command failed with exit code 1 (use -v to
see invocation)

Without a -c I think clang is trying to link the llvm IL file. For
that to work you would need a linker that understands LLVM IL. Both
the apple linker and gold support plugins for doing it.

Then it looks like a bug in llvmc driver – -c is not passed to clang.

I strongly recommend not using llvmc unless you know exactly what you’re doing and what the features and limitations of llvmc are. Please use the clang driver.

Is llvmc just a wrapper on top of llvm-gcc and clang? In search of a way to pass down internal llvm options ( I did not know about -m yet), I found that llvmc has -Wo, option (which does not work), that is why I tried it. So many different driver programs makes it little confusing to newbies.

Thanks,

David

Dan Gohman wrote:

Xinliang David Li wrote:

As simple as

void foo (int n, double *p, int *q)
{
    for (int i = 0; i< n; i++)
      *p += *q;
}

clang -O2 -fstrict-aliasing -emit-llvm -o foo.bc -c foo.c
llc -enable-tbaa -O2 -filetype=asm -o foo.s foo.bc

There's a couple things interacting here:
* clang -fstrict-aliasing -O2 does generate the TBAA info, but it runs the optimizers without enabling the -enable-tbaa flag, so the optimizers never look at it. Oops.
* clang -fstrict-aliasing -O0 does *not* generate the TBAA info in the resulting .bc file. This is probably intended to speed up -O0 builds even if -fstrict-aliasing is set, but is annoying for debugging what's going on under the hood.
* If clang -O2 worked by running 'opt' and 'llc' under the hood, we could tell it to pass a flag along to them, but it doesn't. As it stands, you can't turn -enable-tbaa on when running clang.

In case there is any confusion, the -enable-tbaa option is temporary. TBAA is
a new feature which is still under development.

That's fine, but we'll need a way to get bitcode with TBAA metadata but without any optimizations having been run. (Maybe -O2 -fstrict-aliasing -mllvm -disable-llvm-optzns?)

Nick

Xinliang David Li wrote:

    Xinliang David Li wrote:

        As simple as

        void foo (int n, double *p, int *q)
        {
            for (int i = 0; i < n; i++)
              *p += *q;
        }

        clang -O2 -fstrict-aliasing -emit-llvm -o foo.bc -c foo.c
        llc -enable-tbaa -O2 -filetype=asm -o foo.s foo.bc

    There's a couple things interacting here:
      * clang -fstrict-aliasing -O2 does generate the TBAA info, but it
    runs the optimizers without enabling the -enable-tbaa flag, so the
    optimizers never look at it. Oops.
      * clang -fstrict-aliasing -O0 does *not* generate the TBAA info in
    the resulting .bc file. This is probably intended to speed up -O0
    builds even if -fstrict-aliasing is set, but is annoying for
    debugging what's going on under the hood.
      * If clang -O2 worked by running 'opt' and 'llc' under the hood,
    we could tell it to pass a flag along to them, but it doesn't. As it
    stands, you can't turn -enable-tbaa on when running clang.

    So, putting that together, one way to do it is:

      clang -O2 -fstrict-aliasing foo.c -flto -c -o foo.bc
      opt -O2 -enable-tbaa foo.bc foo2.bc

    -o foo2.bc

      llc -O2 -enable-tbaa foo2.bc -o foo2.s

    at which point the opt run will hoist the loads into a loop
    preheader. Sadly this runs the LLVM optimizers twice (once in clang
    -O2 and once in opt) which could skew results.

Yes, I verified these steps work, but my head is spinning:

1) does -flto has the same effect as -emit-llvm ? FE emits llvm bitcode
and exit without invoking llvm backend?

Yes, -flto and -emit-llvm are synonyms.

2) why do you need to invoke both opt and llc -- I verified invoking
just llc is also fine.

"llc" is really just codegen; the only optimizations it does are ones that are naturally part of lowering from llvm IR to assembly. For example, that includes another run of loop invariant code motion because some loads may have been added -- such as a load of the GOT pointer -- which weren't there in the IR to be hoisted.

"opt" runs any IR pass. You can ask run a single optimization, for example "opt -licm" or you can run an analysis pass like scalar evolutions with "opt -analyze -scalar-evolution". This is where the bulk of LLVM's optimizations live.

3) more general question -- is opt just a barebone llc without invoking
any llvm passes? So why is there a need for two opt driver?

I think of it as opt transforms .bc -> .bc and llc transforms .bc -> .s.

Nick

Yep; you can do this today. And the -fstrict-aliasing is actually redundant
since it's on by default with -O2.

Dan

llvmc is an experimental wrapper, not part of the normal toolchain. I’m not sure why, but it was used by the PIC16 toolchain (when it was in mainline), it allows defining compiler drivers that don’t follow the GCC command line syntax.

I completely agree that llvmc is confusing. I would certainly agree with its removal from mainline, but it is actively maintained and presumably there is a reason for that :slight_smile:

Lets look at this another way: maybe this is a documentation issue. Did llvmc’s existence make you want to use it, or was there some documentation that pushed you in that direction? If it’s a doc issue, it is easy to fix.

Thanks!

-Chris

Xinliang David Li wrote:

Xinliang David Li wrote:

As simple as

void foo (int n, double *p, int *q)
{
for (int i = 0; i < n; i++)
*p += *q;
}

clang -O2 -fstrict-aliasing -emit-llvm -o foo.bc -c foo.c
llc -enable-tbaa -O2 -filetype=asm -o foo.s foo.bc

There’s a couple things interacting here:

  • clang -fstrict-aliasing -O2 does generate the TBAA info, but it
    runs the optimizers without enabling the -enable-tbaa flag, so the
    optimizers never look at it. Oops.
  • clang -fstrict-aliasing -O0 does not generate the TBAA info in
    the resulting .bc file. This is probably intended to speed up -O0
    builds even if -fstrict-aliasing is set, but is annoying for
    debugging what’s going on under the hood.
  • If clang -O2 worked by running ‘opt’ and ‘llc’ under the hood,
    we could tell it to pass a flag along to them, but it doesn’t. As it
    stands, you can’t turn -enable-tbaa on when running clang.

So, putting that together, one way to do it is:

clang -O2 -fstrict-aliasing foo.c -flto -c -o foo.bc
opt -O2 -enable-tbaa foo.bc foo2.bc

-o foo2.bc

llc -O2 -enable-tbaa foo2.bc -o foo2.s

at which point the opt run will hoist the loads into a loop
preheader. Sadly this runs the LLVM optimizers twice (once in clang
-O2 and once in opt) which could skew results.

Yes, I verified these steps work, but my head is spinning:

  1. does -flto has the same effect as -emit-llvm ? FE emits llvm bitcode
    and exit without invoking llvm backend?

Yes, -flto and -emit-llvm are synonyms.

  1. why do you need to invoke both opt and llc – I verified invoking
    just llc is also fine.

“llc” is really just codegen; the only optimizations it does are ones that are naturally part of lowering from llvm IR to assembly. For example, that includes another run of loop invariant code motion because some loads may have been added – such as a load of the GOT pointer – which weren’t there in the IR to be hoisted.

“opt” runs any IR pass. You can ask run a single optimization, for example “opt -licm” or you can run an analysis pass like scalar evolutions with “opt -analyze -scalar-evolution”. This is where the bulk of LLVM’s optimizations live.

I thought llc include all standard optimization passes (equivalent to opt -std-compile-opts + machine code generation) — it seems more natural (to me) to have a single optimization driver that takes llvm bit code as the input.

David

I strongly recommend not using llvmc unless you know exactly what you’re doing and what the features and limitations of llvmc are. Please use the clang driver.

Is llvmc just a wrapper on top of llvm-gcc and clang? In search of a way to pass down internal llvm options ( I did not know about -m yet), I found that llvmc has -Wo, option (which does not work), that is why I tried it. So many different driver programs makes it little confusing to newbies.

llvmc is an experimental wrapper, not part of the normal toolchain. I’m not sure why, but it was used by the PIC16 toolchain (when it was in mainline), it allows defining compiler drivers that don’t follow the GCC command line syntax.

I completely agree that llvmc is confusing. I would certainly agree with its removal from mainline, but it is actively maintained and presumably there is a reason for that :slight_smile:

Lets look at this another way: maybe this is a documentation issue. Did llvmc’s existence make you want to use it, or was there some documentation that pushed you in that direction? If it’s a doc issue, it is easy to fix.

Lack of documentation saying llvmc is experimental, it is actually more natural for me to pick llvmc than llvm-gcc or clang as the compiler driver. LLVM is a great brand name, but it seems more a brand name of a new technology, not a product (unlike gcc which is a both a technology and product). llvm-gcc seems a bad name - it is more like gcc-llvm (gcc FE with alternative backend which is llvm backend. Open64 uses gcc FE, but there is no gcc in their product name.). clang is compiler FE, it can be coupled with gcc backend as well, so using ‘clang’ as the product name does not sound natural. Other questions that may pop up user mind is how is clang and llvm-gcc compare in terms of performance, are they configured with the same set of optimization passes? Without deep investigation, my guess was that ‘llvmc’ (maybe it should be called lcc, similar to icc, gcc, aCC, occ, etc) is an effort to unify the compiler drivers and saves users some confusion :).

Thanks,

David

And that is opt, it handles all machine independent optimizations (though taking advantage of target data if it knows about it). llc handles target dependent code generation as well as some optimization passes that run on machine instrs like the machine licm that Nick was talking about.

-eric