172 lines · plain
1; RUN: llc -verify-machineinstrs < %s -mtriple=x86_64-apple-darwin | FileCheck %s2; TLS function were wrongly model and after fixing that, shrink-wrapping3; cannot help here. To achieve the expected lowering, we need to playing4; tricks similar to AArch64 fast TLS calling convention (r255821).5; Applying tricks on x86-64 similar to r255821.6; RUN: llc < %s -mtriple=x86_64-apple-darwin -enable-shrink-wrap=true | FileCheck %s7; RUN: llc < %s -mtriple=x86_64-apple-darwin -O0 | FileCheck %s --check-prefix=CHECK-O08%struct.S = type { i8 }9 10@sg = internal thread_local global %struct.S zeroinitializer, align 111@__dso_handle = external global i812@__tls_guard = internal thread_local unnamed_addr global i1 false13@sum1 = internal thread_local global i32 0, align 414 15declare void @_ZN1SC1Ev(ptr)16declare void @_ZN1SD1Ev(ptr)17declare i32 @_tlv_atexit(ptr, ptr, ptr)18 19; Every GPR should be saved - except rdi, rax, and rsp20; CHECK-LABEL: _ZTW2sg21; CHECK-NOT: pushq %r1122; CHECK-NOT: pushq %r1023; CHECK-NOT: pushq %r924; CHECK-NOT: pushq %r825; CHECK-NOT: pushq %rsi26; CHECK-NOT: pushq %rdx27; CHECK-NOT: pushq %rcx28; CHECK-NOT: pushq %rbx29; CHECK: callq30; CHECK: jne31; CHECK: callq32; CHECK: tlv_atexit33; CHECK: callq34; CHECK-NOT: popq %rbx35; CHECK-NOT: popq %rcx36; CHECK-NOT: popq %rdx37; CHECK-NOT: popq %rsi38; CHECK-NOT: popq %r839; CHECK-NOT: popq %r940; CHECK-NOT: popq %r1041; CHECK-NOT: popq %r1142 43; CHECK-O0-LABEL: _ZTW2sg44; CHECK-O0: pushq %r1145; CHECK-O0: pushq %r1046; CHECK-O0: pushq %r947; CHECK-O0: pushq %r848; CHECK-O0: pushq %rsi49; CHECK-O0: pushq %rdx50; CHECK-O0: pushq %rcx51; CHECK-O0: callq52; CHECK-O0: jne53; CHECK-O0: callq54; CHECK-O0: tlv_atexit55; CHECK-O0: callq56; CHECK-O0: popq %rcx57; CHECK-O0: popq %rdx58; CHECK-O0: popq %rsi59; CHECK-O0: popq %r860; CHECK-O0: popq %r961; CHECK-O0: popq %r1062; CHECK-O0: popq %r1163define cxx_fast_tlscc nonnull ptr @_ZTW2sg() nounwind {64 %.b.i = load i1, ptr @__tls_guard, align 165 br i1 %.b.i, label %__tls_init.exit, label %init.i66 67init.i:68 store i1 true, ptr @__tls_guard, align 169 tail call void @_ZN1SC1Ev(ptr nonnull @sg) #270 %1 = tail call i32 @_tlv_atexit(ptr nonnull @_ZN1SD1Ev, ptr nonnull @sg, ptr nonnull @__dso_handle) #271 br label %__tls_init.exit72 73__tls_init.exit:74 ret ptr @sg75}76 77; CHECK-LABEL: _ZTW4sum178; CHECK-NOT: pushq %r1179; CHECK-NOT: pushq %r1080; CHECK-NOT: pushq %r981; CHECK-NOT: pushq %r882; CHECK-NOT: pushq %rsi83; CHECK-NOT: pushq %rdx84; CHECK-NOT: pushq %rcx85; CHECK-NOT: pushq %rbx86; CHECK: callq87; CHECK-O0-LABEL: _ZTW4sum188; CHECK-O0-NOT: pushq %r1189; CHECK-O0-NOT: pushq %r1090; CHECK-O0-NOT: pushq %r991; CHECK-O0-NOT: pushq %r892; CHECK-O0-NOT: pushq %rsi93; CHECK-O0-NOT: pushq %rdx94; CHECK-O0-NOT: pushq %rcx95; CHECK-O0-NOT: pushq %rbx96; CHECK-O0-NOT: movq %r1197; CHECK-O0-NOT: movq %r1098; CHECK-O0-NOT: movq %r999; CHECK-O0-NOT: movq %r8100; CHECK-O0-NOT: movq %rsi101; CHECK-O0-NOT: movq %rdx102; CHECK-O0-NOT: movq %rcx103; CHECK-O0-NOT: movq %rbx104; CHECK-O0: callq105define cxx_fast_tlscc nonnull ptr @_ZTW4sum1() nounwind {106 ret ptr @sum1107}108 109; Make sure at O0 we don't overwrite RBP.110; CHECK-O0-LABEL: _ZTW4sum2111; CHECK-O0: pushq %rbp112; CHECK-O0: movq %rsp, %rbp113; CHECK-O0-NOT: movq %r{{.*}}, (%rbp) 114define cxx_fast_tlscc ptr @_ZTW4sum2() #0 {115 ret ptr @sum1116}117 118; Make sure at O0, we don't generate spilling/reloading of the CSRs.119; CHECK-O0-LABEL: tls_test2120; CHECK-O0-NOT: pushq %r11121; CHECK-O0-NOT: pushq %r10122; CHECK-O0-NOT: pushq %r9123; CHECK-O0-NOT: pushq %r8124; CHECK-O0-NOT: pushq %rsi125; CHECK-O0-NOT: pushq %rdx126; CHECK-O0: callq {{.*}}tls_helper127; CHECK-O0-NOT: popq %rdx128; CHECK-O0-NOT: popq %rsi129; CHECK-O0-NOT: popq %r8130; CHECK-O0-NOT: popq %r9131; CHECK-O0-NOT: popq %r10132; CHECK-O0-NOT: popq %r11133; CHECK-O0: ret134%class.C = type { i32 }135@tC = internal thread_local global %class.C zeroinitializer, align 4136declare cxx_fast_tlscc void @tls_helper()137define cxx_fast_tlscc ptr @tls_test2() #1 {138 call cxx_fast_tlscc void @tls_helper()139 ret ptr @tC140}141 142; Make sure we do not allow tail call when caller and callee have different143; calling conventions.144declare ptr @_ZN1CD1Ev(ptr readnone returned %this)145; CHECK-LABEL: tls_test146; CHECK: callq {{.*}}tlv_atexit147define cxx_fast_tlscc void @tls_test() {148entry:149 store i32 0, ptr @tC, align 4150 %0 = tail call i32 @_tlv_atexit(ptr @_ZN1CD1Ev, ptr @tC, ptr nonnull @__dso_handle) #1151 ret void152}153 154@ssp_var = internal thread_local global i8 0, align 1155 156; CHECK-LABEL: test_ssp157; CHECK-NOT: pushq %r11158; CHECK-NOT: pushq %r10159; CHECK-NOT: pushq %r9160; CHECK-NOT: pushq %r8161; CHECK-NOT: pushq %rsi162; CHECK-NOT: pushq %rdx163; CHECK-NOT: pushq %rcx164; CHECK-NOT: pushq %rbx165; CHECK: callq166define cxx_fast_tlscc nonnull ptr @test_ssp() #2 {167 ret ptr @ssp_var168}169attributes #0 = { nounwind "frame-pointer"="all" }170attributes #1 = { nounwind }171attributes #2 = { nounwind sspreq }172