Skip to content

Instantly share code, notes, and snippets.

@kevinmehall
Created December 22, 2014 04:27
Show Gist options
  • Save kevinmehall/fd6ff7d8bd4dfee4788f to your computer and use it in GitHub Desktop.
Save kevinmehall/fd6ff7d8bd4dfee4788f to your computer and use it in GitHub Desktop.
LLVM immediate offset missed optimization for ARM thumb register access
Ubuntu clang version 3.5.0-4ubuntu2 (tags/RELEASE_350/final) (based on LLVM 3.5.0)
00008000 <main>:
8000: 4802 ldr r0, [pc, #8] ; (800c <main+0xc>)
8002: 2101 movs r1, #1
8004: 6001 str r1, [r0, #0]
8006: 4802 ldr r0, [pc, #8] ; (8010 <main+0x10>)
8008: 6001 str r1, [r0, #0]
800a: 4770 bx lr
800c: 10001004 .word 0x10001004
8010: 10001008 .word 0x10001008
gcc version 4.8.3 20140228 (release) [ARM/embedded-4_8-branch revision 208322] (GNU Tools for ARM Embedded Processors)
00008000 <main>:
8000: 4b02 ldr r3, [pc, #8] ; (800c <main+0xc>)
8002: 2201 movs r2, #1
8004: 605a str r2, [r3, #4]
8006: 609a str r2, [r3, #8]
8008: 4770 bx lr
800a: 46c0 nop ; (mov r8, r8)
800c: 10001000 .word 0x10001000
clang-3.5 -v 2>&1 | head -n1
clang-3.5 --target=arm-none-eabi -O3 test.c -ffreestanding -nostdlib -mthumb -o test-clang
arm-none-eabi-objdump -S test-clang
arm-none-eabi-gcc -v 2>&1 | tail -n 1
arm-none-eabi-gcc -O3 -ffreestanding -nostdlib test.c -mthumb -o test-gcc
arm-none-eabi-objdump -S test-gcc
typedef struct foo {
volatile unsigned a;
volatile unsigned b;
volatile unsigned c;
} foo;
void main() {
foo* f = (foo*) 0x10001000;
f->b = 1;
f->c = 1;
}
@kevinmehall
Copy link
Author

Seems to happen when LLVM constant-folds the GEP instruction. This patch for x86 seems relevant:
http://llvm.org/viewvc/llvm-project?view=revision&revision=204739

I'm using the workaround of putting the register base addresses in the linker script, which hides them from LLVM.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment