1; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -mattr=+bulk-memory | FileCheck %s --check-prefixes=CHECK,TLS 2; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -mattr=+bulk-memory -fast-isel | FileCheck %s --check-prefixes=CHECK,TLS 3; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -mattr=-bulk-memory | FileCheck %s --check-prefixes=CHECK,NO-TLS 4target triple = "wasm32-unknown-unknown" 5 6; CHECK-LABEL: address_of_tls: 7; CHECK-NEXT: .functype address_of_tls () -> (i32) 8define i32 @address_of_tls() { 9 ; TLS-DAG: global.get __tls_base 10 ; TLS-DAG: i32.const tls@TLSREL 11 ; TLS-NEXT: i32.add 12 ; TLS-NEXT: return 13 14 ; NO-TLS-NEXT: i32.const tls 15 ; NO-TLS-NEXT: return 16 ret i32 ptrtoint(i32* @tls to i32) 17} 18 19; CHECK-LABEL: address_of_tls_external: 20; CHECK-NEXT: .functype address_of_tls_external () -> (i32) 21define i32 @address_of_tls_external() { 22 ; TLS-DAG: global.get __tls_base 23 ; TLS-DAG: i32.const tls_external@TLSREL 24 ; TLS-NEXT: i32.add 25 ; TLS-NEXT: return 26 27 ; NO-TLS-NEXT: i32.const tls_external 28 ; NO-TLS-NEXT: return 29 ret i32 ptrtoint(i32* @tls_external to i32) 30} 31 32; CHECK-LABEL: ptr_to_tls: 33; CHECK-NEXT: .functype ptr_to_tls () -> (i32) 34define i32* @ptr_to_tls() { 35 ; TLS-DAG: global.get __tls_base 36 ; TLS-DAG: i32.const tls@TLSREL 37 ; TLS-NEXT: i32.add 38 ; TLS-NEXT: return 39 40 ; NO-TLS-NEXT: i32.const tls 41 ; NO-TLS-NEXT: return 42 ret i32* @tls 43} 44 45; CHECK-LABEL: tls_load: 46; CHECK-NEXT: .functype tls_load () -> (i32) 47define i32 @tls_load() { 48 ; TLS-DAG: global.get __tls_base 49 ; TLS-DAG: i32.const tls@TLSREL 50 ; TLS-NEXT: i32.add 51 ; TLS-NEXT: i32.load 0 52 ; TLS-NEXT: return 53 54 ; NO-TLS-NEXT: i32.const 0 55 ; NO-TLS-NEXT: i32.load tls 56 ; NO-TLS-NEXT: return 57 %tmp = load i32, i32* @tls, align 4 58 ret i32 %tmp 59} 60 61; CHECK-LABEL: tls_store: 62; CHECK-NEXT: .functype tls_store (i32) -> () 63define void @tls_store(i32 %x) { 64 ; TLS-DAG: global.get __tls_base 65 ; TLS-DAG: i32.const tls@TLSREL 66 ; TLS-NEXT: i32.add 67 ; TLS-NEXT: i32.store 0 68 ; TLS-NEXT: return 69 70 ; NO-TLS-NEXT: i32.const 0 71 ; NO-TLS-NEXT: i32.store tls 72 ; NO-TLS-NEXT: return 73 store i32 %x, i32* @tls, align 4 74 ret void 75} 76 77; CHECK-LABEL: tls_size: 78; CHECK-NEXT: .functype tls_size () -> (i32) 79define i32 @tls_size() { 80; CHECK-NEXT: global.get __tls_size 81; CHECK-NEXT: return 82 %1 = call i32 @llvm.wasm.tls.size.i32() 83 ret i32 %1 84} 85 86; CHECK: .type tls,@object 87; TLS-NEXT: .section .tbss.tls,"T",@ 88; NO-TLS-NEXT: .section .bss.tls,"",@ 89; CHECK-NEXT: .p2align 2 90; CHECK-NEXT: tls: 91; CHECK-NEXT: .int32 0 92@tls = internal thread_local(localexec) global i32 0 93 94@tls_external = external thread_local(localexec) global i32, align 4 95 96declare i32 @llvm.wasm.tls.size.i32() 97