[llvm] r221695 - [X86][ELF] Fix PR20243 - leaf frame pointer bug with TLS access

Dario Domizioli dario.domizioli at gmail.com
Tue Nov 11 10:44:49 PST 2014


Author: ddomizioli
Date: Tue Nov 11 12:44:49 2014
New Revision: 221695

URL: http://llvm.org/viewvc/llvm-project?rev=221695&view=rev
Log:
[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.



Added:
    llvm/trunk/test/CodeGen/X86/tls-addr-non-leaf-function.ll
Modified:
    llvm/trunk/lib/Target/X86/X86ISelLowering.cpp

Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=221695&r1=221694&r2=221695&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Tue Nov 11 12:44:49 2014
@@ -12792,6 +12792,7 @@ GetTLSADDR(SelectionDAG &DAG, SDValue Ch
 
   // 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);

Added: llvm/trunk/test/CodeGen/X86/tls-addr-non-leaf-function.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tls-addr-non-leaf-function.ll?rev=221695&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/tls-addr-non-leaf-function.ll (added)
+++ llvm/trunk/test/CodeGen/X86/tls-addr-non-leaf-function.ll Tue Nov 11 12:44:49 2014
@@ -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 at TLSGD(%rip), %rdi
+; CHECK: callq __tls_get_addr at PLT
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+ at x = thread_local global i32 0
+define i32 @foo() "no-frame-pointer-elim-non-leaf" {
+  %a = load i32* @x, align 4
+  ret i32 %a
+}





More information about the llvm-commits mailing list