1 ; RUN: llc -mtriple=aarch64-none-linux-gnu -relocation-model=pic -verify-machineinstrs < %s | FileCheck %s 2 ; RUN: llc -mtriple=aarch64-none-linux-gnu -relocation-model=pic -filetype=obj < %s | llvm-objdump -r - | FileCheck --check-prefix=CHECK-RELOC %s 3 4 @general_dynamic_var = external thread_local global i32 5 6 define i32 @test_generaldynamic() { 7 ; CHECK-LABEL: test_generaldynamic: 8 9 %val = load i32* @general_dynamic_var 10 ret i32 %val 11 12 ; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:general_dynamic_var 13 ; CHECK: add x0, x[[TLSDESC_HI]], #:tlsdesc_lo12:general_dynamic_var 14 ; CHECK: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], #:tlsdesc_lo12:general_dynamic_var] 15 ; CHECK: .tlsdesccall general_dynamic_var 16 ; CHECK-NEXT: blr [[CALLEE]] 17 18 ; CHECK: mrs x[[TP:[0-9]+]], tpidr_el0 19 ; CHECK: ldr w0, [x[[TP]], x0] 20 21 ; CHECK-RELOC: R_AARCH64_TLSDESC_ADR_PAGE 22 ; CHECK-RELOC: R_AARCH64_TLSDESC_ADD_LO12_NC 23 ; CHECK-RELOC: R_AARCH64_TLSDESC_LD64_LO12_NC 24 ; CHECK-RELOC: R_AARCH64_TLSDESC_CALL 25 26 } 27 28 define i32* @test_generaldynamic_addr() { 29 ; CHECK-LABEL: test_generaldynamic_addr: 30 31 ret i32* @general_dynamic_var 32 33 ; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:general_dynamic_var 34 ; CHECK: add x0, x[[TLSDESC_HI]], #:tlsdesc_lo12:general_dynamic_var 35 ; CHECK: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], #:tlsdesc_lo12:general_dynamic_var] 36 ; CHECK: .tlsdesccall general_dynamic_var 37 ; CHECK-NEXT: blr [[CALLEE]] 38 39 ; CHECK: mrs [[TP:x[0-9]+]], tpidr_el0 40 ; CHECK: add x0, [[TP]], x0 41 42 ; CHECK-RELOC: R_AARCH64_TLSDESC_ADR_PAGE 43 ; CHECK-RELOC: R_AARCH64_TLSDESC_ADD_LO12_NC 44 ; CHECK-RELOC: R_AARCH64_TLSDESC_LD64_LO12_NC 45 ; CHECK-RELOC: R_AARCH64_TLSDESC_CALL 46 47 } 48 49 @local_dynamic_var = external thread_local(localdynamic) global i32 50 51 define i32 @test_localdynamic() { 52 ; CHECK-LABEL: test_localdynamic: 53 54 %val = load i32* @local_dynamic_var 55 ret i32 %val 56 57 ; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:_TLS_MODULE_BASE_ 58 ; CHECK: add x0, x[[TLSDESC_HI]], #:tlsdesc_lo12:_TLS_MODULE_BASE_ 59 ; CHECK: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], #:tlsdesc_lo12:_TLS_MODULE_BASE_] 60 ; CHECK: .tlsdesccall _TLS_MODULE_BASE_ 61 ; CHECK-NEXT: blr [[CALLEE]] 62 63 ; CHECK: movz [[DTP_OFFSET:x[0-9]+]], #:dtprel_g1:local_dynamic_var 64 ; CHECK: movk [[DTP_OFFSET]], #:dtprel_g0_nc:local_dynamic_var 65 66 ; CHECK: ldr w0, [x0, [[DTP_OFFSET]]] 67 68 ; CHECK-RELOC: R_AARCH64_TLSDESC_ADR_PAGE 69 ; CHECK-RELOC: R_AARCH64_TLSDESC_ADD_LO12_NC 70 ; CHECK-RELOC: R_AARCH64_TLSDESC_LD64_LO12_NC 71 ; CHECK-RELOC: R_AARCH64_TLSDESC_CALL 72 73 } 74 75 define i32* @test_localdynamic_addr() { 76 ; CHECK-LABEL: test_localdynamic_addr: 77 78 ret i32* @local_dynamic_var 79 80 ; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:_TLS_MODULE_BASE_ 81 ; CHECK: add x0, x[[TLSDESC_HI]], #:tlsdesc_lo12:_TLS_MODULE_BASE_ 82 ; CHECK: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], #:tlsdesc_lo12:_TLS_MODULE_BASE_] 83 ; CHECK: .tlsdesccall _TLS_MODULE_BASE_ 84 ; CHECK-NEXT: blr [[CALLEE]] 85 86 ; CHECK: movz [[DTP_OFFSET:x[0-9]+]], #:dtprel_g1:local_dynamic_var 87 ; CHECK: movk [[DTP_OFFSET]], #:dtprel_g0_nc:local_dynamic_var 88 89 ; CHECK: add x0, x0, [[DTP_OFFSET]] 90 91 ; CHECK-RELOC: R_AARCH64_TLSDESC_ADR_PAGE 92 ; CHECK-RELOC: R_AARCH64_TLSDESC_ADD_LO12_NC 93 ; CHECK-RELOC: R_AARCH64_TLSDESC_LD64_LO12_NC 94 ; CHECK-RELOC: R_AARCH64_TLSDESC_CALL 95 96 } 97 98 ; The entire point of the local-dynamic access model is to have a single call to 99 ; the expensive resolver. Make sure we achieve that goal. 100 101 @local_dynamic_var2 = external thread_local(localdynamic) global i32 102 103 define i32 @test_localdynamic_deduplicate() { 104 ; CHECK-LABEL: test_localdynamic_deduplicate: 105 106 %val = load i32* @local_dynamic_var 107 %val2 = load i32* @local_dynamic_var2 108 109 %sum = add i32 %val, %val2 110 ret i32 %sum 111 112 ; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:_TLS_MODULE_BASE_ 113 ; CHECK: add x0, x[[TLSDESC_HI]], #:tlsdesc_lo12:_TLS_MODULE_BASE_ 114 ; CHECK: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], #:tlsdesc_lo12:_TLS_MODULE_BASE_] 115 ; CHECK: .tlsdesccall _TLS_MODULE_BASE_ 116 ; CHECK-NEXT: blr [[CALLEE]] 117 118 ; CHECK-NOT: _TLS_MODULE_BASE_ 119 120 ; CHECK: ret 121 } 122