1; Run the tests with the `localexec` TLS mode specified. 2; RUN: sed -e 's/\[\[TLS_MODE\]\]/(localexec)/' %s | llc -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -mattr=+bulk-memory,atomics - | FileCheck --check-prefixes=CHECK,TLS %s 3; RUN: sed -e 's/\[\[TLS_MODE\]\]/(localexec)/' %s | llc -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -mattr=+bulk-memory,atomics -fast-isel - | FileCheck --check-prefixes=CHECK,TLS %s 4 5; Also, run the same tests without a specified TLS mode--this should still emit `localexec` code on non-Emscripten targtes which don't currently support dynamic linking. 6; RUN: sed -e 's/\[\[TLS_MODE\]\]//' %s | llc -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -mattr=+bulk-memory,atomics - | FileCheck --check-prefixes=CHECK,TLS %s 7; RUN: sed -e 's/\[\[TLS_MODE\]\]//' %s | llc -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -mattr=+bulk-memory,atomics -fast-isel - | FileCheck --check-prefixes=CHECK,TLS %s 8 9; Finally, when bulk memory is disabled, no TLS code should be generated. 10; RUN: sed -e 's/\[\[TLS_MODE\]\]/(localexec)/' %s | llc -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -mattr=-bulk-memory,atomics - | FileCheck --check-prefixes=CHECK,NO-TLS %s 11target triple = "wasm32-unknown-unknown" 12 13; CHECK-LABEL: address_of_tls: 14; CHECK-NEXT: .functype address_of_tls () -> (i32) 15define i32 @address_of_tls() { 16 ; TLS-DAG: global.get __tls_base 17 ; TLS-DAG: i32.const tls@TLSREL 18 ; TLS-NEXT: i32.add 19 ; TLS-NEXT: return 20 21 ; NO-TLS-NEXT: i32.const tls 22 ; NO-TLS-NEXT: return 23 ret i32 ptrtoint(i32* @tls to i32) 24} 25 26; CHECK-LABEL: address_of_tls_external: 27; CHECK-NEXT: .functype address_of_tls_external () -> (i32) 28define i32 @address_of_tls_external() { 29 ; TLS-DAG: global.get __tls_base 30 ; TLS-DAG: i32.const tls_external@TLSREL 31 ; TLS-NEXT: i32.add 32 ; TLS-NEXT: return 33 34 ; NO-TLS-NEXT: i32.const tls_external 35 ; NO-TLS-NEXT: return 36 ret i32 ptrtoint(i32* @tls_external to i32) 37} 38 39; CHECK-LABEL: ptr_to_tls: 40; CHECK-NEXT: .functype ptr_to_tls () -> (i32) 41define i32* @ptr_to_tls() { 42 ; TLS-DAG: global.get __tls_base 43 ; TLS-DAG: i32.const tls@TLSREL 44 ; TLS-NEXT: i32.add 45 ; TLS-NEXT: return 46 47 ; NO-TLS-NEXT: i32.const tls 48 ; NO-TLS-NEXT: return 49 ret i32* @tls 50} 51 52; CHECK-LABEL: tls_load: 53; CHECK-NEXT: .functype tls_load () -> (i32) 54define i32 @tls_load() { 55 ; TLS-DAG: global.get __tls_base 56 ; TLS-DAG: i32.const tls@TLSREL 57 ; TLS-NEXT: i32.add 58 ; TLS-NEXT: i32.load 0 59 ; TLS-NEXT: return 60 61 ; NO-TLS-NEXT: i32.const 0 62 ; NO-TLS-NEXT: i32.load tls 63 ; NO-TLS-NEXT: return 64 %tmp = load i32, i32* @tls, align 4 65 ret i32 %tmp 66} 67 68; CHECK-LABEL: tls_store: 69; CHECK-NEXT: .functype tls_store (i32) -> () 70define void @tls_store(i32 %x) { 71 ; TLS-DAG: global.get __tls_base 72 ; TLS-DAG: i32.const tls@TLSREL 73 ; TLS-NEXT: i32.add 74 ; TLS-NEXT: i32.store 0 75 ; TLS-NEXT: return 76 77 ; NO-TLS-NEXT: i32.const 0 78 ; NO-TLS-NEXT: i32.store tls 79 ; NO-TLS-NEXT: return 80 store i32 %x, i32* @tls, align 4 81 ret void 82} 83 84; CHECK-LABEL: tls_size: 85; CHECK-NEXT: .functype tls_size () -> (i32) 86define i32 @tls_size() { 87; CHECK-NEXT: global.get __tls_size 88; CHECK-NEXT: return 89 %1 = call i32 @llvm.wasm.tls.size.i32() 90 ret i32 %1 91} 92 93; CHECK: .type tls,@object 94; TLS-NEXT: .section .tbss.tls,"T",@ 95; NO-TLS-NEXT: .section .bss.tls,"",@ 96; CHECK-NEXT: .p2align 2 97; CHECK-NEXT: tls: 98; CHECK-NEXT: .int32 0 99@tls = internal thread_local[[TLS_MODE]] global i32 0 100 101@tls_external = external thread_local[[TLS_MODE]] global i32, align 4 102 103declare i32 @llvm.wasm.tls.size.i32() 104