[cfe-commits] r122643 - in /cfe/trunk: lib/CodeGen/CGDecl.cpp lib/CodeGen/CGStmt.cpp test/CodeGen/asm-variable.c

Rafael Ávila de Espíndola rafael.espindola at gmail.com
Thu Dec 30 17:37:54 PST 2010

> Actually, I've seen this frequently in real C++ code is leading into a
> an inline assembly block and trying to setup registers ahead of time.
> It's required to work around a number of issues. Older GCCs used to only
> allow a small number of inline asm inputs / outputs, and so this would
> be used to grow that slightly in some code that was written to that
> legacy compiler. Rafael encountered code where this is used to pin
> registers for which no clear register constraint exists on the x86-64
> platform. Perhaps this is just a difference of what C++ code we're
> looking at...

I am looking a Firefox 4, which I am trying to compile with clang.

My intention was to keep an error (or maybe an waring) if the code had a 
variable bound to a register but that was never used in an asm 
statement. Unfortunately, I am not familiar enough with clang to know 
where to implement this.

>     but on the other hand
>     the linux kernel uses this extension to access the stack pointer
>     like a variable.
>     register unsigned long current_stack_pointer asm("esp");
>     foo = current_stack_pointer;
>     We used to error out on this, now we treat it like normal stack
>     variable and miscompile the code.
> I've never seen this construct, but then I've never worked on the
> kernel. =/ This is really frustrating, because the ways I can think of
> to make this use case work correctly basically boil down to turning
> every access to the variable into the equivalent inline assembly to
> access the register. I have a feeling this would play havoc with LLVM's
> optimizers, and it would certainly pessimize all the code you mentioned
> above that use this merely as an "optimization".
> What if we made it an error to access a register variable which is
> explicitly declared as referring to the stack pointer or other "special"
> registers that could reasonably be assumed to have meaningful values
> when accessed in this manner?

I am not sure how to implement that, but looks like a good idea if it 
can be done. Some notes:

register unsigned long current_stack_pointer asm("esp");
foo = current_stack_pointer;

Can be miscompiled by gcc since it can move the read after an alloca if 
it wants to for example.

If you want to read a register at particular time, I think the only 
"safe" way to do is to use an asm statement.

We can get more cases right by doing what llvm-gcc does and introduce 
dummy asm statements like

asm("", : : "r"(foo));

after every foo declaration. I don't like the idea too much as code that 
is less likely to be miscompiled is just harder to find bugs. Anything 
that is able to detect the unsupported cases and turn them to errors 
would be very welcome!

For now this lets clang compile code that could not be compiled 
otherwise. There is just no other way to say that a variable in an asm 
statement must be bound to r8 for example.


More information about the cfe-commits mailing list