[LLVMdev] [LLVM] Forward temp label references on ARM in LDR with .ltorg in inline assembly are broken in trunk

David Peixotto dpeixott at codeaurora.org
Thu Feb 20 18:24:57 PST 2014


Hi Gordon,

> I'm not entirely sure what caused this, but the following code, which used
> to behave as expected, is now broken:
> 
> ---- lolwut.c ----------------------------
> 
> void lolwut(void) {
>   __asm __volatile (
>     "ldr r1, =1f  \n"
>     ".ltorg       \n"
>     "1:           \n\t"
>     : : : "r0", "r1" );
> }
> 
> -------------------------------------------
> 
> ~/clang -target armv7-none-eabi -O0 -c -emit-llvm lolwut.c -o lolwut.bc
> ~/llc -O0 lolwut.bc -o lolwut.s
> 
> ---- lolwut.s ----------------------------
> 
> 	.file	"lolwut.bc"
> 	.text
> 	.globl	lolwut
> 	.align	2
> 	.type	lolwut,%function
> lolwut:                                 @ @lolwut
> 	.fnstart
> @ BB#0:                                 @ %entry
> 	@APP
> 	ldr	r1, .Ltmp0
> 	.align	2
> .Ltmp0:
> 	.long	".L11"
> 
> ".L11":
> 
> 	@NO_APP
> 	bx	lr
> .Ltmp1:
> 	.size	lolwut, .Ltmp1-lolwut
> 
> ------------------------------------------
> 
> Somehow, the forward referenced label at 1: in the original assembly is
> getting mangled when its constant pool entry is created (the bad character
> is a 0x02 hex).   In previous versions, the inline assembly was unchanged
> in the output.   Does anyone know what's going on here?   I found the
> checkin that changed how ldr rx, = was handled but haven't had a chance to
> revert and try a prior revision to see if this still happens.

I think the bit that changed is that we now always parse inlineasm, but
before we would not parse it when outputting a .s file. See commit r201333
for details: http://llvm-reviews.chandlerc.com/D2686. I think you can pass
the -no-integrated-as flag to disable parsing inlineasm with the integrated
assembler. There is some discussion on adding a clang/llvm flag to disable
parsing of inlineasm:
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140217/205513.
html


The mangling you see is the assembler generating a private label. It
includes the unprintable character 0x2 so that it cannot conflict with any
user crated label.
 
> I'll file a bug on this after I track down my bugzilla password but I
> wanted to ask here first because I'm willing to fix it if someone can
> point me in the right direction.

It looks like this is behavior is not particular to just .ltorg, but shows
up when printing the private labels.

$ cat tt.s
.syntax unified
foo:
  b 1f
1:
  add r0, r0, r0
$ llvm-mc < tt.s 
        .text
foo:
        b       ".L11"
".L11":
        add     r0, r0, r0
$ llvm-mc < tt.s | hexdump -C
00000000  09 2e 74 65 78 74 0a 0a  0a 66 6f 6f 3a 0a 09 62
|..text...foo:..b|
00000010  09 22 2e 4c 31 02 31 22  0a 22 2e 4c 31 02 31 22
|.".L1.1".".L1.1"|
00000020  3a 0a 09 61 64 64 09 72  30 2c 20 72 30 2c 20 72  |:..add.r0, r0,
r|
00000030  30 0a                                             |0.|
00000032

I'm not sure if this is a bug or the intended behavior for printing these
labels.





More information about the llvm-dev mailing list