https://github.com/ritter-x2a updated https://github.com/llvm/llvm-project/pull/106965
>From c332034894c9fa3de26daedb28a977a3580dc4d8 Mon Sep 17 00:00:00 2001 From: Fabian Ritter <fabian.rit...@amd.com> Date: Mon, 2 Sep 2024 05:37:33 -0400 Subject: [PATCH] [X86] Avoid generating nested CALLSEQ for TLS pointer function arguments When a pointer to thread-local storage is passed in a function call, ISel first lowers the call and wraps the resulting code in CALLSEQ markers. Afterwards, to compute the pointer to TLS, a call to retrieve the TLS base address is generated and then wrapped in a set of CALLSEQ markers. If the latter call is inserted into the call sequence of the former call, this leads to nested call frames, which are illegal and lead to errors in the machine verifier. This patch avoids surrounding the call to compute the TLS base address in CALLSEQ markers if it is already surrounded by such markers. It relies on zero-sized call frames being represented in the call frame size info stored in the MachineBBs. Fixes #45574 and #98042. --- llvm/lib/Target/X86/X86ISelLowering.cpp | 7 +++++ .../test/CodeGen/X86/tls-function-argument.ll | 30 +++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 llvm/test/CodeGen/X86/tls-function-argument.ll diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index bbee0af109c74b..bf9777888df831 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -35593,6 +35593,13 @@ X86TargetLowering::EmitLoweredTLSAddr(MachineInstr &MI, // inside MC, therefore without the two markers shrink-wrapping // may push the prologue/epilogue pass them. const TargetInstrInfo &TII = *Subtarget.getInstrInfo(); + + // Do not introduce CALLSEQ markers if we are already in a call sequence. + // Nested call sequences are not allowed and cause errors in the machine + // verifier. + if (TII.getCallFrameSizeAt(MI).has_value()) + return BB; + const MIMetadata MIMD(MI); MachineFunction &MF = *BB->getParent(); diff --git a/llvm/test/CodeGen/X86/tls-function-argument.ll b/llvm/test/CodeGen/X86/tls-function-argument.ll new file mode 100644 index 00000000000000..9b6ab529db3ea3 --- /dev/null +++ b/llvm/test/CodeGen/X86/tls-function-argument.ll @@ -0,0 +1,30 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 +; RUN: llc -mtriple=x86_64 -verify-machineinstrs -relocation-model=pic < %s | FileCheck %s + +; Passing a pointer to thread-local storage to a function can be problematic +; since computing such addresses requires a function call that is introduced +; very late in instruction selection. We need to ensure that we don't introduce +; nested call sequence markers if this function call happens in a call sequence. + +@TLS = internal thread_local global i64 zeroinitializer, align 8 +declare void @bar(ptr) +define internal void @foo() { +; CHECK-LABEL: foo: +; CHECK: # %bb.0: +; CHECK-NEXT: pushq %rbx +; CHECK-NEXT: .cfi_def_cfa_offset 16 +; CHECK-NEXT: .cfi_offset %rbx, -16 +; CHECK-NEXT: leaq TLS@TLSLD(%rip), %rdi +; CHECK-NEXT: callq __tls_get_addr@PLT +; CHECK-NEXT: leaq TLS@DTPOFF(%rax), %rbx +; CHECK-NEXT: movq %rbx, %rdi +; CHECK-NEXT: callq bar@PLT +; CHECK-NEXT: movq %rbx, %rdi +; CHECK-NEXT: callq bar@PLT +; CHECK-NEXT: popq %rbx +; CHECK-NEXT: .cfi_def_cfa_offset 8 +; CHECK-NEXT: retq + call void @bar(ptr @TLS) + call void @bar(ptr @TLS) + ret void +} _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits