strict aliasing and LLVM

Is type based aliasing implemented in LLVM? Simple test case shows it is not, or an option similar to -fstrict-aliasing is needed?

Thanks,

David

Is type based aliasing implemented in LLVM? Simple test case shows it is
not, or an option similar to -fstrict-aliasing is needed?

It is being implemented. You have to use clang, not llvm-gcc. The
types are encoded as metadata. Compile with -OX and and look for the
TBAA metadata in the .ll file.

Thanks,
David

Cheers,
Rafael

Thanks. Just built clang and saw the meta data and annotations on the memory accesses – is any opt pass consuming the information?

By the way the build instruction in this page http://clang.llvm.org/get_started.html needs to be updated – it recommends config (with default settings) and build llvm in the source dir – it leaves some ‘sticky’ generated files in the source dir leading to building problems.

David

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

Thanks. Just built clang and saw the meta data and annotations on the memory
accesses -- is any opt pass consuming the information?

The tests in test/Analysis/TypeBasedAliasAnalysis suggest that at
least licm is using it. Also note that
lib/Analysis/TypeBasedAliasAnalysis.cpp defines as enable-tbaa option
that is off by default.

By the way the build instruction in this
page http://clang.llvm.org/get_started.html needs to be updated -- it
recommends config (with default settings) and build llvm in the source dir
-- it leaves some 'sticky' generated files in the source dir leading to
building problems.

Thanks. Will try to improve it a bit.

David

Cheers,
Rafael

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

2010/10/27 Xinliang David Li <xinliangli@gmail.com>:

Thanks. Just built clang and saw the meta data and annotations on the memory
accesses – is any opt pass consuming the information?

The tests in test/Analysis/TypeBasedAliasAnalysis suggest that at
least licm is using it. Also note that
lib/Analysis/TypeBasedAliasAnalysis.cpp defines as enable-tbaa option
that is off by default.

I tried the option – no much differences in the generated code.

A related question: how to pass the llvm specific options from clang driver? It supports -Wl, -Wa, -Xanalyzer etc, but there is no documentation on how to pass -enable-tbaa to opt driver.

llvmc supports -Wo, option, but the option specified after -Wo, seems to be dropped. Another thing, when using -clang option to llvmc, I got link errors even when -c or -S is specified:

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)

David

> Thanks. Just built clang and saw the meta data and annotations on the memory
> accesses -- is any opt pass consuming the information?

The tests in test/Analysis/TypeBasedAliasAnalysis suggest that at
least licm is using it. Also note that
lib/Analysis/TypeBasedAliasAnalysis.cpp defines as enable-tbaa option
that is off by default.

LICM, GVN, and DSE are the major consumers right now. That said, the
current TBAA implementation is not very advanced yet.

I tried the option -- no much differences in the generated code.

Can you give an example of code you'd expect to be optimized which isn't?

Dan

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

Memory accesses remain in the loop.

The following works fine:

void foo(int n, double *restrict p, int * restrict *q)
{

}

By the way, Is there a performance category in the llvm bug database?

Thanks,

David

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
   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.

I think the right thing to do is to teach the clang driver to remove -fstrict-aliasing from the cc1 invocation when optimizations are off. This would let us force the flag through with "-Xclang -fstrict-aliasing".

Memory accesses remain in the loop.

The following works fine:

void foo(int n, double *restrict p, int * restrict *q)
{
   ...
}

By the way, Is there a performance category in the llvm bug database?

Nope, we file bugs based on the type of optimization ought to solve it (ie., there's a Scalar optimizations category, a Loop optimizer category, Backend: X86, etc.). Many miscellaneous performance improvements actually live in lib/Target/README.txt (and subdirs of there) instead of the bug tracker.

Nick

clang -O2 foo.c -S -o foo.s -mllvm -enable-tbaa

* 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.

I would expect -O0 to turn off strict-aliasing, so this seems like correct behavior, applying the usual "last flag wins" rule for conflicts. -O0 -fstrict-aliasing should do what you want.

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

Dan

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?

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

  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?

Thanks,

David

Thanks for the -m tip to pass llvm options. Why is it not documented anywhere. See http://clang.llvm.org/docs/UsersManual.html#commandline

David

Thanks for the -m tip to pass llvm options. Why is it not documented anywhere. See http://clang.llvm.org/docs/UsersManual.html#commandline

-mllvm flags are somewhat equivalent to gcc -param options. -mllvm flags are for compiler hackers to play with, and are not stable or documented. Once TBAA is stable and reliable it will be controlled with -fstrict-aliasing as you’d expect.

-Chris

Thanks for the -m tip to pass llvm options. Why is it not documented anywhere. See http://clang.llvm.org/docs/UsersManual.html#commandline

-mllvm flags are somewhat equivalent to gcc -param options. -mllvm flags are for compiler hackers to play with, and are not stable or documented. Once TBAA is stable and reliable it will be controlled with -fstrict-aliasing as you’d expect.

-mllvm is also useful for passing options like -print-after=xxx. May be it should be mentioned when invoking ‘clang --help-hidden’.

Thanks,

David

But that’s another example of something for compiler hackers, which isn’t stable or documented :slight_smile:

-Chris

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?

I think they are the same, but maybe -flto also affects which passes
are run. Not sure. I always used -emit-llvm...

2) why do you need to invoke both opt and llc -- I verified invoking just
llc is also fine.
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?

opt contains the IL -> IL optimizations. It is what you want to use
for testing that a loop is unrolled for example.
llc does the IL -> .s (or .o) transformation. It will also run low level passes.

I guess they could be merged. Never tough about the trade offs.

Thanks,
David

Cheers,
Rafael

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.

David

Cheers,
Rafael

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.

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.

-Chris