From a44126f4322eef7637427d99675711e44a89941e Mon Sep 17 00:00:00 2001 From: Jan Wen Voung Date: Fri, 5 Dec 2014 20:55:53 +0000 Subject: [PATCH] Use 32-bit ebp for NaCl64 in a limited case: llvm.frameaddress. Summary: Follow up to [x32] "Use ebp/esp as frame and stack pointer": http://reviews.llvm.org/D4617 In that earlier patch, NaCl64 was made to always use rbp. That's needed for most cases because rbp should hold a full 64-bit address within the NaCl sandbox so that load/stores off of rbp don't require sandbox adjustment (zeroing the top 32-bits, then filling those by adding r15). However, llvm.frameaddress returns a pointer and pointers are 32-bit for NaCl64. In this case, use ebp instead, which will make the register copy type check. A similar mechanism may be needed for llvm.eh.return, but is not added in this change. Test Plan: test/CodeGen/X86/frameaddr.ll Reviewers: dschuff, nadav Subscribers: jfb, llvm-commits Differential Revision: http://reviews.llvm.org/D6514 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@223510 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86FastISel.cpp | 6 +++--- lib/Target/X86/X86ISelLowering.cpp | 3 ++- lib/Target/X86/X86RegisterInfo.cpp | 8 ++++++++ lib/Target/X86/X86RegisterInfo.h | 1 + test/CodeGen/X86/frameaddr.ll | 11 +++++++++++ 5 files changed, 25 insertions(+), 4 deletions(-) diff --git a/lib/Target/X86/X86FastISel.cpp b/lib/Target/X86/X86FastISel.cpp index ed3a0a5939cd..6c915cfaf5c9 100644 --- a/lib/Target/X86/X86FastISel.cpp +++ b/lib/Target/X86/X86FastISel.cpp @@ -2143,14 +2143,14 @@ bool X86FastISel::fastLowerIntrinsicCall(const IntrinsicInst *II) { case MVT::i64: Opc = X86::MOV64rm; RC = &X86::GR64RegClass; break; } - // This needs to be set before we call getFrameRegister, otherwise we get - // the wrong frame register. + // This needs to be set before we call getPtrSizedFrameRegister, otherwise + // we get the wrong frame register. MachineFrameInfo *MFI = FuncInfo.MF->getFrameInfo(); MFI->setFrameAddressIsTaken(true); const X86RegisterInfo *RegInfo = static_cast( TM.getSubtargetImpl()->getRegisterInfo()); - unsigned FrameReg = RegInfo->getFrameRegister(*(FuncInfo.MF)); + unsigned FrameReg = RegInfo->getPtrSizedFrameRegister(*(FuncInfo.MF)); assert(((FrameReg == X86::RBP && VT == MVT::i64) || (FrameReg == X86::EBP && VT == MVT::i32)) && "Invalid Frame Register!"); diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 6d5a10feab15..a0009eb9a8dd 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -17636,7 +17636,8 @@ SDValue X86TargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const { unsigned Depth = cast(Op.getOperand(0))->getZExtValue(); const X86RegisterInfo *RegInfo = static_cast( DAG.getSubtarget().getRegisterInfo()); - unsigned FrameReg = RegInfo->getFrameRegister(DAG.getMachineFunction()); + unsigned FrameReg = RegInfo->getPtrSizedFrameRegister( + DAG.getMachineFunction()); assert(((FrameReg == X86::RBP && VT == MVT::i64) || (FrameReg == X86::EBP && VT == MVT::i32)) && "Invalid Frame Register!"); diff --git a/lib/Target/X86/X86RegisterInfo.cpp b/lib/Target/X86/X86RegisterInfo.cpp index a4a366da893c..09e651cebfb9 100644 --- a/lib/Target/X86/X86RegisterInfo.cpp +++ b/lib/Target/X86/X86RegisterInfo.cpp @@ -535,6 +535,14 @@ unsigned X86RegisterInfo::getFrameRegister(const MachineFunction &MF) const { return TFI->hasFP(MF) ? FramePtr : StackPtr; } +unsigned X86RegisterInfo::getPtrSizedFrameRegister( + const MachineFunction &MF) const { + unsigned FrameReg = getFrameRegister(MF); + if (Subtarget.isTarget64BitILP32()) + FrameReg = getX86SubSuperRegister(FrameReg, MVT::i32, false); + return FrameReg; +} + namespace llvm { unsigned getX86SubSuperRegister(unsigned Reg, MVT::SimpleValueType VT, bool High) { diff --git a/lib/Target/X86/X86RegisterInfo.h b/lib/Target/X86/X86RegisterInfo.h index cc0a7b2d82c3..406b1fcd8d0f 100644 --- a/lib/Target/X86/X86RegisterInfo.h +++ b/lib/Target/X86/X86RegisterInfo.h @@ -122,6 +122,7 @@ class X86RegisterInfo final : public X86GenRegisterInfo { // Debug information queries. unsigned getFrameRegister(const MachineFunction &MF) const override; + unsigned getPtrSizedFrameRegister(const MachineFunction &MF) const; unsigned getStackRegister() const { return StackPtr; } unsigned getBaseRegister() const { return BasePtr; } // FIXME: Move to FrameInfok diff --git a/test/CodeGen/X86/frameaddr.ll b/test/CodeGen/X86/frameaddr.ll index 452c8e5a21af..3e0f8bc34d64 100644 --- a/test/CodeGen/X86/frameaddr.ll +++ b/test/CodeGen/X86/frameaddr.ll @@ -4,6 +4,8 @@ ; RUN: llc < %s -march=x86-64 -fast-isel -fast-isel-abort | FileCheck %s --check-prefix=CHECK-64 ; RUN: llc < %s -mtriple=x86_64-gnux32 | FileCheck %s --check-prefix=CHECK-X32ABI ; RUN: llc < %s -mtriple=x86_64-gnux32 -fast-isel -fast-isel-abort | FileCheck %s --check-prefix=CHECK-X32ABI +; RUN: llc < %s -mtriple=x86_64-nacl | FileCheck %s --check-prefix=CHECK-NACL64 +; RUN: llc < %s -mtriple=x86_64-nacl -fast-isel -fast-isel-abort | FileCheck %s --check-prefix=CHECK-NACL64 define i8* @test1() nounwind { entry: @@ -25,6 +27,10 @@ entry: ; CHECK-X32ABI-NEXT: movl %ebp, %eax ; CHECK-X32ABI-NEXT: popq %rbp ; CHECK-X32ABI-NEXT: ret +; CHECK-NACL64-LABEL: test1 +; CHECK-NACL64: pushq %rbp +; CHECK-NACL64-NEXT: movq %rsp, %rbp +; CHECK-NACL64-NEXT: movl %ebp, %eax %0 = tail call i8* @llvm.frameaddress(i32 0) ret i8* %0 } @@ -52,6 +58,11 @@ entry: ; CHECK-X32ABI-NEXT: movl (%eax), %eax ; CHECK-X32ABI-NEXT: popq %rbp ; CHECK-X32ABI-NEXT: ret +; CHECK-NACL64-LABEL: test2 +; CHECK-NACL64: pushq %rbp +; CHECK-NACL64-NEXT: movq %rsp, %rbp +; CHECK-NACL64-NEXT: movl (%ebp), %eax +; CHECK-NACL64-NEXT: movl (%eax), %eax %0 = tail call i8* @llvm.frameaddress(i32 2) ret i8* %0 }