Home | History | Annotate | Download | only in ARM
      1 ; RUN: llc -mtriple=thumbv7s-apple-ios7.0 -o - -fast-isel %s | FileCheck %s --check-prefix=T2-MOVT-PIC
      2 ; RUN: llc -mtriple=thumbv7s-apple-ios7.0 -o - %s -mattr=+no-movt | FileCheck %s --check-prefix=T2-LIT-PIC
      3 ; RUN: llc -mtriple=thumbv7s-apple-ios7.0 -o - %s -relocation-model=static | FileCheck %s --check-prefix=T2-MOVT-STATIC
      4 ; RUN: llc -mtriple=thumbv7s-apple-ios7.0 -o - %s -mattr=+no-movt -relocation-model=static | FileCheck %s --check-prefix=T2-LIT-STATIC
      5 ; RUN: llc -mtriple=armv7s-apple-ios7.0 -o - %s | FileCheck %s --check-prefix=ARM-MOVT-PIC
      6 ; RUN: llc -mtriple=armv7s-apple-ios7.0 -o - %s -mattr=+no-movt | FileCheck %s --check-prefix=ARM-LIT-PIC
      7 ; RUN: llc -mtriple=armv7s-apple-ios7.0 -o - %s -relocation-model=static | FileCheck %s --check-prefix=ARM-MOVT-STATIC
      8 ; RUN: llc -mtriple=armv7s-apple-ios7.0 -o - %s -mattr=+no-movt -relocation-model=static | FileCheck %s --check-prefix=ARM-LIT-STATIC
      9 
     10 
     11 @local_tls_var = thread_local global i32 0
     12 @external_tls_var = external thread_local global i32
     13 @hidden_external_tls_var = external hidden thread_local global i32
     14 
     15 
     16 define i32 @test_local_tls() {
     17 ; T2-MOVT-PIC-LABEL: test_local_tls:
     18 ; T2-MOVT-PIC: movw r0, :lower16:(_local_tls_var-([[PCREL_LOC:LPC[0-9]+_[0-9]+]]+4))
     19 ; T2-MOVT-PIC: movt r0, :upper16:(_local_tls_var-([[PCREL_LOC]]+4))
     20 ; T2-MOVT-PIC: [[PCREL_LOC]]:
     21 ; T2-MOVT-PIC-NEXT: add r0, pc
     22 ; T2-MOVT-PIC: ldr [[TLV_GET_ADDR:r[0-9]+]], [r0]
     23 ; T2-MOVT-PIC: blx [[TLV_GET_ADDR]]
     24 ; T2-MOVT-PIC: ldr r0, [r0]
     25 
     26 ; T2-LIT-PIC-LABEL: test_local_tls:
     27 ; T2-LIT-PIC: ldr r0, [[LOCAL_VAR_ADDR:LCPI[0-9]+_[0-9]+]]
     28 ; T2-LIT-PIC: [[PCREL_LOC:LPC[0-9]+_[0-9]+]]:
     29 ; T2-LIT-PIC-NEXT: add r0, pc
     30 ; T2-LIT-PIC: ldr [[TLV_GET_ADDR:r[0-9]+]], [r0]
     31 ; T2-LIT-PIC: blx [[TLV_GET_ADDR]]
     32 ; T2-LIT-PIC: ldr r0, [r0]
     33 ; T2-LIT-PIC: [[LOCAL_VAR_ADDR]]:
     34 ; T2-LIT-PIC-NEXT: .long _local_tls_var-([[PCREL_LOC]]+4)
     35 
     36 ; T2-MOVT-STATIC-LABEL: test_local_tls:
     37 ; T2-MOVT-STATIC: movw r0, :lower16:_local_tls_var
     38 ; T2-MOVT-STATIC: movt r0, :upper16:_local_tls_var
     39 ; T2-MOVT-STATIC: ldr [[TLV_GET_ADDR:r[0-9]+]], [r0]
     40 ; T2-MOVT-STATIC: blx [[TLV_GET_ADDR]]
     41 ; T2-MOVT-STATIC: ldr r0, [r0]
     42 
     43 ; T2-LIT-STATIC-LABEL: test_local_tls:
     44 ; T2-LIT-STATIC: ldr r0, [[LOCAL_VAR_ADDR:LCPI[0-9]+_[0-9]+]]
     45 ; T2-LIT-STATIC: ldr [[TLV_GET_ADDR:r[0-9]+]], [r0]
     46 ; T2-LIT-STATIC: blx [[TLV_GET_ADDR]]
     47 ; T2-LIT-STATIC: ldr r0, [r0]
     48 ; T2-LIT-STATIC: [[LOCAL_VAR_ADDR]]:
     49 ; T2-LIT-STATIC-NEXT: .long _local_tls_var
     50 
     51 ; ARM-MOVT-PIC-LABEL: test_local_tls:
     52 ; ARM-MOVT-PIC: movw [[VARPC1:r[0-9]+]], :lower16:(_local_tls_var-([[PCREL_LOC1:LPC[0-9]+_[0-9]+]]+8))
     53 ; ARM-MOVT-PIC: movt [[VARPC1]], :upper16:(_local_tls_var-([[PCREL_LOC1]]+8))
     54 ; ARM-MOVT-PIC: [[PCREL_LOC1]]:
     55 ; ARM-MOVT-PIC: add r0, pc, [[VARPC1]]
     56 ; ARM-MOVT-PIC: movw [[VARPC2:r[0-9]+]], :lower16:(_local_tls_var-([[PCREL_LOC2:LPC[0-9]+_[0-9]+]]+8))
     57 ; ARM-MOVT-PIC: movt [[VARPC2]], :upper16:(_local_tls_var-([[PCREL_LOC2]]+8))
     58 ; ARM-MOVT-PIC: [[PCREL_LOC2]]:
     59 ; ARM-MOVT-PIC-NEXT: ldr [[TLV_GET_ADDR:r[0-9]+]], [pc, [[VARPC2]]]
     60 ; ARM-MOVT-PIC: blx [[TLV_GET_ADDR]]
     61 ; ARM-MOVT-PIC: ldr r0, [r0]
     62 
     63 ; ARM-LIT-PIC-LABEL: test_local_tls:
     64 ; ARM-LIT-PIC: ldr r0, [[LOCAL_VAR_ADDR:LCPI[0-9]+_[0-9]+]]
     65 ; ARM-LIT-PIC: [[PCREL_LOC:LPC[0-9]+_[0-9]+]]:
     66 ; ARM-LIT-PIC-NEXT: add r0, pc
     67 ; ARM-LIT-PIC: ldr [[TLV_GET_ADDR:r[0-9]+]], [r0]
     68 ; ARM-LIT-PIC: blx [[TLV_GET_ADDR]]
     69 ; ARM-LIT-PIC: ldr r0, [r0]
     70 ; ARM-LIT-PIC: [[LOCAL_VAR_ADDR]]:
     71 ; ARM-LIT-PIC-NEXT: .long _local_tls_var-([[PCREL_LOC]]+8)
     72 
     73 ; ARM-MOVT-STATIC-LABEL: test_local_tls:
     74 ; ARM-MOVT-STATIC: movw r0, :lower16:_local_tls_var
     75 ; ARM-MOVT-STATIC: movt r0, :upper16:_local_tls_var
     76 ; ARM-MOVT-STATIC: ldr [[TLV_GET_ADDR:r[0-9]+]], [r0]
     77 ; ARM-MOVT-STATIC: blx [[TLV_GET_ADDR]]
     78 ; ARM-MOVT-STATIC: ldr r0, [r0]
     79 
     80 ; ARM-LIT-STATIC-LABEL: test_local_tls:
     81 ; ARM-LIT-STATIC: ldr r0, [[LOCAL_VAR_ADDR:LCPI[0-9]+_[0-9]+]]
     82 ; ARM-LIT-STATIC: ldr [[TLV_GET_ADDR:r[0-9]+]], [r0]
     83 ; ARM-LIT-STATIC: blx [[TLV_GET_ADDR]]
     84 ; ARM-LIT-STATIC: ldr r0, [r0]
     85 ; ARM-LIT-STATIC: [[LOCAL_VAR_ADDR]]:
     86 ; ARM-LIT-STATIC-NEXT: .long _local_tls_var
     87 
     88 
     89   %val = load i32, i32* @local_tls_var, align 4
     90   ret i32 %val
     91 }
     92 
     93 define i32 @test_external_tls() {
     94 ; T2-MOVT-PIC-LABEL: test_external_tls:
     95 ; T2-MOVT-PIC: movw r[[EXTGOT:[0-9]+]], :lower16:(L_external_tls_var$non_lazy_ptr-([[PCREL_LOC:LPC[0-9]+_[0-9]+]]+4))
     96 ; T2-MOVT-PIC: movt r[[EXTGOT]], :upper16:(L_external_tls_var$non_lazy_ptr-([[PCREL_LOC]]+4))
     97 ; T2-MOVT-PIC: [[PCREL_LOC]]:
     98 ; T2-MOVT-PIC-NEXT: add r[[EXTGOT]], pc
     99 ; T2-MOVT-PIC: ldr r0, [r[[EXTGOT]]]
    100 ; T2-MOVT-PIC: ldr [[TLV_GET_ADDR:r[0-9]+]], [r0]
    101 ; T2-MOVT-PIC: blx [[TLV_GET_ADDR]]
    102 ; T2-MOVT-PIC: ldr r0, [r0]
    103 
    104 ; T2-LIT-PIC-LABEL: test_external_tls:
    105 ; T2-LIT-PIC: ldr r[[EXTGOT:[0-9]+]], [[EXTERNAL_VAR_ADDR:LCPI[0-9]+_[0-9]+]]
    106 ; T2-LIT-PIC: [[PCREL_LOC:LPC[0-9]+_[0-9]+]]:
    107 ; T2-LIT-PIC-NEXT: add r[[EXTGOT]], pc
    108 ; T2-LIT-PIC: ldr r0, [r[[EXTGOT]]]
    109 ; T2-LIT-PIC: ldr [[TLV_GET_ADDR:r[0-9]+]], [r0]
    110 ; T2-LIT-PIC: blx [[TLV_GET_ADDR]]
    111 ; T2-LIT-PIC: ldr r0, [r0]
    112 ; T2-LIT-PIC: [[EXTERNAL_VAR_ADDR]]:
    113 ; T2-LIT-PIC-NEXT: .long L_external_tls_var$non_lazy_ptr-([[PCREL_LOC]]+4)
    114 
    115 ; T2-MOVT-STATIC-LABEL: test_external_tls:
    116 ; T2-MOVT-STATIC: movw r0, :lower16:_external_tls_var
    117 ; T2-MOVT-STATIC: movt r0, :upper16:_external_tls_var
    118 ; T2-MOVT-STATIC: ldr [[TLV_GET_ADDR:r[0-9]+]], [r0]
    119 ; T2-MOVT-STATIC: blx [[TLV_GET_ADDR]]
    120 ; T2-MOVT-STATIC: ldr r0, [r0]
    121 
    122 ; T2-LIT-STATIC-LABEL: test_external_tls:
    123 ; T2-LIT-STATIC: ldr r0, [[EXTERNAL_VAR_ADDR:LCPI[0-9]+_[0-9]+]]
    124 ; T2-LIT-STATIC: ldr [[TLV_GET_ADDR:r[0-9]+]], [r0]
    125 ; T2-LIT-STATIC: blx [[TLV_GET_ADDR]]
    126 ; T2-LIT-STATIC: ldr r0, [r0]
    127 ; T2-LIT-STATIC: [[EXTERNAL_VAR_ADDR]]:
    128 ; T2-LIT-STATIC-NEXT: .long _external_tls_var
    129 
    130 ; ARM-MOVT-PIC-LABEL: test_external_tls:
    131 ; ARM-MOVT-PIC: movw r[[EXTGOT:[0-9]+]], :lower16:(L_external_tls_var$non_lazy_ptr-([[PCREL_LOC:LPC[0-9]+_[0-9]+]]+8))
    132 ; ARM-MOVT-PIC: movt r[[EXTGOT]], :upper16:(L_external_tls_var$non_lazy_ptr-([[PCREL_LOC]]+8))
    133 ; ARM-MOVT-PIC: [[PCREL_LOC]]:
    134 ; ARM-MOVT-PIC-NEXT: ldr r0, [pc, r[[EXTGOT]]]
    135 ; ARM-MOVT-PIC: ldr [[TLV_GET_ADDR:r[0-9]+]], [r0]
    136 ; ARM-MOVT-PIC: blx [[TLV_GET_ADDR]]
    137 ; ARM-MOVT-PIC: ldr r0, [r0]
    138 
    139 ; ARM-LIT-PIC-LABEL: test_external_tls:
    140 ; ARM-LIT-PIC: ldr r[[EXTGOT:[0-9]+]], [[EXTERNAL_VAR_ADDR:LCPI[0-9]+_[0-9]+]]
    141 ; ARM-LIT-PIC: [[PCREL_LOC:LPC[0-9]+_[0-9]+]]:
    142 ; ARM-LIT-PIC-NEXT: add r[[EXTGOT]], pc
    143 ; ARM-LIT-PIC: ldr r0, [r[[EXTGOT]]]
    144 ; ARM-LIT-PIC: ldr [[TLV_GET_ADDR:r[0-9]+]], [r0]
    145 ; ARM-LIT-PIC: blx [[TLV_GET_ADDR]]
    146 ; ARM-LIT-PIC: ldr r0, [r0]
    147 ; ARM-LIT-PIC: [[EXTERNAL_VAR_ADDR]]:
    148 ; ARM-LIT-PIC-NEXT: .long L_external_tls_var$non_lazy_ptr-([[PCREL_LOC]]+8)
    149 
    150 ; ARM-MOVT-STATIC-LABEL: test_external_tls:
    151 ; ARM-MOVT-STATIC: movw r0, :lower16:_external_tls_var
    152 ; ARM-MOVT-STATIC: movt r0, :upper16:_external_tls_var
    153 ; ARM-MOVT-STATIC: ldr [[TLV_GET_ADDR:r[0-9]+]], [r0]
    154 ; ARM-MOVT-STATIC: blx [[TLV_GET_ADDR]]
    155 ; ARM-MOVT-STATIC: ldr r0, [r0]
    156 
    157 ; ARM-LIT-STATIC-LABEL: test_external_tls:
    158 ; ARM-LIT-STATIC: ldr r0, [[EXTERNAL_VAR_ADDR:LCPI[0-9]+_[0-9]+]]
    159 ; ARM-LIT-STATIC: ldr [[TLV_GET_ADDR:r[0-9]+]], [r0]
    160 ; ARM-LIT-STATIC: blx [[TLV_GET_ADDR]]
    161 ; ARM-LIT-STATIC: ldr r0, [r0]
    162 ; ARM-LIT-STATIC: [[EXTERNAL_VAR_ADDR]]:
    163 ; ARM-LIT-STATIC-NEXT: .long _external_tls_var
    164 
    165   %val = load i32, i32* @external_tls_var, align 4
    166   ret i32 %val
    167 }
    168 
    169 ; Just need something to trigger an indirect reference to the var.
    170 define i32 @use_hidden_external_tls() {
    171   %val = load i32, i32* @hidden_external_tls_var, align 4
    172   ret i32 %val
    173 }
    174 
    175 ; T2-MOVT-PIC: .section __DATA,__thread_ptr,thread_local_variable_pointers
    176 ; T2-MOVT-PIC: .p2align 2
    177 ; T2-MOVT-PIC: L_external_tls_var$non_lazy_ptr:
    178 ; T2-MOVT-PIC:     .indirect_symbol _external_tls_var
    179 ; T2-MOVT-PIC:     .long 0
    180 ; T2-MOVT-PIC: L_hidden_external_tls_var$non_lazy_ptr:
    181 ; T2-MOVT-PIC:     .indirect_symbol _hidden_external_tls_var
    182 ; T2-MOVT-PIC:     .long 0
    183