[llvm-commits] [llvm-gcc-4.2] r100632 - /llvm-gcc-4.2/trunk/gcc/llvm-types.cpp

Duncan Sands baldrick at free.fr
Wed Apr 7 10:02:33 PDT 2010

Hi Jakob,

> For example, this struct:
>    struct S {
>      int a, b;
>      void *c;
>      unsigned d : 8;
>      unsigned e : 8;
>    };
> used to be:
>    %struct.S = type { i32, i32, i8*, i8, i8 },
> but now it becomes:
>    %struct.S = type { i32, i32, i8*, i16 }

this means that you can't write S.d and S.e separately, so if one thread is
writing to S.d while another writes to S.e then you are in trouble.  Also, if
this type is describing a memory mapped I/O region then writing or reading both
d and e when the original code only touches one of them is bad.  I appreciate
that the C standard doesn't require this kind of thing to work, but I'm pretty
sure the Ada standard does [*].  (That said, what llvm-gcc did before was
already broken for Ada, due to this kind of thing).

I would much rather see reads and writes touch as little as possible, and
have the optimizers combine them if they can prove that it is safe.

Another possibility is to handle volatile reads and writes specially, making
only these be minimal.



[*] The Ada standard requires reads and writes marked atomic to be rejected
as an error by the compiler if it isn't able to turn them into appropriate
atomic processor operations.  The Ada front-end "knows" what kinds of things
gcc will turn into atomic operations, and so knows what it has to reject.
Unfortunately llvm-gcc doesn't make exactly the same decisions...

More information about the llvm-commits mailing list