diff --git a/llvm/lib/CodeGen/AsmPrinter/WinException.h b/llvm/lib/CodeGen/AsmPrinter/WinException.h --- a/llvm/lib/CodeGen/AsmPrinter/WinException.h +++ b/llvm/lib/CodeGen/AsmPrinter/WinException.h @@ -39,6 +39,9 @@ /// True if we are generating exception handling on Windows for ARM64. bool isAArch64 = false; + /// True if we are generating exception handling on Windows for ARM (Thumb). + bool isThumb = false; + /// Pointer to the current funclet entry BB. const MachineBasicBlock *CurrentFuncletEntry = nullptr; @@ -77,6 +80,7 @@ const MCExpr *create32bitRef(const MCSymbol *Value); const MCExpr *create32bitRef(const GlobalValue *GV); const MCExpr *getLabel(const MCSymbol *Label); + const MCExpr *getLabelPlusOne(const MCSymbol *Label); const MCExpr *getOffset(const MCSymbol *OffsetOf, const MCSymbol *OffsetFrom); const MCExpr *getOffsetPlusOne(const MCSymbol *OffsetOf, const MCSymbol *OffsetFrom); diff --git a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp --- a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp @@ -43,6 +43,7 @@ // platforms use an imagerel32 relocation to refer to symbols. useImageRel32 = (A->getDataLayout().getPointerSizeInBits() == 64); isAArch64 = Asm->TM.getTargetTriple().isAArch64(); + isThumb = Asm->TM.getTargetTriple().isThumb(); } WinException::~WinException() {} @@ -330,10 +331,12 @@ } const MCExpr *WinException::getLabel(const MCSymbol *Label) { - if (isAArch64) - return MCSymbolRefExpr::create(Label, MCSymbolRefExpr::VK_COFF_IMGREL32, - Asm->OutContext); - return MCBinaryExpr::createAdd(create32bitRef(Label), + return MCSymbolRefExpr::create(Label, MCSymbolRefExpr::VK_COFF_IMGREL32, + Asm->OutContext); +} + +const MCExpr *WinException::getLabelPlusOne(const MCSymbol *Label) { + return MCBinaryExpr::createAdd(getLabel(Label), MCConstantExpr::create(1, Asm->OutContext), Asm->OutContext); } @@ -561,8 +564,8 @@ /// struct Table { /// int NumEntries; /// struct Entry { -/// imagerel32 LabelStart; -/// imagerel32 LabelEnd; +/// imagerel32 LabelStart; // Inclusive +/// imagerel32 LabelEnd; // Exclusive /// imagerel32 FilterOrFinally; // One means catch-all. /// imagerel32 LabelLPad; // Zero means __finally. /// } Entries[NumEntries]; @@ -664,7 +667,7 @@ AddComment("LabelStart"); OS.emitValue(getLabel(BeginLabel), 4); AddComment("LabelEnd"); - OS.emitValue(getLabel(EndLabel), 4); + OS.emitValue(getLabelPlusOne(EndLabel), 4); AddComment(UME.IsFinally ? "FinallyFunclet" : UME.Filter ? "FilterFunction" : "CatchAll"); OS.emitValue(FilterOrFinally, 4); @@ -949,8 +952,15 @@ if (!ChangeLabel) ChangeLabel = StateChange.PreviousEndLabel; // Emit an entry indicating that PCs after 'Label' have this EH state. + // NOTE: On ARM architectures, the StateFromIp automatically takes into + // account that the return address is after the call instruction (whose EH + // state we should be using), but on other platforms we need to +1 to the + // label so that we are using the correct EH state. + const MCExpr *LabelExpression = (isAArch64 || isThumb) + ? getLabel(ChangeLabel) + : getLabelPlusOne(ChangeLabel); IPToStateTable.push_back( - std::make_pair(getLabel(ChangeLabel), StateChange.NewState)); + std::make_pair(LabelExpression, StateChange.NewState)); // FIXME: assert that NewState is between CatchLow and CatchHigh. } } diff --git a/llvm/test/CodeGen/WinEH/wineh-noret-cleanup.ll b/llvm/test/CodeGen/WinEH/wineh-noret-cleanup.ll --- a/llvm/test/CodeGen/WinEH/wineh-noret-cleanup.ll +++ b/llvm/test/CodeGen/WinEH/wineh-noret-cleanup.ll @@ -61,19 +61,19 @@ ; SEH-LABEL: test: ; SEH-LABEL: .Llsda_begin0: -; SEH-NEXT: .long .Ltmp0@IMGREL+1 +; SEH-NEXT: .long .Ltmp0@IMGREL ; SEH-NEXT: .long .Ltmp1@IMGREL+1 ; SEH-NEXT: .long dummy_filter@IMGREL ; SEH-NEXT: .long .LBB0_3@IMGREL -; SEH-NEXT: .long .Ltmp0@IMGREL+1 +; SEH-NEXT: .long .Ltmp0@IMGREL ; SEH-NEXT: .long .Ltmp1@IMGREL+1 ; SEH-NEXT: .long dummy_filter@IMGREL ; SEH-NEXT: .long .LBB0_5@IMGREL -; SEH-NEXT: .long .Ltmp2@IMGREL+1 +; SEH-NEXT: .long .Ltmp2@IMGREL ; SEH-NEXT: .long .Ltmp3@IMGREL+1 ; SEH-NEXT: .long "?dtor$2@?0?test@4HA"@IMGREL ; SEH-NEXT: .long 0 -; SEH-NEXT: .long .Ltmp2@IMGREL+1 +; SEH-NEXT: .long .Ltmp2@IMGREL ; SEH-NEXT: .long .Ltmp3@IMGREL+1 ; SEH-NEXT: .long dummy_filter@IMGREL ; SEH-NEXT: .long .LBB0_5@IMGREL diff --git a/llvm/test/CodeGen/X86/catchret-empty-fallthrough.ll b/llvm/test/CodeGen/X86/catchret-empty-fallthrough.ll --- a/llvm/test/CodeGen/X86/catchret-empty-fallthrough.ll +++ b/llvm/test/CodeGen/X86/catchret-empty-fallthrough.ll @@ -47,7 +47,7 @@ ; CHECK-NEXT: .set .Lfoo$parent_frame_offset, 32 ; CHECK-NEXT: .long (.Llsda_end0-.Llsda_begin0)/16 ; CHECK-NEXT: .Llsda_begin0: -; CHECK-NEXT: .long .Ltmp0@IMGREL+1 +; CHECK-NEXT: .long .Ltmp0@IMGREL ; CHECK-NEXT: .long .Ltmp1@IMGREL+1 ; CHECK-NEXT: .long 1 ; CHECK-NEXT: .long .LBB0_[[catch]]@IMGREL diff --git a/llvm/test/CodeGen/X86/seh-catchpad.ll b/llvm/test/CodeGen/X86/seh-catchpad.ll --- a/llvm/test/CodeGen/X86/seh-catchpad.ll +++ b/llvm/test/CodeGen/X86/seh-catchpad.ll @@ -120,23 +120,23 @@ ; CHECK-NEXT: .set .Lmain$parent_frame_offset, 32 ; CHECK-NEXT: .long (.Llsda_end0-.Llsda_begin0)/16 ; CHECK-NEXT: .Llsda_begin0: -; CHECK-NEXT: .long .Ltmp0@IMGREL+1 +; CHECK-NEXT: .long .Ltmp0@IMGREL ; CHECK-NEXT: .long .Ltmp1@IMGREL+1 ; CHECK-NEXT: .long 1 ; CHECK-NEXT: .long .LBB1_[[except1bb]]@IMGREL -; CHECK-NEXT: .long .Ltmp0@IMGREL+1 +; CHECK-NEXT: .long .Ltmp0@IMGREL ; CHECK-NEXT: .long .Ltmp1@IMGREL+1 ; CHECK-NEXT: .long "?filt$0@0@main@@"@IMGREL ; CHECK-NEXT: .long .LBB1_[[except2bb]]@IMGREL -; CHECK-NEXT: .long .Ltmp2@IMGREL+1 +; CHECK-NEXT: .long .Ltmp2@IMGREL ; CHECK-NEXT: .long .Ltmp3@IMGREL+1 ; CHECK-NEXT: .long "?dtor$[[finbb:[0-9]+]]@?0?main@4HA"@IMGREL ; CHECK-NEXT: .long 0 -; CHECK-NEXT: .long .Ltmp2@IMGREL+1 +; CHECK-NEXT: .long .Ltmp2@IMGREL ; CHECK-NEXT: .long .Ltmp3@IMGREL+1 ; CHECK-NEXT: .long "?filt$0@0@main@@"@IMGREL ; CHECK-NEXT: .long .LBB1_3@IMGREL -; CHECK-NEXT: .long .Ltmp6@IMGREL+1 +; CHECK-NEXT: .long .Ltmp6@IMGREL ; CHECK-NEXT: .long .Ltmp7@IMGREL+1 ; CHECK-NEXT: .long "?filt$0@0@main@@"@IMGREL ; CHECK-NEXT: .long .LBB1_3@IMGREL diff --git a/llvm/test/CodeGen/X86/seh-except-finally.ll b/llvm/test/CodeGen/X86/seh-except-finally.ll --- a/llvm/test/CodeGen/X86/seh-except-finally.ll +++ b/llvm/test/CodeGen/X86/seh-except-finally.ll @@ -82,15 +82,15 @@ ; CHECK-NEXT: .Luse_both$parent_frame_offset ; CHECK-NEXT: .long (.Llsda_end0-.Llsda_begin0)/16 ; CHECK-NEXT: .Llsda_begin0: -; CHECK-NEXT: .long .Ltmp0@IMGREL+1 +; CHECK-NEXT: .long .Ltmp0@IMGREL ; CHECK-NEXT: .long .Ltmp1@IMGREL+1 ; CHECK-NEXT: .long "?dtor$2@?0?use_both@4HA"@IMGREL ; CHECK-NEXT: .long 0 -; CHECK-NEXT: .long .Ltmp0@IMGREL+1 +; CHECK-NEXT: .long .Ltmp0@IMGREL ; CHECK-NEXT: .long .Ltmp1@IMGREL+1 ; CHECK-NEXT: .long "?filt$0@0@use_both@@"@IMGREL ; CHECK-NEXT: .long .LBB0_{{[0-9]+}}@IMGREL -; CHECK-NEXT: .long .Ltmp4@IMGREL+1 +; CHECK-NEXT: .long .Ltmp4@IMGREL ; CHECK-NEXT: .long .Ltmp5@IMGREL+1 ; CHECK-NEXT: .long "?filt$0@0@use_both@@"@IMGREL ; CHECK-NEXT: .long .LBB0_{{[0-9]+}}@IMGREL diff --git a/llvm/test/CodeGen/X86/seh-finally.ll b/llvm/test/CodeGen/X86/seh-finally.ll --- a/llvm/test/CodeGen/X86/seh-finally.ll +++ b/llvm/test/CodeGen/X86/seh-finally.ll @@ -29,7 +29,7 @@ ; X64-NEXT: .set .Lmain$parent_frame_offset, 32 ; X64-NEXT: .long (.Llsda_end0-.Llsda_begin0)/16 # Number of call sites ; X64-NEXT: .Llsda_begin0: -; X64-NEXT: .long .Ltmp0@IMGREL+1 # LabelStart +; X64-NEXT: .long .Ltmp0@IMGREL # LabelStart ; X64-NEXT: .long .Ltmp1@IMGREL+1 # LabelEnd ; X64-NEXT: .long "?dtor$2@?0?main@4HA"@IMGREL # FinallyFunclet ; X64-NEXT: .long 0 # Null diff --git a/llvm/test/CodeGen/X86/seh-safe-div.ll b/llvm/test/CodeGen/X86/seh-safe-div.ll --- a/llvm/test/CodeGen/X86/seh-safe-div.ll +++ b/llvm/test/CodeGen/X86/seh-safe-div.ll @@ -81,11 +81,11 @@ ; CHECK-NEXT: .Lsafe_div$parent_frame_offset ; CHECK-NEXT: .long (.Llsda_end0-.Llsda_begin0)/16 ; CHECK-NEXT: .Llsda_begin0: -; CHECK-NEXT: .long .Ltmp0@IMGREL+1 +; CHECK-NEXT: .long .Ltmp0@IMGREL ; CHECK-NEXT: .long .Ltmp1@IMGREL+1 ; CHECK-NEXT: .long safe_div_filt0@IMGREL ; CHECK-NEXT: .long [[handler0]]@IMGREL -; CHECK-NEXT: .long .Ltmp0@IMGREL+1 +; CHECK-NEXT: .long .Ltmp0@IMGREL ; CHECK-NEXT: .long .Ltmp1@IMGREL+1 ; CHECK-NEXT: .long safe_div_filt1@IMGREL ; CHECK-NEXT: .long [[handler1]]@IMGREL