Index: llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.h =================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.h +++ llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.h @@ -104,6 +104,7 @@ 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 Index: llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp =================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp +++ llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp @@ -131,6 +131,15 @@ return CSR_iOS_TLSCall_RegMask; } +const uint32_t * +ARMBaseRegisterInfo::getSjLjDispatchPreservedMask(const MachineFunction &MF) const { + const ARMSubtarget &STI = MF.getSubtarget(); + if (!STI.useSoftFloat() && STI.hasVFP2() && !STI.isThumb1Only()) + return CSR_NoRegs_RegMask; + else + return CSR_FPRegs_RegMask; +} + const uint32_t * ARMBaseRegisterInfo::getThisReturnPreservedMask(const MachineFunction &MF, Index: llvm/trunk/lib/Target/ARM/ARMCallingConv.td =================================================================== --- llvm/trunk/lib/Target/ARM/ARMCallingConv.td +++ llvm/trunk/lib/Target/ARM/ARMCallingConv.td @@ -242,6 +242,7 @@ //===----------------------------------------------------------------------===// 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))>; Index: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp =================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp @@ -7865,8 +7865,10 @@ 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(); Index: llvm/trunk/test/CodeGen/ARM/eh-dispcont.ll =================================================================== --- llvm/trunk/test/CodeGen/ARM/eh-dispcont.ll +++ llvm/trunk/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 #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 @@ ; 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 @@ ; THUMB1-NOPIC: .long [[LABEL:LBB0_[0-9]]]+1 ; THUMB1-NOPIC: .end_data_region ; THUMB1-NOPIC: [[LABEL]] + +; THUMB1-NOT: vld +; THUMB1: pop {{[^d]*$}}