diff options
Diffstat (limited to 'test/CodeGen/X86/cxx_tlscc64.ll')
-rw-r--r-- | test/CodeGen/X86/cxx_tlscc64.ll | 94 |
1 files changed, 93 insertions, 1 deletions
diff --git a/test/CodeGen/X86/cxx_tlscc64.ll b/test/CodeGen/X86/cxx_tlscc64.ll index 6c8e45e42d156..ef947367c09e5 100644 --- a/test/CodeGen/X86/cxx_tlscc64.ll +++ b/test/CodeGen/X86/cxx_tlscc64.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -mtriple=x86_64-apple-darwin | FileCheck %s +; RUN: llc -verify-machineinstrs < %s -mtriple=x86_64-apple-darwin | FileCheck %s ; TLS function were wrongly model and after fixing that, shrink-wrapping ; cannot help here. To achieve the expected lowering, we need to playing ; tricks similar to AArch64 fast TLS calling convention (r255821). @@ -39,6 +39,27 @@ declare i32 @_tlv_atexit(void (i8*)*, i8*, i8*) ; CHECK-NOT: popq %r9 ; CHECK-NOT: popq %r10 ; CHECK-NOT: popq %r11 + +; CHECK-O0-LABEL: _ZTW2sg +; CHECK-O0: pushq %r11 +; CHECK-O0: pushq %r10 +; CHECK-O0: pushq %r9 +; CHECK-O0: pushq %r8 +; CHECK-O0: pushq %rsi +; CHECK-O0: pushq %rdx +; CHECK-O0: pushq %rcx +; CHECK-O0: callq +; CHECK-O0: jne +; CHECK-O0: callq +; CHECK-O0: tlv_atexit +; CHECK-O0: callq +; CHECK-O0: popq %rcx +; CHECK-O0: popq %rdx +; CHECK-O0: popq %rsi +; CHECK-O0: popq %r8 +; CHECK-O0: popq %r9 +; CHECK-O0: popq %r10 +; CHECK-O0: popq %r11 define cxx_fast_tlscc nonnull %struct.S* @_ZTW2sg() nounwind { %.b.i = load i1, i1* @__tls_guard, align 1 br i1 %.b.i, label %__tls_init.exit, label %init.i @@ -63,6 +84,24 @@ __tls_init.exit: ; CHECK-NOT: pushq %rcx ; CHECK-NOT: pushq %rbx ; CHECK: callq +; CHECK-O0-LABEL: _ZTW4sum1 +; CHECK-O0-NOT: pushq %r11 +; CHECK-O0-NOT: pushq %r10 +; CHECK-O0-NOT: pushq %r9 +; CHECK-O0-NOT: pushq %r8 +; CHECK-O0-NOT: pushq %rsi +; CHECK-O0-NOT: pushq %rdx +; CHECK-O0-NOT: pushq %rcx +; CHECK-O0-NOT: pushq %rbx +; CHECK-O0-NOT: movq %r11 +; CHECK-O0-NOT: movq %r10 +; CHECK-O0-NOT: movq %r9 +; CHECK-O0-NOT: movq %r8 +; CHECK-O0-NOT: movq %rsi +; CHECK-O0-NOT: movq %rdx +; CHECK-O0-NOT: movq %rcx +; CHECK-O0-NOT: movq %rbx +; CHECK-O0: callq define cxx_fast_tlscc nonnull i32* @_ZTW4sum1() nounwind { ret i32* @sum1 } @@ -76,4 +115,57 @@ define cxx_fast_tlscc i32* @_ZTW4sum2() #0 { ret i32* @sum1 } +; Make sure at O0, we don't generate spilling/reloading of the CSRs. +; CHECK-O0-LABEL: tls_test2 +; CHECK-O0-NOT: pushq %r11 +; CHECK-O0-NOT: pushq %r10 +; CHECK-O0-NOT: pushq %r9 +; CHECK-O0-NOT: pushq %r8 +; CHECK-O0-NOT: pushq %rsi +; CHECK-O0-NOT: pushq %rdx +; CHECK-O0: callq {{.*}}tls_helper +; CHECK-O0-NOT: popq %rdx +; CHECK-O0-NOT: popq %rsi +; CHECK-O0-NOT: popq %r8 +; CHECK-O0-NOT: popq %r9 +; CHECK-O0-NOT: popq %r10 +; CHECK-O0-NOT: popq %r11 +; CHECK-O0: ret +%class.C = type { i32 } +@tC = internal thread_local global %class.C zeroinitializer, align 4 +declare cxx_fast_tlscc void @tls_helper() +define cxx_fast_tlscc %class.C* @tls_test2() #1 { + call cxx_fast_tlscc void @tls_helper() + ret %class.C* @tC +} + +; Make sure we do not allow tail call when caller and callee have different +; calling conventions. +declare %class.C* @_ZN1CD1Ev(%class.C* readnone returned %this) +; CHECK-LABEL: tls_test +; CHECK: callq {{.*}}tlv_atexit +define cxx_fast_tlscc void @tls_test() { +entry: + store i32 0, i32* getelementptr inbounds (%class.C, %class.C* @tC, i64 0, i32 0), align 4 + %0 = tail call i32 @_tlv_atexit(void (i8*)* bitcast (%class.C* (%class.C*)* @_ZN1CD1Ev to void (i8*)*), i8* bitcast (%class.C* @tC to i8*), i8* nonnull @__dso_handle) #1 + ret void +} + +@ssp_var = internal thread_local global i8 0, align 1 + +; CHECK-LABEL: test_ssp +; CHECK-NOT: pushq %r11 +; CHECK-NOT: pushq %r10 +; CHECK-NOT: pushq %r9 +; CHECK-NOT: pushq %r8 +; CHECK-NOT: pushq %rsi +; CHECK-NOT: pushq %rdx +; CHECK-NOT: pushq %rcx +; CHECK-NOT: pushq %rbx +; CHECK: callq +define cxx_fast_tlscc nonnull i8* @test_ssp() #2 { + ret i8* @ssp_var +} attributes #0 = { nounwind "no-frame-pointer-elim"="true" } +attributes #1 = { nounwind } +attributes #2 = { nounwind sspreq } |