diff --git a/lld/test/wasm/no-tls.ll b/lld/test/wasm/no-tls.ll deleted file mode 100644 --- a/lld/test/wasm/no-tls.ll +++ /dev/null @@ -1,48 +0,0 @@ -; Testing that __tls_size and __tls_align are correctly emitted when there are -; no thread_local variables. - -; RUN: llc -mattr=+bulk-memory,+atomics -filetype=obj %s -o %t.o - -target triple = "wasm32-unknown-unknown" - -define void @_start() local_unnamed_addr { -entry: - ret void -} - -; RUN: wasm-ld -no-gc-sections --shared-memory --max-memory=131072 --allow-undefined -o %t.wasm %t.o -; RUN: obj2yaml %t.wasm | FileCheck %s -; CHECK: - Type: GLOBAL -; CHECK-NEXT: Globals: - -; __stack_pointer -; CHECK-NEXT: - Index: 0 -; CHECK-NEXT: Type: I32 -; CHECK-NEXT: Mutable: true -; CHECK-NEXT: InitExpr: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 66576 - -; __tls_base -; CHECK-NEXT: - Index: 1 -; CHECK-NEXT: Type: I32 -; CHECK-NEXT: Mutable: true -; CHECK-NEXT: InitExpr: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 0 - -; __tls_size -; CHECK-NEXT: - Index: 2 -; CHECK-NEXT: Type: I32 -; CHECK-NEXT: Mutable: false -; CHECK-NEXT: InitExpr: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 0 - -; __tls_align -; CHECK-NEXT: - Index: 3 -; CHECK-NEXT: Type: I32 -; CHECK-NEXT: Mutable: false -; CHECK-NEXT: InitExpr: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 1 diff --git a/lld/test/wasm/no-tls.s b/lld/test/wasm/no-tls.s new file mode 100644 --- /dev/null +++ b/lld/test/wasm/no-tls.s @@ -0,0 +1,55 @@ +# Testing that __tls_size and __tls_align are correctly emitted when there are +# no thread_local variables. + +# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s + +.globl _start +_start: + .functype _start () -> () + end_function + +.section .custom_section.target_features,"",@ + .int8 2 + .int8 43 + .int8 7 + .ascii "atomics" + .int8 43 + .int8 11 + .ascii "bulk-memory" + +# RUN: wasm-ld -no-gc-sections --shared-memory --max-memory=131072 --allow-undefined -o %t.wasm %t.o +# RUN: obj2yaml %t.wasm | FileCheck %s +# CHECK: - Type: GLOBAL +# CHECK-NEXT: Globals: + +# __stack_pointer +# CHECK-NEXT: - Index: 0 +# CHECK-NEXT: Type: I32 +# CHECK-NEXT: Mutable: true +# CHECK-NEXT: InitExpr: +# CHECK-NEXT: Opcode: I32_CONST +# CHECK-NEXT: Value: 66576 + +# __tls_base +# CHECK-NEXT: - Index: 1 +# CHECK-NEXT: Type: I32 +# CHECK-NEXT: Mutable: true +# CHECK-NEXT: InitExpr: +# CHECK-NEXT: Opcode: I32_CONST +# CHECK-NEXT: Value: 0 + +# __tls_size +# CHECK-NEXT: - Index: 2 +# CHECK-NEXT: Type: I32 +# CHECK-NEXT: Mutable: false +# CHECK-NEXT: InitExpr: +# CHECK-NEXT: Opcode: I32_CONST +# CHECK-NEXT: Value: 0 + +# __tls_align +# CHECK-NEXT: - Index: 3 +# CHECK-NEXT: Type: I32 +# CHECK-NEXT: Mutable: false +# CHECK-NEXT: InitExpr: +# CHECK-NEXT: Opcode: I32_CONST +# CHECK-NEXT: Value: 1 diff --git a/lld/test/wasm/tls-align.ll b/lld/test/wasm/tls-align.ll deleted file mode 100644 --- a/lld/test/wasm/tls-align.ll +++ /dev/null @@ -1,51 +0,0 @@ -; RUN: llc -mattr=+bulk-memory,+atomics -filetype=obj %s -o %t.o - -target triple = "wasm32-unknown-unknown" - -@no_tls = global i32 0, align 4 -@tls1 = thread_local(localexec) global i32 1, align 4 -@tls2 = thread_local(localexec) global i32 1, align 16 - -define i32* @tls1_addr() { - ret i32* @tls1 -} - -define i32* @tls2_addr() { - ret i32* @tls2 -} - -; RUN: wasm-ld -no-gc-sections --shared-memory --max-memory=131072 --no-entry -o %t.wasm %t.o -; RUN: obj2yaml %t.wasm | FileCheck %s - -; CHECK: - Type: GLOBAL -; CHECK-NEXT: Globals: -; CHECK-NEXT: - Index: 0 -; CHECK-NEXT: Type: I32 -; CHECK-NEXT: Mutable: true -; CHECK-NEXT: InitExpr: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 66592 - -; __tls_base -; CHECK-NEXT: - Index: 1 -; CHECK-NEXT: Type: I32 -; CHECK-NEXT: Mutable: true -; CHECK-NEXT: InitExpr: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 0 - -; __tls_size -; CHECK-NEXT: - Index: 2 -; CHECK-NEXT: Type: I32 -; CHECK-NEXT: Mutable: false -; CHECK-NEXT: InitExpr: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 20 - -; __tls_align -; CHECK-NEXT: - Index: 3 -; CHECK-NEXT: Type: I32 -; CHECK-NEXT: Mutable: false -; CHECK-NEXT: InitExpr: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 16 diff --git a/lld/test/wasm/tls-align.s b/lld/test/wasm/tls-align.s new file mode 100644 --- /dev/null +++ b/lld/test/wasm/tls-align.s @@ -0,0 +1,92 @@ +# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s + +.globaltype __tls_base, i32 +.globaltype __tls_align, i32, immutable + +.globl tls1_addr +tls1_addr: + .functype tls1_addr () -> (i32) + global.get __tls_base + i32.const tls1 + i32.add + end_function + +.globl tls2_addr +tls2_addr: + .functype tls2_addr () -> (i32) + global.get __tls_base + i32.const tls2 + i32.add + end_function + +.globl tls_align +tls_align: + .functype tls_align () -> (i32) + global.get __tls_align + end_function + +.section .bss.no_tls,"",@ +.globl no_tls +.p2align 2 +no_tls: + .int32 0 + .size no_tls, 4 + +.section .tdata.tls1,"",@ +.globl tls1 +.p2align 2 +tls1: + .int32 1 + .size tls1, 4 + +.section .tdata.tls2,"",@ +.globl tls2 +.p2align 4 +tls2: + .int32 1 + .size tls2, 4 + +.section .custom_section.target_features,"",@ + .int8 2 + .int8 43 + .int8 7 + .ascii "atomics" + .int8 43 + .int8 11 + .ascii "bulk-memory" + +# RUN: wasm-ld -no-gc-sections --shared-memory --max-memory=131072 --no-entry -o %t.wasm %t.o +# RUN: obj2yaml %t.wasm | FileCheck %s + +# CHECK: - Type: GLOBAL +# CHECK-NEXT: Globals: +# CHECK-NEXT: - Index: 0 +# CHECK-NEXT: Type: I32 +# CHECK-NEXT: Mutable: true +# CHECK-NEXT: InitExpr: +# CHECK-NEXT: Opcode: I32_CONST +# CHECK-NEXT: Value: 66592 + +# __tls_base +# CHECK-NEXT: - Index: 1 +# CHECK-NEXT: Type: I32 +# CHECK-NEXT: Mutable: true +# CHECK-NEXT: InitExpr: +# CHECK-NEXT: Opcode: I32_CONST +# CHECK-NEXT: Value: 0 + +# __tls_size +# CHECK-NEXT: - Index: 2 +# CHECK-NEXT: Type: I32 +# CHECK-NEXT: Mutable: false +# CHECK-NEXT: InitExpr: +# CHECK-NEXT: Opcode: I32_CONST +# CHECK-NEXT: Value: 20 + +# __tls_align +# CHECK-NEXT: - Index: 3 +# CHECK-NEXT: Type: I32 +# CHECK-NEXT: Mutable: false +# CHECK-NEXT: InitExpr: +# CHECK-NEXT: Opcode: I32_CONST +# CHECK-NEXT: Value: 16 diff --git a/lld/test/wasm/tls.ll b/lld/test/wasm/tls.ll deleted file mode 100644 --- a/lld/test/wasm/tls.ll +++ /dev/null @@ -1,106 +0,0 @@ -; RUN: llc -mattr=+bulk-memory,+atomics -filetype=obj %s -o %t.o - -target triple = "wasm32-unknown-unknown" - -@no_tls = global i32 0, align 4 -@tls1 = thread_local(localexec) global i32 1, align 4 -@tls2 = thread_local(localexec) global i32 1, align 4 - -define i32* @tls1_addr() { - ret i32* @tls1 -} - -define i32* @tls2_addr() { - ret i32* @tls2 -} - -define i32 @tls_align() { - %1 = call i32 @llvm.wasm.tls.align.i32() - ret i32 %1 -} - -declare i32 @llvm.wasm.tls.align.i32() - -; RUN: wasm-ld -no-gc-sections --shared-memory --max-memory=131072 --no-entry -o %t.wasm %t.o -; RUN: obj2yaml %t.wasm | FileCheck %s - -; RUN: wasm-ld -no-gc-sections --shared-memory --max-memory=131072 --no-merge-data-segments --no-entry -o %t.wasm %t.o -; RUN: obj2yaml %t.wasm | FileCheck %s - -; CHECK: - Type: GLOBAL -; CHECK-NEXT: Globals: -; CHECK-NEXT: - Index: 0 -; CHECK-NEXT: Type: I32 -; CHECK-NEXT: Mutable: true -; CHECK-NEXT: InitExpr: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 66576 - -; __tls_base -; CHECK-NEXT: - Index: 1 -; CHECK-NEXT: Type: I32 -; CHECK-NEXT: Mutable: true -; CHECK-NEXT: InitExpr: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 0 - -; __tls_size -; CHECK-NEXT: - Index: 2 -; CHECK-NEXT: Type: I32 -; CHECK-NEXT: Mutable: false -; CHECK-NEXT: InitExpr: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 8 - -; __tls_align -; CHECK-NEXT: - Index: 3 -; CHECK-NEXT: Type: I32 -; CHECK-NEXT: Mutable: false -; CHECK-NEXT: InitExpr: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 4 - - -; CHECK: - Type: CODE -; CHECK-NEXT: Functions: -; Skip __wasm_call_ctors and __wasm_init_memory -; CHECK: - Index: 2 -; CHECK-NEXT: Locals: [] -; CHECK-NEXT: Body: 20002401200041004108FC0800000B - -; Expected body of __wasm_init_tls: -; local.get 0 -; global.set 1 -; local.get 0 -; i32.const 0 -; i32.const 8 -; memory.init 1, 0 -; end - -; CHECK-NEXT: - Index: 3 -; CHECK-NEXT: Locals: [] -; CHECK-NEXT: Body: 2381808080004180808080006A0B - -; Expected body of tls1_addr: -; global.get 1 -; i32.const 0 -; i32.add -; end - -; CHECK-NEXT: - Index: 4 -; CHECK-NEXT: Locals: [] -; CHECK-NEXT: Body: 2381808080004184808080006A0B - -; Expected body of tls1_addr: -; global.get 1 -; i32.const 4 -; i32.add -; end - -; CHECK-NEXT: - Index: 5 -; CHECK-NEXT: Locals: [] -; CHECK-NEXT: Body: 2383808080000B - -; Expected body of tls1_addr: -; global.get 3 -; end diff --git a/lld/test/wasm/tls.s b/lld/test/wasm/tls.s new file mode 100644 --- /dev/null +++ b/lld/test/wasm/tls.s @@ -0,0 +1,140 @@ +# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s + +.globaltype __tls_base, i32 +.globaltype __tls_align, i32, immutable + +.globl tls1_addr +tls1_addr: + .functype tls1_addr () -> (i32) + global.get __tls_base + i32.const tls1 + i32.add + end_function + +.globl tls2_addr +tls2_addr: + .functype tls2_addr () -> (i32) + global.get __tls_base + i32.const tls2 + i32.add + end_function + +.globl tls_align +tls_align: + .functype tls_align () -> (i32) + global.get __tls_align + end_function + +.section .bss.no_tls,"",@ +.globl no_tls +.p2align 2 +no_tls: + .int32 0 + .size no_tls, 4 + +.section .tdata.tls1,"",@ +.globl tls1 +.p2align 2 +tls1: + .int32 1 + .size tls1, 4 + +.section .tdata.tls2,"",@ +.globl tls2 +.p2align 2 +tls2: + .int32 1 + .size tls2, 4 + +.section .custom_section.target_features,"",@ + .int8 2 + .int8 43 + .int8 7 + .ascii "atomics" + .int8 43 + .int8 11 + .ascii "bulk-memory" + +# RUN: wasm-ld -no-gc-sections --shared-memory --max-memory=131072 --no-entry -o %t.wasm %t.o +# RUN: obj2yaml %t.wasm | FileCheck %s + +# RUN: wasm-ld -no-gc-sections --shared-memory --max-memory=131072 --no-merge-data-segments --no-entry -o %t.wasm %t.o +# RUN: obj2yaml %t.wasm | FileCheck %s + +# CHECK: - Type: GLOBAL +# CHECK-NEXT: Globals: +# CHECK-NEXT: - Index: 0 +# CHECK-NEXT: Type: I32 +# CHECK-NEXT: Mutable: true +# CHECK-NEXT: InitExpr: +# CHECK-NEXT: Opcode: I32_CONST +# CHECK-NEXT: Value: 66576 + +# __tls_base +# CHECK-NEXT: - Index: 1 +# CHECK-NEXT: Type: I32 +# CHECK-NEXT: Mutable: true +# CHECK-NEXT: InitExpr: +# CHECK-NEXT: Opcode: I32_CONST +# CHECK-NEXT: Value: 0 + +# __tls_size +# CHECK-NEXT: - Index: 2 +# CHECK-NEXT: Type: I32 +# CHECK-NEXT: Mutable: false +# CHECK-NEXT: InitExpr: +# CHECK-NEXT: Opcode: I32_CONST +# CHECK-NEXT: Value: 8 + +# __tls_align +# CHECK-NEXT: - Index: 3 +# CHECK-NEXT: Type: I32 +# CHECK-NEXT: Mutable: false +# CHECK-NEXT: InitExpr: +# CHECK-NEXT: Opcode: I32_CONST +# CHECK-NEXT: Value: 4 + + +# CHECK: - Type: CODE +# CHECK-NEXT: Functions: +# Skip __wasm_call_ctors and __wasm_init_memory +# CHECK: - Index: 2 +# CHECK-NEXT: Locals: [] +# CHECK-NEXT: Body: 20002401200041004108FC0800000B + +# Expected body of __wasm_init_tls: +# local.get 0 +# global.set 1 +# local.get 0 +# i32.const 0 +# i32.const 8 +# memory.init 1, 0 +# end + +# CHECK-NEXT: - Index: 3 +# CHECK-NEXT: Locals: [] +# CHECK-NEXT: Body: 2381808080004180808080006A0B + +# Expected body of tls1_addr: +# global.get 1 +# i32.const 0 +# i32.add +# end + +# CHECK-NEXT: - Index: 4 +# CHECK-NEXT: Locals: [] +# CHECK-NEXT: Body: 2381808080004184808080006A0B + +# Expected body of tls1_addr: +# global.get 1 +# i32.const 4 +# i32.add +# end + +# CHECK-NEXT: - Index: 5 +# CHECK-NEXT: Locals: [] +# CHECK-NEXT: Body: 2383808080000B + +# Expected body of tls1_addr: +# global.get 3 +# end diff --git a/llvm/lib/MC/MCParser/WasmAsmParser.cpp b/llvm/lib/MC/MCParser/WasmAsmParser.cpp --- a/llvm/lib/MC/MCParser/WasmAsmParser.cpp +++ b/llvm/lib/MC/MCParser/WasmAsmParser.cpp @@ -116,6 +116,7 @@ auto Kind = StringSwitch>(Name) .StartsWith(".data", SectionKind::getData()) + .StartsWith(".tdata", SectionKind::getThreadData()) .StartsWith(".rodata", SectionKind::getReadOnly()) .StartsWith(".text", SectionKind::getText()) .StartsWith(".custom_section", SectionKind::getMetadata())