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