Index: lib/CodeGen/AsmPrinter/ARMException.cpp =================================================================== --- lib/CodeGen/AsmPrinter/ARMException.cpp +++ lib/CodeGen/AsmPrinter/ARMException.cpp @@ -34,6 +34,10 @@ #include "llvm/Target/TargetRegisterInfo.h" using namespace llvm; +static cl::opt +Disable_CantUnwind("disable-arm-cantunwind", cl::Hidden, + cl::desc("Do not Generate EHABI exidx_cantunwind value.")); + ARMException::ARMException(AsmPrinter *A) : DwarfCFIExceptionBase(A) {} ARMException::~ARMException() {} @@ -44,8 +48,12 @@ } void ARMException::beginFunction(const MachineFunction *MF) { - if (Asm->MAI->getExceptionHandlingType() == ExceptionHandling::ARM) + const Function *F = MF->getFunction(); + + if (Asm->MAI->getExceptionHandlingType() == ExceptionHandling::ARM && + (F->hasUWTable() || !Disable_CantUnwind)) getTargetStreamer().emitFnStart(); + // See if we need call frame info. AsmPrinter::CFIMoveType MoveType = Asm->needsCFIMoves(); assert(MoveType != AsmPrinter::CFI_M_EH && @@ -69,6 +77,7 @@ ARMTargetStreamer &ATS = getTargetStreamer(); const Function *F = MF->getFunction(); const Function *Per = nullptr; + if (F->hasPersonalityFn()) Per = dyn_cast(F->getPersonalityFn()->stripPointerCasts()); bool forceEmitPersonality = @@ -76,8 +85,8 @@ F->needsUnwindTableEntry(); bool shouldEmitPersonality = forceEmitPersonality || !MF->getLandingPads().empty(); - if (!Asm->MF->getFunction()->needsUnwindTableEntry() && - !shouldEmitPersonality) + + if (!F->needsUnwindTableEntry() && !shouldEmitPersonality && !Disable_CantUnwind) ATS.emitCantUnwind(); else if (shouldEmitPersonality) { // Emit references to personality. @@ -94,7 +103,8 @@ emitExceptionTable(); } - if (Asm->MAI->getExceptionHandlingType() == ExceptionHandling::ARM) + if (Asm->MAI->getExceptionHandlingType() == ExceptionHandling::ARM && + (F->hasUWTable() || !Disable_CantUnwind)) ATS.emitFnEnd(); } Index: test/CodeGen/ARM/ehabi-cantunwind.ll =================================================================== --- /dev/null +++ test/CodeGen/ARM/ehabi-cantunwind.ll @@ -0,0 +1,36 @@ +; Check that ARM EHABI EXIDX_CANTUNWIND directive is not generated when requested. +; +; - If the function does not throw (nounwind attribute), do not generate unwind table. +; - If the function doesn not throw but unwind table are required (nounwind uwtables +; attributes), do not generate EXIDX_CANTUNWIND value. + +declare void @bar() + +; RUN: llc -mtriple armv7-unknown--eabi -filetype=asm \ +; RUN: -disable-arm-cantunwind -o - %s \ +; RUN: | FileCheck %s --check-prefix=CHECK-NOTHROW + +define void @test0 () #0 { +entry: + call void @bar() + ret void +} + +; CHECK-NOTHROW-LABEL: test0: +; CHECK-NOTHROW-NOT: .fnstart +; CHECK-NOTHROW-NOT: .cantunwind +; CHECK-NOTHROW-NOT: .fnend + +define void @test1 () #1 { +entry: + call void @bar() + ret void +} + +; CHECK-NOTHROW-LABEL: test1: +; CHECK-NOTHROW: .fnstart +; CHECK-NOTHROW-NOT: .cantunwind +; CHECK-NOTHROW: .fnend + +attributes #0 = { nounwind } +attributes #1 = { nounwind uwtable }