[libcxx-commits] [libcxxabi] da1d1a0 - [ARM] __cxa_end_cleanup should be called instead of _UnwindResume.

Daniel Kiss via libcxx-commits libcxx-commits at lists.llvm.org
Wed Oct 27 01:40:06 PDT 2021


Author: Daniel Kiss
Date: 2021-10-27T10:40:00+02:00
New Revision: da1d1a08694bbfe0ea7a23ea094612436e8a2dd0

URL: https://github.com/llvm/llvm-project/commit/da1d1a08694bbfe0ea7a23ea094612436e8a2dd0
DIFF: https://github.com/llvm/llvm-project/commit/da1d1a08694bbfe0ea7a23ea094612436e8a2dd0.diff

LOG: [ARM] __cxa_end_cleanup should be called instead of _UnwindResume.

ARM EHABI[1] specifies the __cxa_end_cleanup to be called after cleanup.
It will call the UnwindResume.
__cxa_begin_cleanup will be called from libcxxabi while __cxa_end_cleanup is never called.
This will trigger a termination when a foreign exception is processed while UnwindResume is called
because the global state will be wrong due to the missing __cxa_end_cleanup call.

Additional test here: D109856
[1] https://github.com/ARM-software/abi-aa/blob/main/ehabi32/ehabi32.rst#941compiler-helper-functions

Reviewed By: logan

Differential Revision: https://reviews.llvm.org/D111703

Added: 
    llvm/test/CodeGen/ARM/eh-resume.ll
    llvm/test/CodeGen/ARM/eh-resume2.ll

Modified: 
    libcxxabi/src/cxa_exception.cpp
    llvm/include/llvm/ADT/Triple.h
    llvm/include/llvm/IR/RuntimeLibcalls.def
    llvm/lib/CodeGen/DwarfEHPrepare.cpp
    llvm/lib/Target/ARM/ARMSubtarget.h
    llvm/test/CodeGen/ARM/debug-frame.ll
    llvm/test/CodeGen/ARM/ehabi.ll

Removed: 
    llvm/test/CodeGen/ARM/eh-resume-darwin.ll


################################################################################
diff  --git a/libcxxabi/src/cxa_exception.cpp b/libcxxabi/src/cxa_exception.cpp
index 35956f197f59d..593fdbec2b1b3 100644
--- a/libcxxabi/src/cxa_exception.cpp
+++ b/libcxxabi/src/cxa_exception.cpp
@@ -341,8 +341,10 @@ unwinding with _Unwind_Resume.
 According to ARM EHABI 8.4.1, __cxa_end_cleanup() should not clobber any
 register, thus we have to write this function in assembly so that we can save
 {r1, r2, r3}.  We don't have to save r0 because it is the return value and the
-first argument to _Unwind_Resume().  In addition, we are saving r4 in order to
-align the stack to 16 bytes, even though it is a callee-save register.
+first argument to _Unwind_Resume().  In addition, we are saving lr in order to
+align the stack to 16 bytes and lr will be used to identify the caller and its
+frame information. _Unwind_Resume never return and we need to keep the original
+lr so just branch to it.
 */
 __attribute__((used)) static _Unwind_Exception *
 __cxa_end_cleanup_impl()
@@ -372,18 +374,15 @@ __cxa_end_cleanup_impl()
     return &exception_header->unwindHeader;
 }
 
