Skip to content

Commit d3a8363

Browse files
[X86] Do not elect to tail call if caller must preserve all registers
A miscompilation issue has been addressed with improved checking. Fixes: #97758.
1 parent c137b3e commit d3a8363

File tree

2 files changed

+10
-1
lines changed

2 files changed

+10
-1
lines changed

llvm/lib/Target/X86/X86ISelLoweringCall.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2856,6 +2856,13 @@ bool X86TargetLowering::IsEligibleForTailCallOptimization(
28562856
return false;
28572857
}
28582858

2859+
// The stack frame of the caller cannot be replaced by the tail-callee one's
2860+
// if the function is required to preserve all the registers. Conservatively
2861+
// prevent tail optimization even if hypothetically all the registers are used
2862+
// for passing formal parameters or returning values.
2863+
if (CallerF.hasFnAttribute("no_caller_saved_registers"))
2864+
return false;
2865+
28592866
unsigned StackArgsSize = CCInfo.getStackSize();
28602867

28612868
// If the callee takes no arguments then go on to check the results of the

llvm/test/CodeGen/X86/tailcall-caller-nocsr.ll

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,18 @@ define void @caller(i32 %0, i32 %1) #0 {
1313
; CHECK-NEXT: pushq %rdx
1414
; CHECK-NEXT: pushq %rcx
1515
; CHECK-NEXT: pushq %rax
16+
; CHECK-NEXT: movl %esi, %edx
1617
; CHECK-NEXT: movl %edi, %esi
1718
; CHECK-NEXT: movl $.L.str, %edi
19+
; CHECK-NEXT: callq printf@PLT
1820
; CHECK-NEXT: popq %rax
1921
; CHECK-NEXT: popq %rcx
2022
; CHECK-NEXT: popq %rdx
2123
; CHECK-NEXT: popq %r8
2224
; CHECK-NEXT: popq %r9
2325
; CHECK-NEXT: popq %r10
2426
; CHECK-NEXT: popq %r11
25-
; CHECK-NEXT: jmp printf@PLT # TAILCALL
27+
; CHECK-NEXT: retq
2628
%3 = tail call i32 @printf(ptr @.str, i32 %0, i32 %1)
2729
ret void
2830
}

0 commit comments

Comments
 (0)