[llvm] [X86] Do not elect to tail call if caller must preserve all registers (PR #112098)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Oct 12 08:20:38 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-x86
Author: Antonio Frighetto (antoniofrighetto)
<details>
<summary>Changes</summary>
A miscompilation issue has been addressed with improved checking.
Fixes: https://github.com/llvm/llvm-project/issues/97758.
---
Full diff: https://github.com/llvm/llvm-project/pull/112098.diff
2 Files Affected:
- (modified) llvm/lib/Target/X86/X86ISelLoweringCall.cpp (+7)
- (added) llvm/test/CodeGen/X86/tailcall-caller-nocsr.ll (+34)
``````````diff
diff --git a/llvm/lib/Target/X86/X86ISelLoweringCall.cpp b/llvm/lib/Target/X86/X86ISelLoweringCall.cpp
index 8561658379f7e4..eb166ff7002df5 100644
--- a/llvm/lib/Target/X86/X86ISelLoweringCall.cpp
+++ b/llvm/lib/Target/X86/X86ISelLoweringCall.cpp
@@ -2856,6 +2856,13 @@ bool X86TargetLowering::IsEligibleForTailCallOptimization(
return false;
}
+ // The stack frame of the caller cannot be replaced by the tail-callee one's
+ // if the function is required to preserve all the registers. Conservatively
+ // prevent tail optimization even if hypothetically all the registers are used
+ // for passing formal parameters or returning values.
+ if (CLI.CB->getFunction()->hasFnAttribute("no_caller_saved_registers"))
+ return false;
+
unsigned StackArgsSize = CCInfo.getStackSize();
// If the callee takes no arguments then go on to check the results of the
diff --git a/llvm/test/CodeGen/X86/tailcall-caller-nocsr.ll b/llvm/test/CodeGen/X86/tailcall-caller-nocsr.ll
new file mode 100644
index 00000000000000..0385017a1ced73
--- /dev/null
+++ b/llvm/test/CodeGen/X86/tailcall-caller-nocsr.ll
@@ -0,0 +1,34 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc < %s -mtriple=x86_64-linux-gnu -mattr=-sse,-avx | FileCheck %s
+
+ at .str = private unnamed_addr constant [6 x i8] c"%d %d\00", align 1
+
+define void @caller(i32 %0, i32 %1) #0 {
+; CHECK-LABEL: caller:
+; CHECK: # %bb.0:
+; CHECK-NEXT: pushq %r11
+; CHECK-NEXT: pushq %r10
+; CHECK-NEXT: pushq %r9
+; CHECK-NEXT: pushq %r8
+; CHECK-NEXT: pushq %rdx
+; CHECK-NEXT: pushq %rcx
+; CHECK-NEXT: pushq %rax
+; CHECK-NEXT: movl %esi, %edx
+; CHECK-NEXT: movl %edi, %esi
+; CHECK-NEXT: movl $.L.str, %edi
+; CHECK-NEXT: callq printf at PLT
+; CHECK-NEXT: popq %rax
+; CHECK-NEXT: popq %rcx
+; CHECK-NEXT: popq %rdx
+; CHECK-NEXT: popq %r8
+; CHECK-NEXT: popq %r9
+; CHECK-NEXT: popq %r10
+; CHECK-NEXT: popq %r11
+; CHECK-NEXT: retq
+ %3 = tail call i32 @printf(ptr @.str, i32 %0, i32 %1)
+ ret void
+}
+
+declare i32 @printf(ptr, ...) nounwind
+
+attributes #0 = { mustprogress nounwind "no_caller_saved_registers" }
``````````
</details>
https://github.com/llvm/llvm-project/pull/112098
More information about the llvm-commits
mailing list