Index: test/Transforms/NaCl/expand-tls.ll |
diff --git a/test/Transforms/NaCl/expand-tls.ll b/test/Transforms/NaCl/expand-tls.ll |
new file mode 100644 |
index 0000000000000000000000000000000000000000..76859194eb9ff74bb6860ba3418d9f079a51e6fe |
--- /dev/null |
+++ b/test/Transforms/NaCl/expand-tls.ll |
@@ -0,0 +1,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 define the TLS layout functions |
+ |
+declare i32 @__nacl_tp_tls_offset(i32) |
+declare i32 @__nacl_tp_tdb_offset(i32) |
+ |
+define i32 @test_get_tp_tls_offset(i32 %tls_size) { |
+ %offset = call i32 @__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: __nacl_tp_tls_offset |
+ |
+define i32 @test_get_tp_tdb_offset(i32 %tdb_size) { |
+ %offset = call i32 @__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: __nacl_tp_tdb_offset |