mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-02 07:11:49 +00:00
[X86][ELF] Fix PR20243 - leaf frame pointer bug with TLS access
The ISel lowering for global TLS access in PIC mode was creating a pseudo instruction that is later expanded to a call, but the code was not setting the hasCalls flag in the MachineFrameInfo alongside the adjustsStack flag. This caused some functions to be mistakenly recognized as leaf functions, and this in turn affected the decision to eliminate the frame pointer. With the fix, hasCalls is properly set and the leaf frame pointer is correctly preserved. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@221695 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
659b1491b8
commit
949d328bee
@ -12792,6 +12792,7 @@ GetTLSADDR(SelectionDAG &DAG, SDValue Chain, GlobalAddressSDNode *GA,
|
||||
|
||||
// TLSADDR will be codegen'ed as call. Inform MFI that function has calls.
|
||||
MFI->setAdjustsStack(true);
|
||||
MFI->setHasCalls(true);
|
||||
|
||||
SDValue Flag = Chain.getValue(1);
|
||||
return DAG.getCopyFromReg(Chain, dl, ReturnReg, PtrVT, Flag);
|
||||
|
37
test/CodeGen/X86/tls-addr-non-leaf-function.ll
Normal file
37
test/CodeGen/X86/tls-addr-non-leaf-function.ll
Normal file
@ -0,0 +1,37 @@
|
||||
; RUN: llc < %s -relocation-model=pic -O2 -disable-fp-elim -o - | FileCheck %s
|
||||
; RUN: llc < %s -relocation-model=pic -O2 -o - | FileCheck %s
|
||||
|
||||
; This test runs twice with different options regarding the frame pointer:
|
||||
; first the elimination is disabled, then it is enabled. The disabled case is
|
||||
; the "control group".
|
||||
; The function 'foo' below is marked with the "no-frame-pointer-elim-non-leaf"
|
||||
; attribute which dictates that the frame pointer should not be eliminated
|
||||
; unless the function is a leaf (i.e. it doesn't call any other function).
|
||||
; Now, 'foo' is not a leaf function, because it performs a TLS access which on
|
||||
; X86 ELF in PIC mode is expanded as a library call.
|
||||
; This call is represented with a pseudo-instruction which doesn't appear to be
|
||||
; a call when inspected by the analysis passes (it doesn't have the "isCall"
|
||||
; flag), and the ISel lowering code creating the pseudo was not informing the
|
||||
; MachineFrameInfo that the function contained calls. This affected the decision
|
||||
; whether to eliminate the frame pointer.
|
||||
; With the fix, the "hasCalls" flag is set in the MFI for the function whenever
|
||||
; a TLS access pseudo-instruction is created, so 'foo' appears to be a non-leaf
|
||||
; function, and the difference in the options does not affect codegen: both
|
||||
; versions will have a frame pointer.
|
||||
|
||||
; Test that there's some frame pointer usage in 'foo'...
|
||||
; CHECK: foo:
|
||||
; CHECK: pushq %rbp
|
||||
; CHECK: movq %rsp, %rbp
|
||||
; ... and the TLS library call is also present.
|
||||
; CHECK: leaq x@TLSGD(%rip), %rdi
|
||||
; CHECK: callq __tls_get_addr@PLT
|
||||
|
||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
@x = thread_local global i32 0
|
||||
define i32 @foo() "no-frame-pointer-elim-non-leaf" {
|
||||
%a = load i32* @x, align 4
|
||||
ret i32 %a
|
||||
}
|
Loading…
Reference in New Issue
Block a user