forked from OSchip/llvm-project
[WinEH] Fix ip2state table emission with funclets
Previously we were hijacking the old LandingPadInfo data structures to communicate our state numbers. Now we don't need that anymore. llvm-svn: 248763
This commit is contained in:
parent
525c013921
commit
c71d6275ca
|
@ -28,6 +28,7 @@ class GlobalVariable;
|
|||
class InvokeInst;
|
||||
class IntrinsicInst;
|
||||
class LandingPadInst;
|
||||
class MCExpr;
|
||||
class MCSymbol;
|
||||
class MachineBasicBlock;
|
||||
class Value;
|
||||
|
@ -160,15 +161,18 @@ struct WinEHTryBlockMapEntry {
|
|||
|
||||
struct WinEHFuncInfo {
|
||||
DenseMap<const Instruction *, int> EHPadStateMap;
|
||||
DenseMap<MCSymbol *, std::pair<int, MCSymbol *>> InvokeToStateMap;
|
||||
SmallVector<WinEHUnwindMapEntry, 4> UnwindMap;
|
||||
SmallVector<WinEHTryBlockMapEntry, 4> TryBlockMap;
|
||||
SmallVector<SEHUnwindMapEntry, 4> SEHUnwindMap;
|
||||
SmallVector<std::pair<MCSymbol *, int>, 4> IPToStateList;
|
||||
int UnwindHelpFrameIdx = INT_MAX;
|
||||
int UnwindHelpFrameOffset = -1;
|
||||
|
||||
int getLastStateNumber() const { return UnwindMap.size() - 1; }
|
||||
|
||||
void addIPToStateRange(const BasicBlock *PadBB, MCSymbol *InvokeBegin,
|
||||
MCSymbol *InvokeEnd);
|
||||
|
||||
/// localescape index of the 32-bit EH registration node. Set by
|
||||
/// WinEHStatePass and used indirectly by SEH filter functions of the parent.
|
||||
int EHRegNodeEscapeIndex = INT_MAX;
|
||||
|
|
|
@ -965,7 +965,7 @@ void AsmPrinter::EmitFunctionBody() {
|
|||
EmitFunctionBodyEnd();
|
||||
|
||||
if (!MMI->getLandingPads().empty() || MMI->hasDebugInfo() ||
|
||||
MAI->hasDotTypeDotSizeDirective()) {
|
||||
MMI->hasEHFunclets() || MAI->hasDotTypeDotSizeDirective()) {
|
||||
// Create a symbol for the end of function.
|
||||
CurrentFnEnd = createTempSymbol("func_end");
|
||||
OutStreamer->EmitLabel(CurrentFnEnd);
|
||||
|
@ -1260,7 +1260,7 @@ void AsmPrinter::SetupMachineFunction(MachineFunction &MF) {
|
|||
CurExceptionSym = nullptr;
|
||||
bool NeedsLocalForSize = MAI->needsLocalForSize();
|
||||
if (!MMI->getLandingPads().empty() || MMI->hasDebugInfo() ||
|
||||
NeedsLocalForSize) {
|
||||
MMI->hasEHFunclets() || NeedsLocalForSize) {
|
||||
CurrentFnBegin = createTempSymbol("func_begin");
|
||||
if (NeedsLocalForSize)
|
||||
CurrentFnSymForSize = CurrentFnBegin;
|
||||
|
|
|
@ -176,6 +176,12 @@ const MCExpr *WinException::create32bitRef(const Value *V) {
|
|||
return create32bitRef(MMI->getAddrLabelSymbol(cast<BasicBlock>(V)));
|
||||
}
|
||||
|
||||
const MCExpr *WinException::getLabelPlusOne(MCSymbol *Label) {
|
||||
return MCBinaryExpr::createAdd(create32bitRef(Label),
|
||||
MCConstantExpr::create(1, Asm->OutContext),
|
||||
Asm->OutContext);
|
||||
}
|
||||
|
||||
/// Emit the language-specific data that __C_specific_handler expects. This
|
||||
/// handler lives in the x64 Microsoft C runtime and allows catching or cleaning
|
||||
/// up after faults with __try, __except, and __finally. The typeinfo values
|
||||
|
@ -263,9 +269,7 @@ void WinException::emitCSpecificHandlerTable(const MachineFunction *MF) {
|
|||
if (CSE.EndLabel) {
|
||||
// The interval is half-open, so we have to add one to include the return
|
||||
// address of the last invoke in the range.
|
||||
End = MCBinaryExpr::createAdd(create32bitRef(CSE.EndLabel),
|
||||
MCConstantExpr::create(1, Asm->OutContext),
|
||||
Asm->OutContext);
|
||||
End = getLabelPlusOne(CSE.EndLabel);
|
||||
} else {
|
||||
End = create32bitRef(EHFuncEndSym);
|
||||
}
|
||||
|
@ -312,13 +316,15 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
|
|||
|
||||
StringRef FuncLinkageName = GlobalValue::getRealLinkageName(F->getName());
|
||||
|
||||
SmallVector<std::pair<const MCExpr *, int>, 4> IPToStateTable;
|
||||
MCSymbol *FuncInfoXData = nullptr;
|
||||
if (shouldEmitPersonality) {
|
||||
// If we're 64-bit, emit a pointer to the C++ EH data, and build a map from
|
||||
// IPs to state numbers.
|
||||
FuncInfoXData =
|
||||
Asm->OutContext.getOrCreateSymbol(Twine("$cppxdata$", FuncLinkageName));
|
||||
OS.EmitValue(create32bitRef(FuncInfoXData), 4);
|
||||
|
||||
extendIP2StateTable(MF, FuncInfo);
|
||||
computeIP2StateTable(MF, FuncInfo, IPToStateTable);
|
||||
} else {
|
||||
FuncInfoXData = Asm->OutContext.getOrCreateLSDASymbol(FuncLinkageName);
|
||||
emitEHRegistrationOffsetLabel(FuncInfo, FuncLinkageName);
|
||||
|
@ -333,7 +339,7 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
|
|||
if (!FuncInfo.TryBlockMap.empty())
|
||||
TryBlockMapXData =
|
||||
Asm->OutContext.getOrCreateSymbol(Twine("$tryMap$", FuncLinkageName));
|
||||
if (!FuncInfo.IPToStateList.empty())
|
||||
if (!IPToStateTable.empty())
|
||||
IPToStateXData =
|
||||
Asm->OutContext.getOrCreateSymbol(Twine("$ip2state$", FuncLinkageName));
|
||||
|
||||
|
@ -359,7 +365,7 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
|
|||
OS.EmitValue(create32bitRef(UnwindMapXData), 4); // UnwindMap
|
||||
OS.EmitIntValue(FuncInfo.TryBlockMap.size(), 4); // NumTryBlocks
|
||||
OS.EmitValue(create32bitRef(TryBlockMapXData), 4); // TryBlockMap
|
||||
OS.EmitIntValue(FuncInfo.IPToStateList.size(), 4); // IPMapEntries
|
||||
OS.EmitIntValue(IPToStateTable.size(), 4); // IPMapEntries
|
||||
OS.EmitValue(create32bitRef(IPToStateXData), 4); // IPToStateMap
|
||||
if (Asm->MAI->usesWindowsCFI())
|
||||
OS.EmitIntValue(FuncInfo.UnwindHelpFrameOffset, 4); // UnwindHelp
|
||||
|
@ -477,80 +483,87 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
|
|||
// };
|
||||
if (IPToStateXData) {
|
||||
OS.EmitLabel(IPToStateXData);
|
||||
for (auto &IPStatePair : FuncInfo.IPToStateList) {
|
||||
OS.EmitValue(create32bitRef(IPStatePair.first), 4); // IP
|
||||
OS.EmitIntValue(IPStatePair.second, 4); // State
|
||||
for (auto &IPStatePair : IPToStateTable) {
|
||||
OS.EmitValue(IPStatePair.first, 4); // IP
|
||||
OS.EmitIntValue(IPStatePair.second, 4); // State
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WinException::extendIP2StateTable(const MachineFunction *MF,
|
||||
WinEHFuncInfo &FuncInfo) {
|
||||
// The Itanium LSDA table sorts similar landing pads together to simplify the
|
||||
// actions table, but we don't need that.
|
||||
SmallVector<const LandingPadInfo *, 64> LandingPads;
|
||||
const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads();
|
||||
LandingPads.reserve(PadInfos.size());
|
||||
for (const auto &LP : PadInfos)
|
||||
LandingPads.push_back(&LP);
|
||||
|
||||
RangeMapType PadMap;
|
||||
computePadMap(LandingPads, PadMap);
|
||||
|
||||
// The end label of the previous invoke or nounwind try-range.
|
||||
MCSymbol *LastLabel = Asm->getFunctionBegin();
|
||||
|
||||
void WinException::computeIP2StateTable(
|
||||
const MachineFunction *MF, WinEHFuncInfo &FuncInfo,
|
||||
SmallVectorImpl<std::pair<const MCExpr *, int>> &IPToStateTable) {
|
||||
// Whether there is a potentially throwing instruction (currently this means
|
||||
// an ordinary call) between the end of the previous try-range and now.
|
||||
bool SawPotentiallyThrowing = false;
|
||||
bool SawPotentiallyThrowing = true;
|
||||
|
||||
int LastEHState = -2;
|
||||
// Remember what state we were in the last time we found a begin try label.
|
||||
// This allows us to coalesce many nearby invokes with the same state into one
|
||||
// entry.
|
||||
int LastEHState = -1;
|
||||
MCSymbol *LastEndLabel = Asm->getFunctionBegin();
|
||||
assert(LastEndLabel && "need local function start label");
|
||||
|
||||
// The parent function and the catch handlers contribute to the 'ip2state'
|
||||
// table.
|
||||
// Indicate that all calls from the prologue to the first invoke unwind to
|
||||
// caller. We handle this as a special case since other ranges starting at end
|
||||
// labels need to use LtmpN+1.
|
||||
IPToStateTable.push_back(std::make_pair(create32bitRef(LastEndLabel), -1));
|
||||
|
||||
// Include ip2state entries for the beginning of the main function and
|
||||
// for catch handler functions.
|
||||
FuncInfo.IPToStateList.push_back(std::make_pair(LastLabel, -1));
|
||||
LastEHState = -1;
|
||||
for (const auto &MBB : *MF) {
|
||||
// FIXME: Do we need to emit entries for funclet base states?
|
||||
|
||||
for (const auto &MI : MBB) {
|
||||
// Find all the EH_LABEL instructions, tracking if we've crossed a
|
||||
// potentially throwing call since the last label.
|
||||
if (!MI.isEHLabel()) {
|
||||
if (MI.isCall())
|
||||
SawPotentiallyThrowing |= !callToNoUnwindFunction(&MI);
|
||||
continue;
|
||||
}
|
||||
|
||||
// End of the previous try-range?
|
||||
MCSymbol *BeginLabel = MI.getOperand(0).getMCSymbol();
|
||||
if (BeginLabel == LastLabel)
|
||||
// If this was an end label, return SawPotentiallyThrowing to the start
|
||||
// state and keep going. Otherwise, we will consider the call between the
|
||||
// begin/end labels to be a potentially throwing call and generate extra
|
||||
// table entries.
|
||||
MCSymbol *Label = MI.getOperand(0).getMCSymbol();
|
||||
if (Label == LastEndLabel)
|
||||
SawPotentiallyThrowing = false;
|
||||
|
||||
// Beginning of a new try-range?
|
||||
RangeMapType::const_iterator L = PadMap.find(BeginLabel);
|
||||
if (L == PadMap.end())
|
||||
// Nope, it was just some random label.
|
||||
// Check if this was a begin label. Otherwise, it must be an end label or
|
||||
// some random label, and we should continue.
|
||||
auto StateAndEnd = FuncInfo.InvokeToStateMap.find(Label);
|
||||
if (StateAndEnd == FuncInfo.InvokeToStateMap.end())
|
||||
continue;
|
||||
|
||||
const PadRange &P = L->second;
|
||||
const LandingPadInfo *LandingPad = LandingPads[P.PadIndex];
|
||||
assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] &&
|
||||
"Inconsistent landing pad map!");
|
||||
// Extract the state and end label.
|
||||
int State;
|
||||
MCSymbol *EndLabel;
|
||||
std::tie(State, EndLabel) = StateAndEnd->second;
|
||||
|
||||
// FIXME: Should this be using FuncInfo.HandlerBaseState?
|
||||
// If there was a potentially throwing call between this begin label and
|
||||
// the last end label, we need an extra base state entry to indicate that
|
||||
// those calls unwind directly to the caller.
|
||||
if (SawPotentiallyThrowing && LastEHState != -1) {
|
||||
FuncInfo.IPToStateList.push_back(std::make_pair(LastLabel, -1));
|
||||
IPToStateTable.push_back(
|
||||
std::make_pair(getLabelPlusOne(LastEndLabel), -1));
|
||||
SawPotentiallyThrowing = false;
|
||||
LastEHState = -1;
|
||||
}
|
||||
|
||||
if (LandingPad->WinEHState != LastEHState)
|
||||
FuncInfo.IPToStateList.push_back(
|
||||
std::make_pair(BeginLabel, LandingPad->WinEHState));
|
||||
LastEHState = LandingPad->WinEHState;
|
||||
LastLabel = LandingPad->EndLabels[P.RangeIndex];
|
||||
// Emit an entry indicating that PCs after 'Label' have this EH state.
|
||||
if (State != LastEHState)
|
||||
IPToStateTable.push_back(std::make_pair(create32bitRef(Label), State));
|
||||
LastEHState = State;
|
||||
LastEndLabel = EndLabel;
|
||||
}
|
||||
}
|
||||
|
||||
if (LastEndLabel != Asm->getFunctionBegin()) {
|
||||
// Indicate that all calls from the last invoke until the epilogue unwind to
|
||||
// caller. This also ensures that we have at least one ip2state entry, if
|
||||
// somehow all invokes were deleted during CodeGen.
|
||||
IPToStateTable.push_back(std::make_pair(getLabelPlusOne(LastEndLabel), -1));
|
||||
}
|
||||
}
|
||||
|
||||
void WinException::emitEHRegistrationOffsetLabel(const WinEHFuncInfo &FuncInfo,
|
||||
|
|
|
@ -47,7 +47,9 @@ class LLVM_LIBRARY_VISIBILITY WinException : public EHStreamer {
|
|||
/// tables.
|
||||
void emitExceptHandlerTable(const MachineFunction *MF);
|
||||
|
||||
void extendIP2StateTable(const MachineFunction *MF, WinEHFuncInfo &FuncInfo);
|
||||
void computeIP2StateTable(
|
||||
const MachineFunction *MF, WinEHFuncInfo &FuncInfo,
|
||||
SmallVectorImpl<std::pair<const MCExpr *, int>> &IPToStateTable);
|
||||
|
||||
/// Emits the label used with llvm.x86.seh.recoverfp, which is used by
|
||||
/// outlined funclets.
|
||||
|
@ -56,6 +58,7 @@ class LLVM_LIBRARY_VISIBILITY WinException : public EHStreamer {
|
|||
|
||||
const MCExpr *create32bitRef(const MCSymbol *Value);
|
||||
const MCExpr *create32bitRef(const Value *V);
|
||||
const MCExpr *getLabelPlusOne(MCSymbol *Label);
|
||||
|
||||
public:
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
|
|
@ -5262,7 +5262,13 @@ SelectionDAGBuilder::lowerInvokable(TargetLowering::CallLoweringInfo &CLI,
|
|||
DAG.setRoot(DAG.getEHLabel(getCurSDLoc(), getRoot(), EndLabel));
|
||||
|
||||
// Inform MachineModuleInfo of range.
|
||||
MMI.addInvoke(FuncInfo.MBBMap[EHPadBB], BeginLabel, EndLabel);
|
||||
if (MMI.hasEHFunclets()) {
|
||||
WinEHFuncInfo &EHInfo =
|
||||
MMI.getWinEHFuncInfo(DAG.getMachineFunction().getFunction());
|
||||
EHInfo.addIPToStateRange(EHPadBB, BeginLabel, EndLabel);
|
||||
} else {
|
||||
MMI.addInvoke(FuncInfo.MBBMap[EHPadBB], BeginLabel, EndLabel);
|
||||
}
|
||||
}
|
||||
|
||||
return Result;
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "llvm/IR/IntrinsicInst.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/PatternMatch.h"
|
||||
#include "llvm/MC/MCSymbol.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
@ -3499,3 +3500,12 @@ void WinEHPrepare::replaceUseWithLoad(Value *V, Use &U, AllocaInst *&SpillSlot,
|
|||
U.set(Load);
|
||||
}
|
||||
}
|
||||
|
||||
void WinEHFuncInfo::addIPToStateRange(const BasicBlock *PadBB,
|
||||
MCSymbol *InvokeBegin,
|
||||
MCSymbol *InvokeEnd) {
|
||||
assert(PadBB->isEHPad() && EHPadStateMap.count(PadBB->getFirstNonPHI()) &&
|
||||
"should get EH pad BB with precomputed state");
|
||||
InvokeToStateMap[InvokeBegin] =
|
||||
std::make_pair(EHPadStateMap[PadBB->getFirstNonPHI()], InvokeEnd);
|
||||
}
|
||||
|
|
|
@ -119,12 +119,14 @@ catchendblock: ; preds = %catch, %catch.2, %c
|
|||
; X86-NEXT: .long [[catch2bb]]
|
||||
|
||||
; X64-LABEL: try_catch_catch:
|
||||
; X64: Lfunc_begin0:
|
||||
; X64: pushq %rbp
|
||||
; X64: .seh_pushreg 5
|
||||
; X64: subq $48, %rsp
|
||||
; X64: .seh_stackalloc 48
|
||||
; X64: leaq 48(%rsp), %rbp
|
||||
; X64: .seh_setframe 5, 48
|
||||
; X64: .Ltmp0
|
||||
; X64-DAG: leaq -[[local_offs:[0-9]+]](%rbp), %rdx
|
||||
; X64-DAG: movl $1, %ecx
|
||||
; X64: callq f
|
||||
|
@ -138,6 +140,7 @@ catchendblock: ; preds = %catch, %catch.2, %c
|
|||
; X64: pushq %rbp
|
||||
; X64: movq %rdx, %rbp
|
||||
; X64: subq $32, %rsp
|
||||
; X64-DAG: .Ltmp4
|
||||
; X64-DAG: leaq -[[local_offs]](%rbp), %rdx
|
||||
; X64-DAG: movl [[e_addr:[-0-9]+]](%rbp), %ecx
|
||||
; X64: callq f
|
||||
|
@ -154,20 +157,50 @@ catchendblock: ; preds = %catch, %catch.2, %c
|
|||
; X64-DAG: leaq -[[local_offs]](%rbp), %rdx
|
||||
; X64-DAG: movl $3, %ecx
|
||||
; X64: callq f
|
||||
; X64: .Ltmp3
|
||||
; X64: addq $32, %rsp
|
||||
; X64-NEXT: popq %rbp
|
||||
; X64-NEXT: leaq [[contbb]](%rip), %rax
|
||||
; X64-NEXT: retq
|
||||
|
||||
; X64: $cppxdata$try_catch_catch:
|
||||
; X64-NEXT: .long 429065506
|
||||
; X64-NEXT: .long 2
|
||||
; X64-NEXT: .long ($stateUnwindMap$try_catch_catch)@IMGREL
|
||||
; X64-NEXT: .long 1
|
||||
; X64-NEXT: .long ($tryMap$try_catch_catch)@IMGREL
|
||||
; X64-NEXT: .long 4
|
||||
; X64-NEXT: .long ($ip2state$try_catch_catch)@IMGREL
|
||||
; X64-NEXT: .long 32
|
||||
; X64-NEXT: .long 0
|
||||
; X64-NEXT: .long 1
|
||||
|
||||
; X64: $tryMap$try_catch_catch:
|
||||
; X64-NEXT: .long 0
|
||||
; X64-NEXT: .long 0
|
||||
; X64-NEXT: .long 1
|
||||
; X64-NEXT: .long 2
|
||||
; X64-NEXT: .long ($handlerMap$0$try_catch_catch)@IMGREL
|
||||
|
||||
; X64: $handlerMap$0$try_catch_catch:
|
||||
; X64: .long 0
|
||||
; X64: .long "??_R0H@8"@IMGREL
|
||||
; X64-NEXT: .long 0
|
||||
; X64-NEXT: .long "??_R0H@8"@IMGREL
|
||||
; FIXME: This should probably be offset from rsp, not rbp.
|
||||
; X64: .long [[e_addr]]
|
||||
; X64: .long [[catch1bb]]@IMGREL
|
||||
; X64: .long 56
|
||||
; X64: .long 64
|
||||
; X64: .long 0
|
||||
; X64: .long 0
|
||||
; X64: .long [[catch2bb]]@IMGREL
|
||||
; X64: .long 56
|
||||
; X64-NEXT: .long [[e_addr]]
|
||||
; X64-NEXT: .long [[catch1bb]]@IMGREL
|
||||
; X64-NEXT: .long 56
|
||||
; X64-NEXT: .long 64
|
||||
; X64-NEXT: .long 0
|
||||
; X64-NEXT: .long 0
|
||||
; X64-NEXT: .long [[catch2bb]]@IMGREL
|
||||
; X64-NEXT: .long 56
|
||||
|
||||
; X64: $ip2state$try_catch_catch:
|
||||
; X64-NEXT: .long .Lfunc_begin0@IMGREL
|
||||
; X64-NEXT: .long -1
|
||||
; X64-NEXT: .long .Ltmp0@IMGREL
|
||||
; X64-NEXT: .long 0
|
||||
; X64-NEXT: .long .Ltmp4@IMGREL
|
||||
; X64-NEXT: .long 1
|
||||
; X64-NEXT: .long .Ltmp3@IMGREL+1
|
||||
; X64-NEXT: .long -1
|
||||
|
|
|
@ -96,12 +96,19 @@ cleanup.outer: ; preds = %invoke.cont.1, %c
|
|||
; X86: .long LBB1_[[cleanup_inner]]
|
||||
|
||||
; X64-LABEL: nested_cleanup:
|
||||
; X64: .Lfunc_begin1:
|
||||
; X64: .Ltmp8:
|
||||
; X64: movl $1, %ecx
|
||||
; X64: callq f
|
||||
; X64: .Ltmp10:
|
||||
; X64: movl $2, %ecx
|
||||
; X64: callq f
|
||||
; X64: .Ltmp11:
|
||||
; X64: callq "??1Dtor@@QAE@XZ"
|
||||
; X64: .Ltmp12:
|
||||
; X64: movl $3, %ecx
|
||||
; X64: callq f
|
||||
; X64: .Ltmp13:
|
||||
|
||||
; X64: .LBB1_[[cleanup_inner:[0-9]+]]: # %cleanup.inner
|
||||
; X64: pushq %rbp
|
||||
|
@ -117,29 +124,38 @@ cleanup.outer: ; preds = %invoke.cont.1, %c
|
|||
; X64: popq %rbp
|
||||
; X64: retq
|
||||
|
||||
; X64: .seh_handlerdata
|
||||
; X64: .long ($cppxdata$nested_cleanup)@IMGREL
|
||||
; X64: .align 4
|
||||
; X64:$cppxdata$nested_cleanup:
|
||||
; X64: .long 429065506
|
||||
; X64: .long 2
|
||||
; X64: .long ($stateUnwindMap$nested_cleanup)@IMGREL
|
||||
; X64: .long 0
|
||||
; X64: .long 0
|
||||
; X64: .long 1
|
||||
; X64: .long ($ip2state$nested_cleanup)@IMGREL
|
||||
; X64: .long 40
|
||||
; X64: .long 0
|
||||
; X64: .long 1
|
||||
; X64:$stateUnwindMap$nested_cleanup:
|
||||
; X64: .long -1
|
||||
; X64: .long .LBB1_[[cleanup_outer]]@IMGREL
|
||||
; X64: .long 0
|
||||
; X64: .long .LBB1_[[cleanup_inner]]@IMGREL
|
||||
; FIXME: The ip2state table is totally wrong.
|
||||
; X64:$ip2state$nested_cleanup:
|
||||
; X64: .long .Lfunc_begin1@IMGREL
|
||||
; X64: .long -1
|
||||
; X64: .seh_handlerdata
|
||||
; X64-NEXT: .long ($cppxdata$nested_cleanup)@IMGREL
|
||||
; X64-NEXT: .align 4
|
||||
; X64: $cppxdata$nested_cleanup:
|
||||
; X64-NEXT: .long 429065506
|
||||
; X64-NEXT: .long 2
|
||||
; X64-NEXT: .long ($stateUnwindMap$nested_cleanup)@IMGREL
|
||||
; X64-NEXT: .long 0
|
||||
; X64-NEXT: .long 0
|
||||
; X64-NEXT: .long 5
|
||||
; X64-NEXT: .long ($ip2state$nested_cleanup)@IMGREL
|
||||
; X64-NEXT: .long 40
|
||||
; X64-NEXT: .long 0
|
||||
; X64-NEXT: .long 1
|
||||
|
||||
; X64: $stateUnwindMap$nested_cleanup:
|
||||
; X64-NEXT: .long -1
|
||||
; X64-NEXT: .long .LBB1_[[cleanup_outer]]@IMGREL
|
||||
; X64-NEXT: .long 0
|
||||
; X64-NEXT: .long .LBB1_[[cleanup_inner]]@IMGREL
|
||||
|
||||
; X64: $ip2state$nested_cleanup:
|
||||
; X64-NEXT: .long .Lfunc_begin1@IMGREL
|
||||
; X64-NEXT: .long -1
|
||||
; X64-NEXT: .long .Ltmp8@IMGREL
|
||||
; X64-NEXT: .long 0
|
||||
; X64-NEXT: .long .Ltmp10@IMGREL
|
||||
; X64-NEXT: .long 1
|
||||
; X64-NEXT: .long .Ltmp12@IMGREL
|
||||
; X64-NEXT: .long 0
|
||||
; X64-NEXT: .long .Ltmp13@IMGREL+1
|
||||
; X64-NEXT: .long -1
|
||||
|
||||
attributes #0 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
|
||||
attributes #1 = { nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
|
||||
|
|
Loading…
Reference in New Issue