-asm (
-    "	.pushsection	.text.__cxa_end_cleanup,\"ax\",%progbits\n"
+asm("	.pushsection	.text.__cxa_end_cleanup,\"ax\",%progbits\n"
     "	.globl	__cxa_end_cleanup\n"
     "	.type	__cxa_end_cleanup,%function\n"
     "__cxa_end_cleanup:\n"
-    "	push	{r1, r2, r3, r4}\n"
+    "	push	{r1, r2, r3, lr}\n"
     "	bl	__cxa_end_cleanup_impl\n"
-    "	pop	{r1, r2, r3, r4}\n"
-    "	bl	_Unwind_Resume\n"
-    "	bl	abort\n"
-    "	.popsection"
-);
+    "	pop	{r1, r2, r3, lr}\n"
+    "	b	_Unwind_Resume\n"
+    "	.popsection");
 #endif // defined(_LIBCXXABI_ARM_EHABI)
 
 /*

diff  --git a/llvm/include/llvm/ADT/Triple.h b/llvm/include/llvm/ADT/Triple.h
index e18fbf5c8457f..27eada6a3e3c4 100644
--- a/llvm/include/llvm/ADT/Triple.h
+++ b/llvm/include/llvm/ADT/Triple.h
@@ -721,6 +721,18 @@ class Triple {
     return getArch() == Triple::arm || getArch() == Triple::armeb;
   }
 
+  /// Tests whether the target supports the EHABI exception
+  /// handling standard.
+  bool isTargetEHABICompatible() const {
+    return (getEnvironment() == Triple::EABI ||
+            getEnvironment() == Triple::GNUEABI ||
+            getEnvironment() == Triple::MuslEABI ||
+            getEnvironment() == Triple::EABIHF ||
+            getEnvironment() == Triple::GNUEABIHF ||
+            getEnvironment() == Triple::MuslEABIHF || isAndroid()) &&
+           isOSBinFormatELF();
+  }
+
   /// Tests whether the target is AArch64 (little and big endian).
   bool isAArch64() const {
     return getArch() == Triple::aarch64 || getArch() == Triple::aarch64_be ||

diff  --git a/llvm/include/llvm/IR/RuntimeLibcalls.def b/llvm/include/llvm/IR/RuntimeLibcalls.def
index dd28780ac946f..5f295660557ad 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.def
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.def
@@ -432,6 +432,7 @@ HANDLE_LIBCALL(MEMSET_ELEMENT_UNORDERED_ATOMIC_16, "__llvm_memset_element_unorde
 
 // Exception handling
 HANDLE_LIBCALL(UNWIND_RESUME, "_Unwind_Resume")
+HANDLE_LIBCALL(CXA_END_CLEANUP, "__cxa_end_cleanup")
 
 // Note: there are two sets of atomics libcalls; see
 // <https://llvm.org/docs/Atomics.html> for more info on the

diff  --git a/llvm/lib/CodeGen/DwarfEHPrepare.cpp b/llvm/lib/CodeGen/DwarfEHPrepare.cpp
index fde7b942665d4..fb8a3e383950c 100644
--- a/llvm/lib/CodeGen/DwarfEHPrepare.cpp
+++ b/llvm/lib/CodeGen/DwarfEHPrepare.cpp
@@ -14,6 +14,7 @@
 #include "llvm/ADT/BitVector.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/Triple.h"
 #include "llvm/Analysis/CFG.h"
 #include "llvm/Analysis/DomTreeUpdater.h"
 #include "llvm/Analysis/EHPersonalities.h"
@@ -54,13 +55,11 @@ namespace {
 class DwarfEHPrepare {
   CodeGenOpt::Level OptLevel;
 
-  // RewindFunction - _Unwind_Resume or the target equivalent.
-  FunctionCallee &RewindFunction;
-
   Function &F;
   const TargetLowering &TLI;
   DomTreeUpdater *DTU;
   const TargetTransformInfo *TTI;
+  const Triple &TargetTriple;
 
   /// Return the exception object from the value passed into
   /// the 'resume' instruction (typically an aggregate). Clean up any dead
@@ -78,11 +77,11 @@ class DwarfEHPrepare {
   bool InsertUnwindResumeCalls();
 
 public:
-  DwarfEHPrepare(CodeGenOpt::Level OptLevel_, FunctionCallee &RewindFunction_,
-                 Function &F_, const TargetLowering &TLI_, DomTreeUpdater *DTU_,
-                 const TargetTransformInfo *TTI_)
-      : OptLevel(OptLevel_), RewindFunction(RewindFunction_), F(F_), TLI(TLI_),
-        DTU(DTU_), TTI(TTI_) {}
+  DwarfEHPrepare(CodeGenOpt::Level OptLevel_, Function &F_,
+                 const TargetLowering &TLI_, DomTreeUpdater *DTU_,
+                 const TargetTransformInfo *TTI_, const Triple &TargetTriple_)
+      : OptLevel(OptLevel_), F(F_), TLI(TLI_), DTU(DTU_), TTI(TTI_),
+        TargetTriple(TargetTriple_) {}
 
   bool run();
 };
@@ -211,13 +210,28 @@ bool DwarfEHPrepare::InsertUnwindResumeCalls() {
   if (ResumesLeft == 0)
     return true; // We pruned them all.
 
-  // Find the rewind function if we didn't already.
-  if (!RewindFunction) {
-    FunctionType *FTy =
+  // RewindFunction - _Unwind_Resume or the target equivalent.
+  FunctionCallee RewindFunction;
+  CallingConv::ID RewindFunctionCallingConv;
+  FunctionType *FTy;
+  const char *RewindName;
+  bool DoesRewindFunctionNeedExceptionObject;
+
+  if ((Pers == EHPersonality::GNU_CXX || Pers == EHPersonality::GNU_CXX_SjLj) &&
+      TargetTriple.isTargetEHABICompatible()) {
+    RewindName = TLI.getLibcallName(RTLIB::CXA_END_CLEANUP);
+    FTy = FunctionType::get(Type::getVoidTy(Ctx), false);
+    RewindFunctionCallingConv =
+        TLI.getLibcallCallingConv(RTLIB::CXA_END_CLEANUP);
+    DoesRewindFunctionNeedExceptionObject = false;
+  } else {
+    RewindName = TLI.getLibcallName(RTLIB::UNWIND_RESUME);
+    FTy =
         FunctionType::get(Type::getVoidTy(Ctx), Type::getInt8PtrTy(Ctx), false);
-    const char *RewindName = TLI.getLibcallName(RTLIB::UNWIND_RESUME);
-    RewindFunction = F.getParent()->getOrInsertFunction(RewindName, FTy);
+    RewindFunctionCallingConv = TLI.getLibcallCallingConv(RTLIB::UNWIND_RESUME);
+    DoesRewindFunctionNeedExceptionObject = true;
   }
+  RewindFunction = F.getParent()->getOrInsertFunction(RewindName, FTy);
 
   // Create the basic block where the _Unwind_Resume call will live.
   if (ResumesLeft == 1) {
@@ -226,10 +240,14 @@ bool DwarfEHPrepare::InsertUnwindResumeCalls() {
     ResumeInst *RI = Resumes.front();
     BasicBlock *UnwindBB = RI->getParent();
     Value *ExnObj = GetExceptionObject(RI);
+    llvm::SmallVector<Value *, 1> RewindFunctionArgs;
+    if (DoesRewindFunctionNeedExceptionObject)
+      RewindFunctionArgs.push_back(ExnObj);
 
-    // Call the _Unwind_Resume function.
-    CallInst *CI = CallInst::Create(RewindFunction, ExnObj, "", UnwindBB);
-    CI->setCallingConv(TLI.getLibcallCallingConv(RTLIB::UNWIND_RESUME));
+    // Call the rewind function.
+    CallInst *CI =
+        CallInst::Create(RewindFunction, RewindFunctionArgs, "", UnwindBB);
+    CI->setCallingConv(RewindFunctionCallingConv);
 
     // We never expect _Unwind_Resume to return.
     CI->setDoesNotReturn();
@@ -240,6 +258,8 @@ bool DwarfEHPrepare::InsertUnwindResumeCalls() {
   std::vector<DominatorTree::UpdateType> Updates;
   Updates.reserve(Resumes.size());
 
+  llvm::SmallVector<Value *, 1> RewindFunctionArgs;
+
   BasicBlock *UnwindBB = BasicBlock::Create(Ctx, "unwind_resume", &F);
   PHINode *PN = PHINode::Create(Type::getInt8PtrTy(Ctx), ResumesLeft, "exn.obj",
                                 UnwindBB);
@@ -257,9 +277,13 @@ bool DwarfEHPrepare::InsertUnwindResumeCalls() {
     ++NumResumesLowered;
   }
 
+  if (DoesRewindFunctionNeedExceptionObject)
+    RewindFunctionArgs.push_back(PN);
+
   // Call the function.
-  CallInst *CI = CallInst::Create(RewindFunction, PN, "", UnwindBB);
-  CI->setCallingConv(TLI.getLibcallCallingConv(RTLIB::UNWIND_RESUME));
+  CallInst *CI =
+      CallInst::Create(RewindFunction, RewindFunctionArgs, "", UnwindBB);
+  CI->setCallingConv(RewindFunctionCallingConv);
 
   // We never expect _Unwind_Resume to return.
   CI->setDoesNotReturn();
@@ -277,22 +301,20 @@ bool DwarfEHPrepare::run() {
   return Changed;
 }
 
-static bool prepareDwarfEH(CodeGenOpt::Level OptLevel,
-                           FunctionCallee &RewindFunction, Function &F,
+static bool prepareDwarfEH(CodeGenOpt::Level OptLevel, Function &F,
                            const TargetLowering &TLI, DominatorTree *DT,
-                           const TargetTransformInfo *TTI) {
+                           const TargetTransformInfo *TTI,
+                           const Triple &TargetTriple) {
   DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
 
-  return DwarfEHPrepare(OptLevel, RewindFunction, F, TLI, DT ? &DTU : nullptr,
-                        TTI)
+  return DwarfEHPrepare(OptLevel, F, TLI, DT ? &DTU : nullptr, TTI,
+                        TargetTriple)
       .run();
 }
 
 namespace {
 
 class DwarfEHPrepareLegacyPass : public FunctionPass {
-  // RewindFunction - _Unwind_Resume or the target equivalent.
-  FunctionCallee RewindFunction = nullptr;
 
   CodeGenOpt::Level OptLevel;
 
@@ -315,12 +337,7 @@ class DwarfEHPrepareLegacyPass : public FunctionPass {
         DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
       TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
     }
-    return prepareDwarfEH(OptLevel, RewindFunction, F, TLI, DT, TTI);
-  }
-
-  bool doFinalization(Module &M) override {
-    RewindFunction = nullptr;
-    return false;
+    return prepareDwarfEH(OptLevel, F, TLI, DT, TTI, TM.getTargetTriple());
   }
 
   void getAnalysisUsage(AnalysisUsage &AU) const override {

diff  --git a/llvm/lib/Target/ARM/ARMSubtarget.h b/llvm/lib/Target/ARM/ARMSubtarget.h
index 807bbc11bd948..68390c9902686 100644
--- a/llvm/lib/Target/ARM/ARMSubtarget.h
+++ b/llvm/lib/Target/ARM/ARMSubtarget.h
@@ -792,14 +792,7 @@ class ARMSubtarget : public ARMGenSubtargetInfo {
   // ARM Targets that support EHABI exception handling standard
   // Darwin uses SjLj. Other targets might need more checks.
   bool isTargetEHABICompatible() const {
-    return (TargetTriple.getEnvironment() == Triple::EABI ||
-            TargetTriple.getEnvironment() == Triple::GNUEABI ||
-            TargetTriple.getEnvironment() == Triple::MuslEABI ||
-            TargetTriple.getEnvironment() == Triple::EABIHF ||
-            TargetTriple.getEnvironment() == Triple::GNUEABIHF ||
-            TargetTriple.getEnvironment() == Triple::MuslEABIHF ||
-            isTargetAndroid()) &&
-           !isTargetDarwin() && !isTargetWindows();
+    return TargetTriple.isTargetEHABICompatible();
   }
 
   bool isTargetHardFloat() const;

diff  --git a/llvm/test/CodeGen/ARM/debug-frame.ll b/llvm/test/CodeGen/ARM/debug-frame.ll
index b561be465d25d..b7660443a7d32 100644
--- a/llvm/test/CodeGen/ARM/debug-frame.ll
+++ b/llvm/test/CodeGen/ARM/debug-frame.ll
@@ -197,29 +197,27 @@ declare void @_ZSt9terminatev()
 
 ; CHECK-V7-FP-LABEL: _Z4testiiiiiddddd:
 ; CHECK-V7-FP:   .cfi_startproc
-; CHECK-V7-FP:   push   {r4, r10, r11, lr}
-; CHECK-V7-FP:   .cfi_def_cfa_offset 16
+; CHECK-V7-FP:   push   {r11, lr}
+; CHECK-V7-FP:   .cfi_def_cfa_offset 8
 ; CHECK-V7-FP:   .cfi_offset lr, -4
 ; CHECK-V7-FP:   .cfi_offset r11, -8
-; CHECK-V7-FP:   .cfi_offset r10, -12
-; CHECK-V7-FP:   .cfi_offset r4, -16
-; CHECK-V7-FP:   add    r11, sp, #8
-; CHECK-V7-FP:   .cfi_def_cfa r11, 8
+; CHECK-V7-FP:   mov     r11, sp
+; CHECK-V7-FP:   .cfi_def_cfa_register r11
 ; CHECK-V7-FP:   vpush  {d8, d9, d10, d11, d12}
-; CHECK-V7-FP:   .cfi_offset d12, -24
-; CHECK-V7-FP:   .cfi_offset d11, -32
-; CHECK-V7-FP:   .cfi_offset d10, -40
-; CHECK-V7-FP:   .cfi_offset d9, -48
-; CHECK-V7-FP:   .cfi_offset d8, -56
+; CHECK-V7-FP:   .cfi_offset d12, -16
+; CHECK-V7-FP:   .cfi_offset d11, -24
+; CHECK-V7-FP:   .cfi_offset d10, -32
+; CHECK-V7-FP:   .cfi_offset d9, -40
+; CHECK-V7-FP:   .cfi_offset d8, -48
 ; CHECK-V7-FP:   sub    sp, sp, #24
 ; CHECK-V7-FP:   .cfi_endproc
 
 ; CHECK-V7-FP-ELIM-LABEL: _Z4testiiiiiddddd:
 ; CHECK-V7-FP-ELIM:   .cfi_startproc
-; CHECK-V7-FP-ELIM:   push   {r4, lr}
+; CHECK-V7-FP-ELIM:   push   {r11, lr}
 ; CHECK-V7-FP-ELIM:   .cfi_def_cfa_offset 8
 ; CHECK-V7-FP-ELIM:   .cfi_offset lr, -4
-; CHECK-V7-FP-ELIM:   .cfi_offset r4, -8
+; CHECK-V7-FP-ELIM:   .cfi_offset r11, -8
 ; CHECK-V7-FP-ELIM:   vpush  {d8, d9, d10, d11, d12}
 ; CHECK-V7-FP-ELIM:   .cfi_def_cfa_offset 48
 ; CHECK-V7-FP-ELIM:   .cfi_offset d12, -16
@@ -260,29 +258,27 @@ declare void @_ZSt9terminatev()
 
 ; CHECK-THUMB-V7-FP-LABEL: _Z4testiiiiiddddd:
 ; CHECK-THUMB-V7-FP:   .cfi_startproc
-; CHECK-THUMB-V7-FP:   push   {r4, r6, r7, lr}
-; CHECK-THUMB-V7-FP:   .cfi_def_cfa_offset 16
+; CHECK-THUMB-V7-FP:   push   {r7, lr}
+; CHECK-THUMB-V7-FP:   .cfi_def_cfa_offset 8
 ; CHECK-THUMB-V7-FP:   .cfi_offset lr, -4
 ; CHECK-THUMB-V7-FP:   .cfi_offset r7, -8
-; CHECK-THUMB-V7-FP:   .cfi_offset r6, -12
-; CHECK-THUMB-V7-FP:   .cfi_offset r4, -16
-; CHECK-THUMB-V7-FP:   add    r7, sp, #8
-; CHECK-THUMB-V7-FP:   .cfi_def_cfa r7, 8
+; CHECK-THUMB-V7-FP:   mov    r7, sp
+; CHECK-THUMB-V7-FP:   .cfi_def_cfa_register r7
 ; CHECK-THUMB-V7-FP:   vpush  {d8, d9, d10, d11, d12}
-; CHECK-THUMB-V7-FP:   .cfi_offset d12, -24
-; CHECK-THUMB-V7-FP:   .cfi_offset d11, -32
-; CHECK-THUMB-V7-FP:   .cfi_offset d10, -40
-; CHECK-THUMB-V7-FP:   .cfi_offset d9, -48
-; CHECK-THUMB-V7-FP:   .cfi_offset d8, -56
+; CHECK-THUMB-V7-FP:   .cfi_offset d12, -16
+; CHECK-THUMB-V7-FP:   .cfi_offset d11, -24
+; CHECK-THUMB-V7-FP:   .cfi_offset d10, -32
+; CHECK-THUMB-V7-FP:   .cfi_offset d9, -40
+; CHECK-THUMB-V7-FP:   .cfi_offset d8, -48
 ; CHECK-THUMB-V7-FP:   sub    sp, #24
 ; CHECK-THUMB-V7-FP:   .cfi_endproc
 
 ; CHECK-THUMB-V7-FP-ELIM-LABEL: _Z4testiiiiiddddd:
 ; CHECK-THUMB-V7-FP-ELIM:   .cfi_startproc
-; CHECK-THUMB-V7-FP-ELIM:   push   {r4, lr}
+; CHECK-THUMB-V7-FP-ELIM:   push   {r7, lr}
 ; CHECK-THUMB-V7-FP-ELIM:   .cfi_def_cfa_offset 8
 ; CHECK-THUMB-V7-FP-ELIM:   .cfi_offset lr, -4
-; CHECK-THUMB-V7-FP-ELIM:   .cfi_offset r4, -8
+; CHECK-THUMB-V7-FP-ELIM:   .cfi_offset r7, -8
 ; CHECK-THUMB-V7-FP-ELIM:   vpush  {d8, d9, d10, d11, d12}
 ; CHECK-THUMB-V7-FP-ELIM:   .cfi_def_cfa_offset 48
 ; CHECK-THUMB-V7-FP-ELIM:   .cfi_offset d12, -16
@@ -296,20 +292,18 @@ declare void @_ZSt9terminatev()
 
 ; CHECK-THUMB-V7-FP-NOIAS-LABEL: _Z4testiiiiiddddd:
 ; CHECK-THUMB-V7-FP-NOIAS:   .cfi_startproc
-; CHECK-THUMB-V7-FP-NOIAS:   push   {r4, r6, r7, lr}
-; CHECK-THUMB-V7-FP-NOIAS:   .cfi_def_cfa_offset 16
+; CHECK-THUMB-V7-FP-NOIAS:   push   {r7, lr}
+; CHECK-THUMB-V7-FP-NOIAS:   .cfi_def_cfa_offset 8
 ; CHECK-THUMB-V7-FP-NOIAS:   .cfi_offset 14, -4
 ; CHECK-THUMB-V7-FP-NOIAS:   .cfi_offset 7, -8
-; CHECK-THUMB-V7-FP-NOIAS:   .cfi_offset 6, -12
-; CHECK-THUMB-V7-FP-NOIAS:   .cfi_offset 4, -16
-; CHECK-THUMB-V7-FP-NOIAS:   add    r7, sp, #8
-; CHECK-THUMB-V7-FP-NOIAS:   .cfi_def_cfa 7, 8
+; CHECK-THUMB-V7-FP-NOIAS:   mov    r7, sp
+; CHECK-THUMB-V7-FP-NOIAS:   .cfi_def_cfa_register 7
 ; CHECK-THUMB-V7-FP-NOIAS:   vpush  {d8, d9, d10, d11, d12}
-; CHECK-THUMB-V7-FP-NOIAS:   .cfi_offset 268, -24
-; CHECK-THUMB-V7-FP-NOIAS:   .cfi_offset 267, -32
-; CHECK-THUMB-V7-FP-NOIAS:   .cfi_offset 266, -40
-; CHECK-THUMB-V7-FP-NOIAS:   .cfi_offset 265, -48
-; CHECK-THUMB-V7-FP-NOIAS:   .cfi_offset 264, -56
+; CHECK-THUMB-V7-FP-NOIAS:   .cfi_offset 268, -16
+; CHECK-THUMB-V7-FP-NOIAS:   .cfi_offset 267, -24
+; CHECK-THUMB-V7-FP-NOIAS:   .cfi_offset 266, -32
+; CHECK-THUMB-V7-FP-NOIAS:   .cfi_offset 265, -40
+; CHECK-THUMB-V7-FP-NOIAS:   .cfi_offset 264, -48
 ; CHECK-THUMB-V7-FP-NOIAS:   sub    sp, #24
 ; CHECK-THUMB-V7-FP-NOIAS:   .cfi_endproc
 

diff  --git a/llvm/test/CodeGen/ARM/eh-resume-darwin.ll b/llvm/test/CodeGen/ARM/eh-resume.ll
similarity index 76%
rename from llvm/test/CodeGen/ARM/eh-resume-darwin.ll
rename to llvm/test/CodeGen/ARM/eh-resume.ll
index 6c2716bffa6d4..12fe2667b8f0c 100644
--- a/llvm/test/CodeGen/ARM/eh-resume-darwin.ll
+++ b/llvm/test/CodeGen/ARM/eh-resume.ll
@@ -2,6 +2,8 @@
 ; RUN: llc < %s -mtriple=armv7-apple-watchos -arm-atomic-cfg-tidy=0 | FileCheck %s -check-prefix=IOS
 ; RUN: llc < %s -mtriple=armv7k-apple-ios -arm-atomic-cfg-tidy=0 | FileCheck %s -check-prefix=WATCHABI
 ; RUN: llc < %s -mtriple=armv7k-apple-watchos -arm-atomic-cfg-tidy=0 | FileCheck %s -check-prefix=WATCHABI
+; RUN: llc < %s -mtriple=armv7-none-gnueabihf -arm-atomic-cfg-tidy=0 | FileCheck %s -check-prefix=EABI
+; RUN: llc < %s -mtriple=armv7-none-none -arm-atomic-cfg-tidy=0 | FileCheck %s -check-prefix=ABI
 
 declare void @func()
 
@@ -23,3 +25,5 @@ lpad:
 
 ; IOS: __Unwind_SjLj_Resume
 ; WATCHABI: __Unwind_Resume
+; EABI: __cxa_end_cleanup
+; ABI: _Unwind_Resume

diff  --git a/llvm/test/CodeGen/ARM/eh-resume2.ll b/llvm/test/CodeGen/ARM/eh-resume2.ll
new file mode 100644
index 0000000000000..d30b507255c4d
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/eh-resume2.ll
@@ -0,0 +1,32 @@
+; RUN: llc < %s -mtriple=armv7-apple-ios -arm-atomic-cfg-tidy=0 | FileCheck %s -check-prefix=IOS
+; RUN: llc < %s -mtriple=armv7-apple-watchos -arm-atomic-cfg-tidy=0 | FileCheck %s -check-prefix=IOS
+; RUN: llc < %s -mtriple=armv7k-apple-ios -arm-atomic-cfg-tidy=0 | FileCheck %s -check-prefix=WATCHABI
+; RUN: llc < %s -mtriple=armv7k-apple-watchos -arm-atomic-cfg-tidy=0 | FileCheck %s -check-prefix=WATCHABI
+; RUN: llc < %s -mtriple=armv7-none-gnueabihf -arm-atomic-cfg-tidy=0 | FileCheck %s -check-prefix=EABI
+; RUN: llc < %s -mtriple=armv7-none-none -arm-atomic-cfg-tidy=0 | FileCheck %s -check-prefix=ABI
+
+; ARM EABI for C++/__gxx_personality* specifies __cxa_end_cleanup, but for C code / __gcc_personality*
+; the _Unwind_Resume is required.
+
+declare void @func()
+
+declare i32 @__gcc_personality_v0(...)
+
+define void @test0() personality i8* bitcast (i32 (...)* @__gcc_personality_v0 to i8*) {
+entry:
+  invoke void @func()
+    to label %cont unwind label %lpad
+
+cont:
+  ret void
+
+lpad:
+  %exn = landingpad { i8*, i32 }
+           cleanup
+  resume { i8*, i32 } %exn
+}
+
+; IOS: __Unwind_SjLj_Resume
+; WATCHABI: __Unwind_Resume
+; EABI: _Unwind_Resume
+; ABI: _Unwind_Resume

diff  --git a/llvm/test/CodeGen/ARM/ehabi.ll b/llvm/test/CodeGen/ARM/ehabi.ll
index 5c4a2b620a1f0..c8c0b5b61980a 100644
--- a/llvm/test/CodeGen/ARM/ehabi.ll
+++ b/llvm/test/CodeGen/ARM/ehabi.ll
@@ -181,10 +181,10 @@ declare void @_ZSt9terminatev()
 
 ; CHECK-V7-FP-LABEL: _Z4testiiiiiddddd:
 ; CHECK-V7-FP:   .fnstart
-; CHECK-V7-FP:   .save  {r4, r10, r11, lr}
-; CHECK-V7-FP:   push   {r4, r10, r11, lr}
-; CHECK-V7-FP:   .setfp r11, sp, #8
-; CHECK-V7-FP:   add    r11, sp, #8
+; CHECK-V7-FP:   .save  {r11, lr}
+; CHECK-V7-FP:   push   {r11, lr}
+; CHECK-V7-FP:   .setfp r11, sp
+; CHECK-V7-FP:   mov    r11, sp
 ; CHECK-V7-FP:   .vsave {d8, d9, d10, d11, d12}
 ; CHECK-V7-FP:   vpush  {d8, d9, d10, d11, d12}
 ; CHECK-V7-FP:   .pad   #24
@@ -195,8 +195,8 @@ declare void @_ZSt9terminatev()
 
 ; CHECK-V7-FP-ELIM-LABEL: _Z4testiiiiiddddd:
 ; CHECK-V7-FP-ELIM:   .fnstart
-; CHECK-V7-FP-ELIM:   .save  {r4, lr}
-; CHECK-V7-FP-ELIM:   push   {r4, lr}
+; CHECK-V7-FP-ELIM:   .save  {r11, lr}
+; CHECK-V7-FP-ELIM:   push   {r11, lr}
 ; CHECK-V7-FP-ELIM:   .vsave {d8, d9, d10, d11, d12}
 ; CHECK-V7-FP-ELIM:   vpush  {d8, d9, d10, d11, d12}
 ; CHECK-V7-FP-ELIM:   .pad   #24
@@ -254,33 +254,31 @@ declare void @_ZSt9terminatev()
 ; DWARF-V7-FP:    .cfi_startproc
 ; DWARF-V7-FP:    .cfi_personality 0, __gxx_personality_v0
 ; DWARF-V7-FP:    .cfi_lsda 0, .Lexception0
-; DWARF-V7-FP:    push {r4, r10, r11, lr}
-; DWARF-V7-FP:    .cfi_def_cfa_offset 16
+; DWARF-V7-FP:    push {r11, lr}
+; DWARF-V7-FP:    .cfi_def_cfa_offset 8
 ; DWARF-V7-FP:    .cfi_offset lr, -4
 ; DWARF-V7-FP:    .cfi_offset r11, -8
-; DWARF-V7-FP:    .cfi_offset r10, -12
-; DWARF-V7-FP:    .cfi_offset r4, -16
-; DWARF-V7-FP:    add r11, sp, #8
-; DWARF-V7-FP:    .cfi_def_cfa r11, 8
+; DWARF-V7-FP:    mov r11, sp
+; DWARF-V7-FP:    .cfi_def_cfa_register r11
 ; DWARF-V7-FP:    vpush {d8, d9, d10, d11, d12}
-; DWARF-V7-FP:    .cfi_offset d12, -24
-; DWARF-V7-FP:    .cfi_offset d11, -32
-; DWARF-V7-FP:    .cfi_offset d10, -40
-; DWARF-V7-FP:    .cfi_offset d9, -48
+; DWARF-V7-FP:    .cfi_offset d12, -16
+; DWARF-V7-FP:    .cfi_offset d11, -24
+; DWARF-V7-FP:    .cfi_offset d10, -32
+; DWARF-V7-FP:    .cfi_offset d9, -40
 ; DWARF-V7-FP:    sub sp, sp, #24
-; DWARF-V7-FP:    sub sp, r11, #48
+; DWARF-V7-FP:    sub sp, r11, #40
 ; DWARF-V7-FP:    vpop {d8, d9, d10, d11, d12}
-; DWARF-V7-FP:    pop {r4, r10, r11, pc}
+; DWARF-V7-FP:    pop {r11, pc}
 ; DWARF-V7-FP:    .cfi_endproc
 
 ; DWARF-V7-FP-ELIM-LABEL: _Z4testiiiiiddddd:
 ; DWARF-V7-FP-ELIM:    .cfi_startproc
 ; DWARF-V7-FP-ELIM:    .cfi_personality 0, __gxx_personality_v0
 ; DWARF-V7-FP-ELIM:    .cfi_lsda 0, .Lexception0
-; DWARF-V7-FP-ELIM:    push {r4, lr}
+; DWARF-V7-FP-ELIM:    push {r11, lr}
 ; DWARF-V7-FP-ELIM:    .cfi_def_cfa_offset 8
 ; DWARF-V7-FP-ELIM:    .cfi_offset lr, -4
-; DWARF-V7-FP-ELIM:    .cfi_offset r4, -8
+; DWARF-V7-FP-ELIM:    .cfi_offset r11, -8
 ; DWARF-V7-FP-ELIM:    vpush {d8, d9, d10, d11, d12}
 ; DWARF-V7-FP-ELIM:    .cfi_offset d12, -16
 ; DWARF-V7-FP-ELIM:    .cfi_offset d11, -24
@@ -290,7 +288,7 @@ declare void @_ZSt9terminatev()
 ; DWARF-V7-FP-ELIM:    .cfi_def_cfa_offset 72
 ; DWARF-V7-FP-ELIM:    add sp, sp, #24
 ; DWARF-V7-FP-ELIM:    vpop {d8, d9, d10, d11, d12}
-; DWARF-V7-FP-ELIM:    pop {r4, pc}
+; DWARF-V7-FP-ELIM:    pop {r11, pc}
 ; DWARF-V7-FP-ELIM:    .cfi_endproc
 
 ; DWARF-WIN-FP-ELIM-LABEL: _Z4testiiiiiddddd:


        


More information about the libcxx-commits mailing list