[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:
Dario Domizioli 2014-11-11 18:44:49 +00:00
parent 659b1491b8
commit 949d328bee
2 changed files with 38 additions and 0 deletions

View File

@ -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);

View 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
}