aboutsummaryrefslogtreecommitdiff
path: root/test/Transforms/NaCl/expand-tls.ll
blob: b824ec074ec9958ce7ffa6b2158f6798041a5497 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
; RUN: opt < %s -nacl-expand-tls -S | FileCheck %s

; All thread-local variables should be removed
; RUN: opt < %s -nacl-expand-tls -S | FileCheck %s -check-prefix=NO_TLS

; NO_TLS-NOT: thread_local

@tvar1 = thread_local global i64 123
@tvar2 = thread_local global i32 456


; CHECK: %tls_init_template = type <{ i64, i32 }>
; CHECK: %tls_struct = type <{ %tls_init_template, %tls_bss_template }>
; CHECK: %tls_bss_template = type <{ [4 x i8] }>


; CHECK: @__tls_template_start = internal constant %tls_init_template <{ i64 123, i32 456 }>

; CHECK: @__tls_template_alignment = internal constant i32 8


define i64* @get_tvar1() {
  ret i64* @tvar1
}
; CHECK: define i64* @get_tvar1()
; CHECK: %tls_raw = call i8* @llvm.nacl.read.tp()
; CHECK: %tls_struct = bitcast i8* %tls_raw to %tls_struct*
; CHECK: %field = getelementptr %tls_struct* %tls_struct, i32 -1, i32 0, i32 0
; CHECK: ret i64* %field


define i32* @get_tvar2() {
  ret i32* @tvar2
}
; Much the same as for get_tvar1.
; CHECK: define i32* @get_tvar2()
; CHECK: %field = getelementptr %tls_struct* %tls_struct, i32 -1, i32 0, i32 1


; Check that we define global variables for TLS templates

@__tls_template_start = external global i8
@__tls_template_tdata_end = external global i8
@__tls_template_end = external global i8

define i8* @get_tls_template_start() {
  ret i8* @__tls_template_start
}
; CHECK: define i8* @get_tls_template_start()
; CHECK: ret i8* bitcast (%tls_init_template* @__tls_template_start to i8*)

define i8* @get_tls_template_tdata_end() {
  ret i8* @__tls_template_tdata_end
}
; CHECK: define i8* @get_tls_template_tdata_end()
; CHECK: ret i8* bitcast (%tls_init_template* getelementptr inbounds (%tls_init_template* @__tls_template_start, i32 1) to i8*)

define i8* @get_tls_template_end() {
  ret i8* @__tls_template_end
}
; CHECK: define i8* @get_tls_template_end()
; CHECK: ret i8* bitcast (%tls_struct* getelementptr (%tls_struct* bitcast (%tls_init_template* @__tls_template_start to %tls_struct*), i32 1) to i8*)


; Check that we expand out the TLS layout intrinsics

declare i32 @llvm.nacl.tp.tls.offset(i32)
declare i32 @llvm.nacl.tp.tdb.offset(i32)

define i32 @test_get_tp_tls_offset(i32 %tls_size) {
  %offset = call i32 @llvm.nacl.tp.tls.offset(i32 %tls_size)
  ret i32 %offset
}
; Uses of the intrinsic are replaced with uses of a regular function.
; CHECK: define i32 @test_get_tp_tls_offset
; CHECK: call i32 @nacl_tp_tls_offset
; NO_TLS-NOT: llvm.nacl.tp.tls.offset

define i32 @test_get_tp_tdb_offset(i32 %tdb_size) {
  %offset = call i32 @llvm.nacl.tp.tdb.offset(i32 %tdb_size)
  ret i32 %offset
}
; Uses of the intrinsic are replaced with uses of a regular function.
; CHECK: define i32 @test_get_tp_tdb_offset
; CHECK: call i32 @nacl_tp_tdb_offset
; NO_TLS-NOT: llvm.nacl.tp.tdb.offset