summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp9
-rw-r--r--llvm/lib/Target/ARM/ARMBaseRegisterInfo.h1
-rw-r--r--llvm/lib/Target/ARM/ARMCallingConv.td1
-rw-r--r--llvm/lib/Target/ARM/ARMISelLowering.cpp6
-rw-r--r--llvm/test/CodeGen/ARM/eh-dispcont.ll30
5 files changed, 39 insertions, 8 deletions
diff --git a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
index 2f8b56032cc..bc759dbe8cc 100644
--- a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
@@ -131,6 +131,15 @@ ARMBaseRegisterInfo::getTLSCallPreservedMask(const MachineFunction &MF) const {
return CSR_iOS_TLSCall_RegMask;
}
+const uint32_t *
+ARMBaseRegisterInfo::getSjLjDispatchPreservedMask(const MachineFunction &MF) const {
+ const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>();
+ if (!STI.useSoftFloat() && STI.hasVFP2() && !STI.isThumb1Only())
+ return CSR_NoRegs_RegMask;
+ else
+ return CSR_FPRegs_RegMask;
+}
+
const uint32_t *
ARMBaseRegisterInfo::getThisReturnPreservedMask(const MachineFunction &MF,
diff --git a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h
index 06d0f790241..330e1535e86 100644
--- a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h
+++ b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h
@@ -104,6 +104,7 @@ public:
CallingConv::ID) const override;
const uint32_t *getNoPreservedMask() const override;
const uint32_t *getTLSCallPreservedMask(const MachineFunction &MF) const;
+ const uint32_t *getSjLjDispatchPreservedMask(const MachineFunction &MF) const;
/// getThisReturnPreservedMask - Returns a call preserved mask specific to the
/// case that 'returned' is on an i32 first argument if the calling convention
diff --git a/llvm/lib/Target/ARM/ARMCallingConv.td b/llvm/lib/Target/ARM/ARMCallingConv.td
index edb69581b9d..9c278a52a7f 100644
--- a/llvm/lib/Target/ARM/ARMCallingConv.td
+++ b/llvm/lib/Target/ARM/ARMCallingConv.td
@@ -242,6 +242,7 @@ def RetCC_ARM_AAPCS_VFP : CallingConv<[
//===----------------------------------------------------------------------===//
def CSR_NoRegs : CalleeSavedRegs<(add)>;
+def CSR_FPRegs : CalleeSavedRegs<(add (sequence "D%u", 0, 31))>;
def CSR_AAPCS : CalleeSavedRegs<(add LR, R11, R10, R9, R8, R7, R6, R5, R4,
(sequence "D%u", 15, 8))>;
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index ba2c2866a5c..7623841a8e3 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -7865,8 +7865,10 @@ void ARMTargetLowering::EmitSjLjDispatchBlock(MachineInstr &MI,
const ARMBaseRegisterInfo &RI = AII->getRegisterInfo();
// Add a register mask with no preserved registers. This results in all
- // registers being marked as clobbered.
- MIB.addRegMask(RI.getNoPreservedMask());
+ // registers being marked as clobbered. This can't work if the dispatch block
+ // is in a Thumb1 function and is linked with ARM code which uses the FP
+ // registers, as there is no way to preserve the FP registers in Thumb1 mode.
+ MIB.addRegMask(RI.getSjLjDispatchPreservedMask(*MF));
bool IsPositionIndependent = isPositionIndependent();
unsigned NumLPads = LPadList.size();
diff --git a/llvm/test/CodeGen/ARM/eh-dispcont.ll b/llvm/test/CodeGen/ARM/eh-dispcont.ll
index e9871aa7dc7..d6d93818a88 100644
--- a/llvm/test/CodeGen/ARM/eh-dispcont.ll
+++ b/llvm/test/CodeGen/ARM/eh-dispcont.ll
@@ -1,9 +1,9 @@
-; RUN: llc -mtriple armv7-apple-ios -relocation-model=pic -o - %s | FileCheck %s -check-prefix=ARM-PIC
-; RUN: llc -mtriple armv7-apple-ios -relocation-model=static -o - %s | FileCheck %s -check-prefix=ARM-NOPIC
-; RUN: llc -mtriple armv7-apple-ios -relocation-model=dynamic-no-pic -o - %s | FileCheck %s -check-prefix=ARM-NOPIC
-; RUN: llc -mtriple thumbv6-apple-ios -relocation-model=pic -o - %s | FileCheck %s -check-prefix=THUMB1-PIC
-; RUN: llc -mtriple thumbv6-apple-ios -relocation-model=static -o - %s | FileCheck %s -check-prefix=THUMB1-NOPIC
-; RUN: llc -mtriple thumbv6-apple-ios -relocation-model=dynamic-no-pic -o - %s | FileCheck %s -check-prefix=THUMB1-NOPIC
+; RUN: llc -mtriple armv7-apple-ios -relocation-model=pic -o - %s | FileCheck %s -check-prefix=ARM-PIC -check-prefix=ARM
+; RUN: llc -mtriple armv7-apple-ios -relocation-model=static -o - %s | FileCheck %s -check-prefix=ARM-NOPIC -check-prefix=ARM
+; RUN: llc -mtriple armv7-apple-ios -relocation-model=dynamic-no-pic -o - %s | FileCheck %s -check-prefix=ARM-NOPIC -check-prefix=ARM
+; RUN: llc -mtriple thumbv6-apple-ios -relocation-model=pic -o - %s | FileCheck %s -check-prefix=THUMB1-PIC -check-prefix=THUMB1
+; RUN: llc -mtriple thumbv6-apple-ios -relocation-model=static -o - %s | FileCheck %s -check-prefix=THUMB1-NOPIC -check-prefix=THUMB1
+; RUN: llc -mtriple thumbv6-apple-ios -relocation-model=dynamic-no-pic -o - %s | FileCheck %s -check-prefix=THUMB1-NOPIC -check-prefix=THUMB1
@_ZTIi = external constant i8*
@@ -41,6 +41,9 @@ attributes #0 = { ssp }
attributes #1 = { nounwind }
attributes #2 = { noreturn }
+; ARM: vst1.64
+; ARM: vst1.64
+
; ARM-PIC: cxa_throw
; ARM-PIC: trap
; ARM-PIC: adr [[REG1:r[0-9]+]], [[LJTI:.*]]
@@ -63,6 +66,18 @@ attributes #2 = { noreturn }
; ARM-NOPIC: .end_data_region
; ARM-NOPIC: [[LABEL]]
+; ARM: vld1.64
+; ARM: vld1.64
+
+; On Thumb1 targets, we have no way to preserve the floating-point registers.
+; If all other code is built for Thumb1 or is built soft-float, this is not a
+; problem as the FP regs don't need saving. However, if this code is linked
+; against ARM code that uses the FP regs, they won't be restored correctly. We
+; don't support this use-case, but have no way to prevent it in the compiler.
+
+; THUMB1: push {{[^d]*$}}
+; THUMB1-NOT: vst
+
; THUMB1-PIC: cxa_throw
; THUMB1-PIC: trap
; THUMB1-PIC: adr [[REG1:r[0-9]+]], [[LJTI:.*]]
@@ -87,3 +102,6 @@ attributes #2 = { noreturn }
; THUMB1-NOPIC: .long [[LABEL:LBB0_[0-9]]]+1
; THUMB1-NOPIC: .end_data_region
; THUMB1-NOPIC: [[LABEL]]
+
+; THUMB1-NOT: vld
+; THUMB1: pop {{[^d]*$}}
OpenPOWER on IntegriCloud