Home | History | Annotate | Download | only in AArch64
      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