-
Notifications
You must be signed in to change notification settings - Fork 15.3k
Open
Labels
backend:ARMgood first issuehttps://github.com/llvm/llvm-project/contributehttps://github.com/llvm/llvm-project/contribute
Description
Description
The LLVM compiler generates incorrect ARM assembly code that assumes 128-bit alignment for emulated TLS variables, when only 32-bit (4-byte) alignment is guaranteed.
Reproducer
Given the following LLVM IR:
@test = internal thread_local(localdynamic) global [64 x i8] c"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture writeonly, i8* nocapture readonly, i32, i1 immarg)
define void @testfunc() {
%1 = alloca [64 x i8], align 1
%a = getelementptr inbounds [64 x i8], [64 x i8]* %1, i32 0, i32 0
%b = getelementptr inbounds [64 x i8], [64 x i8]* @test, i32 0, i32 0
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %a, i8* %b, i32 64, i1 false)
ret void
}Compiled with: llc -O3 -emulated-tls -mtriple=armv7-linux-gnueabihf
Actual Output
testfunc: @ @testfunc
push {r11, lr}
sub sp, sp, #64
movw r0, :lower16:__emutls_v.test
movt r0, :upper16:__emutls_v.test
bl __emutls_get_address
vld1.64 {d16, d17}, [r0:128]!
vld1.64 {d18, d19}, [r0:128]!
vld1.64 {d20, d21}, [r0:128]!
vld1.64 {d22, d23}, [r0:128]
mov r0, sp
vst1.64 {d16, d17}, [r0]!
vst1.64 {d18, d19}, [r0]!
vst1.64 {d20, d21}, [r0]!
vst1.64 {d22, d23}, [r0]
add sp, sp, #64
pop {r11, pc}
__emutls_v.test:
.long 64 @ 0x40
.long 1 @ 0x1
.long 0
.long __emutls_t.test
__emutls_t.test:
.zero 64,65Problem
The generated code uses vld1.64 instructions with :128 alignment specifiers, which require 128-bit (16-byte) alignment. However, emulated TLS only guarantees 4-byte alignment on ARMv7.
From the emulated TLS implementation in compiler-rt/lib/builtins/emutls.c:
static __inline void *emutls_allocate_object(__emutls_control *control) {
size_t size = control->size;
size_t align = control->align;
void *base;
if (align < sizeof(void *))
align = sizeof(void *); // Only guarantees pointer-size alignment (4 bytes on ARMv7)
// ...
}This mismatch between assumed alignment (128-bit) and actual alignment (32-bit) will cause crashes or undefined behavior at runtime.
Expected Behavior
The compiler should either:
- Use unaligned load instructions when emulated TLS is enabled, or
- Ensure emulated TLS allocations meet the alignment requirements used in the generated code
Metadata
Metadata
Assignees
Labels
backend:ARMgood first issuehttps://github.com/llvm/llvm-project/contributehttps://github.com/llvm/llvm-project/contribute