From 6b97ebe9a32342207b24a5f73ebbf3070ec8d189 Mon Sep 17 00:00:00 2001 From: Stephen Lin Date: Wed, 26 Jun 2013 21:42:14 +0000 Subject: [PATCH] ARM: Proactively ensure that the LowerCallResult hack for 'this'-returns is not used for incompatible calling conventions. (Currently, ARM 'this'-returns are handled in the standard calling convention case by treating R0 as preserved and doing some extra magic in LowerCallResult; this may not apply to calling conventions added in the future so this patch provides and documents an interface for indicating such) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@185024 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMBaseRegisterInfo.cpp | 3 +++ lib/Target/ARM/ARMBaseRegisterInfo.h | 11 ++++++++++- lib/Target/ARM/ARMISelLowering.cpp | 13 ++++++++++--- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/lib/Target/ARM/ARMBaseRegisterInfo.cpp index 3ba3b625d7d..0e1e50e5293 100644 --- a/lib/Target/ARM/ARMBaseRegisterInfo.cpp +++ b/lib/Target/ARM/ARMBaseRegisterInfo.cpp @@ -75,6 +75,9 @@ const uint32_t* ARMBaseRegisterInfo::getThisReturnPreservedMask(CallingConv::ID) const { return (STI.isTargetIOS() && !STI.isAAPCS_ABI()) ? CSR_iOS_ThisReturn_RegMask : CSR_AAPCS_ThisReturn_RegMask; + // This should return NULL in the case of any calling convention that does + // not use the same register for an i32 first argument and an i32 return + // value } const uint32_t* diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.h b/lib/Target/ARM/ARMBaseRegisterInfo.h index 03b36825419..be3f1368f69 100644 --- a/lib/Target/ARM/ARMBaseRegisterInfo.h +++ b/lib/Target/ARM/ARMBaseRegisterInfo.h @@ -94,9 +94,18 @@ public: /// Code Generation virtual methods... const uint16_t *getCalleeSavedRegs(const MachineFunction *MF = 0) const; const uint32_t *getCallPreservedMask(CallingConv::ID) const; - const uint32_t *getThisReturnPreservedMask(CallingConv::ID) const; const uint32_t *getNoPreservedMask() const; + // getThisReturnPreservedMask - Returns a call preserved mask specific to the + // case that 'returned' is an i32 first argument if the calling convention + // is one that can (partially) model this attribute with a preserved mask + // (i.e. it is a calling convention that uses the same register for the first + // i32 argument and an i32 return value) + // + // Should return NULL in the case that the calling convention does not have + // this property + const uint32_t *getThisReturnPreservedMask(CallingConv::ID) const; + BitVector getReservedRegs(const MachineFunction &MF) const; const TargetRegisterClass* diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index 6b981d5ba52..c8d73d76d75 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -1711,10 +1711,17 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, const uint32_t *Mask; const TargetRegisterInfo *TRI = getTargetMachine().getRegisterInfo(); const ARMBaseRegisterInfo *ARI = static_cast(TRI); - if (isThisReturn) - // For 'this' returns, use the R0-preserving mask + if (isThisReturn) { + // For 'this' returns, use the R0-preserving mask if applicable Mask = ARI->getThisReturnPreservedMask(CallConv); - else + if (!Mask) { + // Set isThisReturn to false if the calling convention is not one that + // allows 'returned' to be modeled in this way, so LowerCallResult does + // not try to pass 'this' straight through + isThisReturn = false; + Mask = ARI->getCallPreservedMask(CallConv); + } + } else Mask = ARI->getCallPreservedMask(CallConv); assert(Mask && "Missing call preserved mask for calling convention"); -- 2.34.1