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<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,
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]*$}}