Home | History | Annotate | Download | only in AArch64
      1 ; RUN: llc -mtriple=arm64-none-linux-gnu -relocation-model=pic -aarch64-elf-ldtls-generation=1 -verify-machineinstrs < %s | FileCheck %s
      2 ; RUN: llc -mtriple=arm64-none-linux-gnu -relocation-model=pic -aarch64-elf-ldtls-generation=1 -filetype=obj < %s | llvm-objdump -r - | FileCheck --check-prefix=CHECK-RELOC %s
      3 ; RUN: llc -mtriple=arm64-none-linux-gnu -relocation-model=pic -verify-machineinstrs < %s | FileCheck --check-prefix=CHECK-NOLD %s
      4 ; RUN: llc -mtriple=arm64-none-linux-gnu -relocation-model=pic -filetype=obj < %s | llvm-objdump -r - | FileCheck --check-prefix=CHECK-NOLD-RELOC %s
      5 
      6 @general_dynamic_var = external thread_local global i32
      7 
      8 define i32 @test_generaldynamic() {
      9 ; CHECK-LABEL: test_generaldynamic:
     10 
     11   %val = load i32, i32* @general_dynamic_var
     12   ret i32 %val
     13 
     14 ; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:general_dynamic_var
     15 ; CHECK-NEXT: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], :tlsdesc_lo12:general_dynamic_var]
     16 ; CHECK-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_lo12:general_dynamic_var
     17 ; CHECK-NEXT: .tlsdesccall general_dynamic_var
     18 ; CHECK-NEXT: blr [[CALLEE]]
     19 
     20 ; CHECK-NOLD: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:general_dynamic_var
     21 ; CHECK-NOLD-NEXT: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], :tlsdesc_lo12:general_dynamic_var]
     22 ; CHECK-NOLD-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_lo12:general_dynamic_var
     23 ; CHECK-NOLD-NEXT: .tlsdesccall general_dynamic_var
     24 ; CHECK-NOLD-NEXT: blr [[CALLEE]]
     25 
     26 
     27 ; CHECK: mrs x[[TP:[0-9]+]], TPIDR_EL0
     28 ; CHECK: ldr w0, [x[[TP]], x0]
     29 ; CHECK-NOLD: mrs x[[TP:[0-9]+]], TPIDR_EL0
     30 ; CHECK-NOLD: ldr w0, [x[[TP]], x0]
     31 
     32 ; CHECK-RELOC: R_AARCH64_TLSDESC_ADR_PAGE21
     33 ; CHECK-RELOC: R_AARCH64_TLSDESC_LD64_LO12_NC
     34 ; CHECK-RELOC: R_AARCH64_TLSDESC_ADD_LO12_NC
     35 ; CHECK-RELOC: R_AARCH64_TLSDESC_CALL
     36 
     37 ; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_ADR_PAGE21
     38 ; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_LD64_LO12_NC
     39 ; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_ADD_LO12_NC
     40 ; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_CALL
     41 
     42 }
     43 
     44 define i32* @test_generaldynamic_addr() {
     45 ; CHECK-LABEL: test_generaldynamic_addr:
     46 
     47   ret i32* @general_dynamic_var
     48 
     49 ; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:general_dynamic_var
     50 ; CHECK-NEXT: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], :tlsdesc_lo12:general_dynamic_var]
     51 ; CHECK-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_lo12:general_dynamic_var
     52 ; CHECK-NEXT: .tlsdesccall general_dynamic_var
     53 ; CHECK-NEXT: blr [[CALLEE]]
     54 
     55 ; CHECK: mrs [[TP:x[0-9]+]], TPIDR_EL0
     56 ; CHECK: add x0, [[TP]], x0
     57 
     58 ; CHECK-RELOC: R_AARCH64_TLSDESC_ADR_PAGE21
     59 ; CHECK-RELOC: R_AARCH64_TLSDESC_LD64_LO12_NC
     60 ; CHECK-RELOC: R_AARCH64_TLSDESC_ADD_LO12_NC
     61 ; CHECK-RELOC: R_AARCH64_TLSDESC_CALL
     62 
     63 ; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_ADR_PAGE21
     64 ; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_LD64_LO12_NC
     65 ; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_ADD_LO12_NC
     66 ; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_CALL
     67 
     68 }
     69 
     70 @local_dynamic_var = external thread_local(localdynamic) global i32
     71 
     72 define i32 @test_localdynamic() {
     73 ; CHECK-LABEL: test_localdynamic:
     74 
     75   %val = load i32, i32* @local_dynamic_var
     76   ret i32 %val
     77 
     78 ; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:_TLS_MODULE_BASE_
     79 ; CHECK-NEXT: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], :tlsdesc_lo12:_TLS_MODULE_BASE_]
     80 ; CHECK-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_lo12:_TLS_MODULE_BASE_
     81 ; CHECK-NEXT: .tlsdesccall _TLS_MODULE_BASE_
     82 ; CHECK-NEXT: blr [[CALLEE]]
     83 ; CHECK-NEXT: add x[[TPOFF:[0-9]+]], x0, :dtprel_hi12:local_dynamic_var
     84 ; CHECK-NEXT: add x[[TPOFF]], x[[TPOFF]], :dtprel_lo12_nc:local_dynamic_var
     85 ; CHECK: mrs x[[TPIDR:[0-9]+]], TPIDR_EL0
     86 ; CHECK: ldr w0, [x[[TPIDR]], x[[TPOFF]]]
     87 
     88 ; CHECK-NOLD: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:local_dynamic_var
     89 ; CHECK-NOLD-NEXT: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], :tlsdesc_lo12:local_dynamic_var]
     90 ; CHECK-NOLD-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_lo12:local_dynamic_var
     91 ; CHECK-NOLD-NEXT: .tlsdesccall local_dynamic_var
     92 ; CHECK-NOLD-NEXT: blr [[CALLEE]]
     93 ; CHECK-NOLD: mrs x[[TPIDR:[0-9]+]], TPIDR_EL0
     94 ; CHECK-NOLD: ldr w0, [x[[TPIDR]], x0]
     95 
     96 
     97 ; CHECK-RELOC: R_AARCH64_TLSDESC_ADR_PAGE21
     98 ; CHECK-RELOC: R_AARCH64_TLSDESC_LD64_LO12_NC
     99 ; CHECK-RELOC: R_AARCH64_TLSDESC_ADD_LO12_NC
    100 ; CHECK-RELOC: R_AARCH64_TLSDESC_CALL
    101 ; CHECK-RELOC: R_AARCH64_TLSLD_ADD_DTPREL_HI12
    102 ; CHECK-RELOC: R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC
    103 
    104 ; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_ADR_PAGE21
    105 ; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_LD64_LO12_NC
    106 ; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_ADD_LO12_NC
    107 ; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_CALL
    108 
    109 }
    110 
    111 define i32* @test_localdynamic_addr() {
    112 ; CHECK-LABEL: test_localdynamic_addr:
    113 
    114 ; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:_TLS_MODULE_BASE_
    115 ; CHECK-NEXT: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], :tlsdesc_lo12:_TLS_MODULE_BASE_]
    116 ; CHECK-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_lo12:_TLS_MODULE_BASE_
    117 ; CHECK-NEXT: .tlsdesccall _TLS_MODULE_BASE_
    118 ; CHECK-NEXT: blr [[CALLEE]]
    119 ; CHECK-NEXT: add x[[TPOFF:[0-9]+]], x0, :dtprel_hi12:local_dynamic_var
    120 ; CHECK-NEXT: add x[[TPOFF]], x[[TPOFF]], :dtprel_lo12_nc:local_dynamic_var
    121 ; CHECK: mrs x[[TPIDR:[0-9]+]], TPIDR_EL0
    122 ; CHECK: add x0, x[[TPIDR]], x[[TPOFF]]
    123 
    124 ; CHECK-NOLD: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:local_dynamic_var
    125 ; CHECK-NOLD-NEXT: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], :tlsdesc_lo12:local_dynamic_var]
    126 ; CHECK-NOLD-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_lo12:local_dynamic_var
    127 ; CHECK-NOLD-NEXT: .tlsdesccall local_dynamic_var
    128 ; CHECK-NOLD-NEXT: blr [[CALLEE]]
    129 ; CHECK-NOLD: mrs x[[TPIDR:[0-9]+]], TPIDR_EL0
    130 ; CHECK-NOLD: add x0, x[[TPIDR]], x0
    131   ret i32* @local_dynamic_var
    132 
    133 ; CHECK-RELOC: R_AARCH64_TLSDESC_ADR_PAGE21
    134 ; CHECK-RELOC: R_AARCH64_TLSDESC_LD64_LO12_NC
    135 ; CHECK-RELOC: R_AARCH64_TLSDESC_ADD_LO12_NC
    136 ; CHECK-RELOC: R_AARCH64_TLSDESC_CALL
    137 ; CHECK-RELOC: R_AARCH64_TLSLD_ADD_DTPREL_HI12
    138 ; CHECK-RELOC: R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC
    139 
    140 ; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_ADR_PAGE21
    141 ; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_LD64_LO12_NC
    142 ; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_ADD_LO12_NC
    143 ; CHECK-NOLD-RELOC: R_AARCH64_TLSDESC_CALL
    144 }
    145 
    146 ; The entire point of the local-dynamic access model is to have a single call to
    147 ; the expensive resolver. Make sure we achieve that goal.
    148 
    149 @local_dynamic_var2 = external thread_local(localdynamic) global i32
    150 
    151 define i32 @test_localdynamic_deduplicate() {
    152 ; CHECK-LABEL: test_localdynamic_deduplicate:
    153 
    154   %val = load i32, i32* @local_dynamic_var
    155   %val2 = load i32, i32* @local_dynamic_var2
    156 
    157   %sum = add i32 %val, %val2
    158   ret i32 %sum
    159 
    160 ; CHECK: adrp x[[DTPREL_HI:[0-9]+]], :tlsdesc:_TLS_MODULE_BASE_
    161 ; CHECK-NEXT: ldr [[CALLEE:x[0-9]+]], [x[[DTPREL_HI]], :tlsdesc_lo12:_TLS_MODULE_BASE_]
    162 ; CHECK-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_lo12:_TLS_MODULE_BASE
    163 ; CHECK-NEXT: .tlsdesccall _TLS_MODULE_BASE_
    164 ; CHECK-NEXT: blr [[CALLEE]]
    165 
    166 ; CHECK-NOT: _TLS_MODULE_BASE_
    167 
    168 ; CHECK: ret
    169 }
    170