Issue 167219
Summary Incorrect alignment assumption for emulated TLS on ARMv7
Labels new issue
Assignees
Reporter goottime
    ## 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:
```llvm
@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
```asm
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,65
```

## Problem

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_](https://github.com/llvm/llvm-project/blob/main/compiler-rt/lib/builtins/emutls.c):
```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
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to