diff --git a/clang/test/CodeGen/basic-block-sections.c b/clang/test/CodeGen/basic-block-sections.c --- a/clang/test/CodeGen/basic-block-sections.c +++ b/clang/test/CodeGen/basic-block-sections.c @@ -1,12 +1,12 @@ // REQUIRES: x86-registered-target -// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -S -o - < %s | FileCheck %s --check-prefix=PLAIN -// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -S -fbasic-block-sections=all -fbasic-block-sections=none -o - < %s | FileCheck %s --check-prefix=PLAIN +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -S -o - < %s | FileCheck %s --check-prefix=PLAIN +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -S -fbasic-block-sections=all -fbasic-block-sections=none -o - < %s | FileCheck %s --check-prefix=PLAIN -// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -S -fbasic-block-sections=labels -o - < %s | FileCheck %s --check-prefix=BB_LABELS -// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -S -fbasic-block-sections=all -o - < %s | FileCheck %s --check-prefix=BB_WORLD --check-prefix=BB_ALL -// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -S -fbasic-block-sections=list=%S/Inputs/basic-block-sections.funcnames -o - < %s | FileCheck %s --check-prefix=BB_WORLD --check-prefix=BB_LIST -// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -S -fbasic-block-sections=all -funique-basic-block-section-names -o - < %s | FileCheck %s --check-prefix=UNIQUE +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -S -fbasic-block-sections=labels -o - < %s | FileCheck %s --check-prefix=BB_LABELS +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -S -fbasic-block-sections=all -o - < %s | FileCheck %s --check-prefix=BB_WORLD --check-prefix=BB_ALL +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -S -fbasic-block-sections=list=%S/Inputs/basic-block-sections.funcnames -o - < %s | FileCheck %s --check-prefix=BB_WORLD --check-prefix=BB_LIST +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -S -fbasic-block-sections=all -funique-basic-block-section-names -o - < %s | FileCheck %s --check-prefix=UNIQUE int world(int a) { if (a > 10) @@ -28,9 +28,66 @@ // // BB_LABELS-NOT: section // BB_LABELS: world: -// BB_LABELS: a.BB.world: -// BB_LABELS: aa.BB.world: -// BB_LABELS: a.BB.another: +// BB_LABELS: .Lfunc_begin0: +// BB_LABELS: .LBB_END0_0: +// BB_LABELS: .LBB0_1: +// BB_LABELS: .LBB_END0_1: +// BB_LABELS: .LBB0_3: +// BB_LABELS: .LBB_END0_3: +// BB_LABELS: .LBB0_4: +// BB_LABELS: .LBB_END0_4: +// BB_LABELS: .LBB0_5: +// BB_LABELS: .LBB_END0_5: +// BB_LABELS: .Lfunc_end0: +// +// BB_LABELS: .section .bb_info,"o",@progbits,.text +// BB_LABELS-NEXT: .quad .Lfunc_begin0 +// BB_LABELS-NEXT: .byte 6 +// BB_LABELS-NEXT: .uleb128 .Lfunc_begin0-.Lfunc_begin0 +// BB_LABELS-NEXT: .uleb128 .LBB_END0_0-.Lfunc_begin0 +// BB_LABELS-NEXT: .byte 0 +// BB_LABELS-NEXT: .uleb128 .LBB0_1-.Lfunc_begin0 +// BB_LABELS-NEXT: .uleb128 .LBB_END0_1-.LBB0_1 +// BB_LABELS-NEXT: .byte 0 +// BB_LABELS-NEXT: .uleb128 .LBB0_2-.Lfunc_begin0 +// BB_LABELS-NEXT: .uleb128 .LBB_END0_2-.LBB0_2 +// BB_LABELS-NEXT: .byte 0 +// BB_LABELS-NEXT: .uleb128 .LBB0_3-.Lfunc_begin0 +// BB_LABELS-NEXT: .uleb128 .LBB_END0_3-.LBB0_3 +// BB_LABELS-NEXT: .byte 0 +// BB_LABELS-NEXT: .uleb128 .LBB0_4-.Lfunc_begin0 +// BB_LABELS-NEXT: .uleb128 .LBB_END0_4-.LBB0_4 +// BB_LABELS-NEXT: .byte 0 +// BB_LABELS-NEXT: .uleb128 .LBB0_5-.Lfunc_begin0 +// BB_LABELS-NEXT: .uleb128 .LBB_END0_5-.LBB0_5 +// BB_LABELS-NEXT: .byte 1 +// +// BB_LABELS: another: +// BB_LABELS: .Lfunc_begin1: +// BB_LABELS: .LBB_END1_0: +// BB_LABELS: .LBB1_1: +// BB_LABELS: .LBB_END1_1: +// BB_LABELS: .LBB1_2: +// BB_LABELS: .LBB_END1_2: +// BB_LABELS: .LBB1_3: +// BB_LABELS: .LBB_END1_3: +// BB_LABELS: .Lfunc_end1: +// +// BB_LABELS: .section .bb_info,"o",@progbits,.text +// BB_LABELS-NEXT: .quad .Lfunc_begin1 +// BB_LABELS-NEXT: .byte 4 +// BB_LABELS-NEXT: .uleb128 .Lfunc_begin1-.Lfunc_begin1 +// BB_LABELS-NEXT: .uleb128 .LBB_END1_0-.Lfunc_begin1 +// BB_LABELS-NEXT: .byte 0 +// BB_LABELS-NEXT: .uleb128 .LBB1_1-.Lfunc_begin1 +// BB_LABELS-NEXT: .uleb128 .LBB_END1_1-.LBB1_1 +// BB_LABELS-NEXT: .byte 0 +// BB_LABELS-NEXT: .uleb128 .LBB1_2-.Lfunc_begin1 +// BB_LABELS-NEXT: .uleb128 .LBB_END1_2-.LBB1_2 +// BB_LABELS-NEXT: .byte 0 +// BB_LABELS-NEXT: .uleb128 .LBB1_3-.Lfunc_begin1 +// BB_LABELS-NEXT: .uleb128 .LBB_END1_3-.LBB1_3 +// BB_LABELS-NEXT: .byte 1 // // BB_WORLD: .section .text.world,"ax",@progbits{{$}} // BB_WORLD: world: diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h --- a/llvm/include/llvm/CodeGen/AsmPrinter.h +++ b/llvm/include/llvm/CodeGen/AsmPrinter.h @@ -342,6 +342,8 @@ void emitStackSizeSection(const MachineFunction &MF); + void emitBBAddrMapSection(const MachineFunction &MF); + void emitRemarksSection(remarks::RemarkStreamer &RS); enum CFIMoveType { CFI_M_None, CFI_M_EH, CFI_M_Debug }; diff --git a/llvm/include/llvm/CodeGen/MachineBasicBlock.h b/llvm/include/llvm/CodeGen/MachineBasicBlock.h --- a/llvm/include/llvm/CodeGen/MachineBasicBlock.h +++ b/llvm/include/llvm/CodeGen/MachineBasicBlock.h @@ -478,6 +478,15 @@ /// Returns the MCSymbol marking the end of this basic block. MCSymbol *getEndSymbol() const; + /// Returns the BB metadata to be emitted in the bb_addr_map section. + /// The format of the result is described as follows. + /// + /// 1st bit (LSB): set if this is a return block (return or tail call). + /// 2nd bit: set if this is a block ending with a tail call. + /// 3rd bit: seet if this is an exception handling (EH) pad. + /// The remaining bits are zero. + unsigned getBBAddrMapMetadata() const; + /// Returns true if this block may have an INLINEASM_BR (overestimate, by /// checking if any of the successors are indirect targets of any inlineasm_br /// in the function). diff --git a/llvm/include/llvm/CodeGen/MachineFunction.h b/llvm/include/llvm/CodeGen/MachineFunction.h --- a/llvm/include/llvm/CodeGen/MachineFunction.h +++ b/llvm/include/llvm/CodeGen/MachineFunction.h @@ -504,9 +504,6 @@ void setBBSectionsType(BasicBlockSection V) { BBSectionsType = V; } - /// Creates basic block Labels for this function. - void createBBLabels(); - /// Assign IsBeginSection IsEndSection fields for basic blocks in this /// function. void assignBeginEndSections(); diff --git a/llvm/include/llvm/MC/MCObjectFileInfo.h b/llvm/include/llvm/MC/MCObjectFileInfo.h --- a/llvm/include/llvm/MC/MCObjectFileInfo.h +++ b/llvm/include/llvm/MC/MCObjectFileInfo.h @@ -338,6 +338,8 @@ MCSection *getStackSizesSection(const MCSection &TextSec) const; + MCSection *getBBAddrMapSection(const MCSection &TextSec) const; + // ELF specific sections. MCSection *getDataRelROSection() const { return DataRelROSection; } const MCSection *getMergeableConst4Section() const { diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -1023,6 +1023,36 @@ MCConstantExpr::create(FrameOffset, OutContext)); } +void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) { + // Do not emit the section if BB labels are not requested for this function. + if (!MF.hasBBLabels()) + return; + + MCSection *BBAddrMapSection = + getObjFileLowering().getBBAddrMapSection(*MF.getSection()); + if (!BBAddrMapSection) + return; + + const MCSymbol *FunctionSymbol = getFunctionBegin(); + + OutStreamer->PushSection(); + OutStreamer->SwitchSection(BBAddrMapSection); + OutStreamer->emitSymbolValue(FunctionSymbol, getPointerSize()); + // Emit the total number of basic blocks in this function. + OutStreamer->emitULEB128IntValue(MF.size()); + // Emit BB Information for each basic block in the funciton. + for (const auto &MBB : MF) { + const MCSymbol *MBBSymbol = + MBB.pred_empty() ? FunctionSymbol : MBB.getSymbol(); + // Emit the basic block offset. + emitLabelDifferenceAsULEB128(MBBSymbol, FunctionSymbol); + // Emit the basic block size. + emitLabelDifferenceAsULEB128(MBB.getEndSymbol(), MBBSymbol); + OutStreamer->emitULEB128IntValue(MBB.getBBAddrMapMetadata()); + } + OutStreamer->PopSection(); +} + void AsmPrinter::emitStackSizeSection(const MachineFunction &MF) { if (!MF.getTarget().Options.EmitStackSizeSection) return; @@ -1174,34 +1204,26 @@ } // We must emit temporary symbol for the end of this basic block, if either - // we have BBLabels enabled and we want to emit size directive for the BBs, - // or if this basic blocks marks the end of a section (except the section - // containing the entry basic block as the end symbol for that section is - // CurrentFnEnd). - if ((MAI->hasDotTypeDotSizeDirective() && MF->hasBBLabels()) || - (MBB.isEndSection() && !MBB.sameSection(&MF->front()))) + // we have BBLabels enabled or if this basic blocks marks the end of a + // section (except the section containing the entry basic block as the end + // symbol for that section is CurrentFnEnd). + if (MF->hasBBLabels() || + (MAI->hasDotTypeDotSizeDirective() && MBB.isEndSection() && + !MBB.sameSection(&MF->front()))) OutStreamer->emitLabel(MBB.getEndSymbol()); - // Helper for emitting the size directive associated with a basic block - // symbol. - auto emitELFSizeDirective = [&](MCSymbol *SymForSize) { - const MCExpr *SizeExp = MCBinaryExpr::createSub( - MCSymbolRefExpr::create(MBB.getEndSymbol(), OutContext), - MCSymbolRefExpr::create(SymForSize, OutContext), OutContext); - OutStreamer->emitELFSize(SymForSize, SizeExp); - }; - - // Emit size directive for the size of each basic block, if BBLabels is - // enabled. - if (MAI->hasDotTypeDotSizeDirective() && MF->hasBBLabels()) - emitELFSizeDirective(MBB.getSymbol()); - - // Emit size directive for the size of each basic block section once we - // get to the end of that section. if (MBB.isEndSection()) { + // The size directive for the section containing the entry block is + // handled separately by the function section. if (!MBB.sameSection(&MF->front())) { - if (MAI->hasDotTypeDotSizeDirective()) - emitELFSizeDirective(CurrentSectionBeginSym); + if (MAI->hasDotTypeDotSizeDirective()) { + // Emit the size directive for the basic block section. + const MCExpr *SizeExp = MCBinaryExpr::createSub( + MCSymbolRefExpr::create(MBB.getEndSymbol(), OutContext), + MCSymbolRefExpr::create(CurrentSectionBeginSym, OutContext), + OutContext); + OutStreamer->emitELFSize(CurrentSectionBeginSym, SizeExp); + } MBBSectionRanges[MBB.getSectionIDNum()] = MBBSectionRange{CurrentSectionBeginSym, MBB.getEndSymbol()}; } @@ -1293,6 +1315,9 @@ HI.Handler->endFunction(MF); } + // Emit section containing BB address offsets and their metadata. + emitBBAddrMapSection(*MF); + // Emit section containing stack size metadata. emitStackSizeSection(*MF); @@ -1802,7 +1827,7 @@ F.hasFnAttribute("function-instrument") || F.hasFnAttribute("xray-instruction-threshold") || needFuncLabelsForEHOrDebugInfo(MF) || NeedsLocalForSize || - MF.getTarget().Options.EmitStackSizeSection) { + MF.getTarget().Options.EmitStackSizeSection || MF.hasBBLabels()) { CurrentFnBegin = createTempSymbol("func_begin"); if (NeedsLocalForSize) CurrentFnSymForSize = CurrentFnBegin; diff --git a/llvm/lib/CodeGen/BasicBlockSections.cpp b/llvm/lib/CodeGen/BasicBlockSections.cpp --- a/llvm/lib/CodeGen/BasicBlockSections.cpp +++ b/llvm/lib/CodeGen/BasicBlockSections.cpp @@ -336,7 +336,6 @@ if (BBSectionsType == BasicBlockSection::Labels) { MF.setBBSectionsType(BBSectionsType); - MF.createBBLabels(); return true; } @@ -346,7 +345,6 @@ FuncBBClusterInfo)) return true; MF.setBBSectionsType(BBSectionsType); - MF.createBBLabels(); assignSectionsAndSortBasicBlocks(MF, FuncBBClusterInfo); return true; } diff --git a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp --- a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp +++ b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp @@ -446,10 +446,8 @@ } // Check Basic Block Section Flags. if (MF.getTarget().getBBSectionsType() == BasicBlockSection::Labels) { - MF.createBBLabels(); MF.setBBSectionsType(BasicBlockSection::Labels); } else if (MF.hasBBSections()) { - MF.createBBLabels(); MF.assignBeginEndSections(); } PFS.SM = &SM; diff --git a/llvm/lib/CodeGen/MachineBasicBlock.cpp b/llvm/lib/CodeGen/MachineBasicBlock.cpp --- a/llvm/lib/CodeGen/MachineBasicBlock.cpp +++ b/llvm/lib/CodeGen/MachineBasicBlock.cpp @@ -55,33 +55,22 @@ MachineBasicBlock::~MachineBasicBlock() { } +unsigned MachineBasicBlock::getBBAddrMapMetadata() const { + const TargetInstrInfo *TII = getParent()->getSubtarget().getInstrInfo(); + return ((unsigned)isReturnBlock()) | + ((!empty() && TII->isTailCall(back())) << 1) | (isEHPad() << 2); +} + /// Return the MCSymbol for this basic block. MCSymbol *MachineBasicBlock::getSymbol() const { if (!CachedMCSymbol) { const MachineFunction *MF = getParent(); MCContext &Ctx = MF->getContext(); - auto Prefix = Ctx.getAsmInfo()->getPrivateLabelPrefix(); - assert(getNumber() >= 0 && "cannot get label for unreachable MBB"); - - // We emit a non-temporary symbol for every basic block if we have BBLabels - // or -- with basic block sections -- when a basic block begins a section. - // With basic block symbols, we use a unary encoding which can - // compress the symbol names significantly. For basic block sections where - // this block is the first in a cluster, we use a non-temp descriptive name. - // Otherwise we fall back to use temp label. - if (MF->hasBBLabels()) { - auto Iter = MF->getBBSectionsSymbolPrefix().begin(); - if (getNumber() < 0 || - getNumber() >= (int)MF->getBBSectionsSymbolPrefix().size()) - report_fatal_error("Unreachable MBB: " + Twine(getNumber())); - // The basic blocks for function foo are named a.BB.foo, aa.BB.foo, and - // so on. - std::string Prefix(Iter + 1, Iter + getNumber() + 1); - std::reverse(Prefix.begin(), Prefix.end()); - CachedMCSymbol = - Ctx.getOrCreateSymbol(Twine(Prefix) + ".BB." + Twine(MF->getName())); - } else if (MF->hasBBSections() && isBeginSection()) { + // We emit a non-temporary symbol -- with a descriptive name -- if it begins + // a section (with basic block sections). Otherwise we fall back to use temp + // label. + if (MF->hasBBSections() && isBeginSection()) { SmallString<5> Suffix; if (SectionID == MBBSectionID::ColdSectionID) { Suffix += ".cold"; @@ -92,6 +81,7 @@ } CachedMCSymbol = Ctx.getOrCreateSymbol(MF->getName() + Suffix); } else { + auto Prefix = Ctx.getAsmInfo()->getPrivateLabelPrefix(); CachedMCSymbol = Ctx.getOrCreateSymbol(Twine(Prefix) + "BB" + Twine(MF->getFunctionNumber()) + "_" + Twine(getNumber())); diff --git a/llvm/lib/CodeGen/MachineFunction.cpp b/llvm/lib/CodeGen/MachineFunction.cpp --- a/llvm/lib/CodeGen/MachineFunction.cpp +++ b/llvm/lib/CodeGen/MachineFunction.cpp @@ -341,33 +341,6 @@ MBBNumbering.resize(BlockNo); } -/// This is used with -fbasic-block-sections or -fbasicblock-labels option. -/// A unary encoding of basic block labels is done to keep ".strtab" sizes -/// small. -void MachineFunction::createBBLabels() { - const TargetInstrInfo *TII = getSubtarget().getInstrInfo(); - this->BBSectionsSymbolPrefix.resize(getNumBlockIDs(), 'a'); - for (auto MBBI = begin(), E = end(); MBBI != E; ++MBBI) { - assert( - (MBBI->getNumber() >= 0 && MBBI->getNumber() < (int)getNumBlockIDs()) && - "BasicBlock number was out of range!"); - // 'a' - Normal block. - // 'r' - Return block. - // 'l' - Landing Pad. - // 'L' - Return and landing pad. - bool isEHPad = MBBI->isEHPad(); - bool isRetBlock = MBBI->isReturnBlock() && !TII->isTailCall(MBBI->back()); - char type = 'a'; - if (isEHPad && isRetBlock) - type = 'L'; - else if (isEHPad) - type = 'l'; - else if (isRetBlock) - type = 'r'; - BBSectionsSymbolPrefix[MBBI->getNumber()] = type; - } -} - /// This method iterates over the basic blocks and assigns their IsBeginSection /// and IsEndSection fields. This must be called after MBB layout is finalized /// and the SectionID's are assigned to MBBs. diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp --- a/llvm/lib/MC/MCObjectFileInfo.cpp +++ b/llvm/lib/MC/MCObjectFileInfo.cpp @@ -953,3 +953,20 @@ GroupName, MCSection::NonUniqueID, cast(TextSec.getBeginSymbol())); } + +MCSection *MCObjectFileInfo::getBBAddrMapSection(const MCSection &TextSec) const { + if (Env != IsELF) + return nullptr; + + const MCSectionELF &ElfSec = static_cast(TextSec); + unsigned Flags = ELF::SHF_LINK_ORDER; + StringRef GroupName; + if (const MCSymbol *Group = ElfSec.getGroup()) { + GroupName = Group->getName(); + Flags |= ELF::SHF_GROUP; + } + + return Ctx->getELFSection(".bb_addr_map", ELF::SHT_PROGBITS, Flags, 0, GroupName, + MCSection::NonUniqueID, + cast(TextSec.getBeginSymbol())); +} diff --git a/llvm/test/CodeGen/X86/basic-block-sections-labels-functions-sections.ll b/llvm/test/CodeGen/X86/basic-block-sections-labels-functions-sections.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/X86/basic-block-sections-labels-functions-sections.ll @@ -0,0 +1,35 @@ +; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -function-sections -basic-block-sections=labels | FileCheck %s + +$_Z4fooTIiET_v = comdat any + +define dso_local i32 @_Z3barv() { + ret i32 0 +} +;; Check we add SHF_LINK_ORDER for .bb_addr_map and link it with the corresponding .text sections. +; CHECK: .section .text._Z3barv,"ax",@progbits +; CHECK-LABEL: _Z3barv: +; CHECK-NEXT: [[BAR_BEGIN:.+]]: +; CHECK: .section .bb_addr_map,"o",@progbits,.text._Z3barv{{$}} +; CHECK-NEXT: .quad [[BAR_BEGIN]] + + +define dso_local i32 @_Z3foov() { + %1 = call i32 @_Z4fooTIiET_v() + ret i32 %1 +} +; CHECK: .section .text._Z3foov,"ax",@progbits +; CHECK-LABEL: _Z3foov: +; CHECK-NEXT: [[FOO_BEGIN:.+]]: +; CHECK: .section .bb_addr_map,"o",@progbits,.text._Z3foov{{$}} +; CHECK-NEXT: .quad [[FOO_BEGIN]] + + +define linkonce_odr dso_local i32 @_Z4fooTIiET_v() comdat { + ret i32 0 +} +;; Check we add .bb_addr_map section to a COMDAT group with the corresponding .text section if such a COMDAT exists. +; CHECK: .section .text._Z4fooTIiET_v,"axG",@progbits,_Z4fooTIiET_v,comdat +; CHECK-LABEL: _Z4fooTIiET_v: +; CHECK-NEXT: [[FOOCOMDAT_BEGIN:.+]]: +; CHECK: .section .bb_addr_map,"Go",@progbits,_Z4fooTIiET_v,comdat,.text._Z4fooTIiET_v{{$}} +; CHECK-NEXT: .quad [[FOOCOMDAT_BEGIN]] diff --git a/llvm/test/CodeGen/X86/basic-block-sections-labels.ll b/llvm/test/CodeGen/X86/basic-block-sections-labels.ll --- a/llvm/test/CodeGen/X86/basic-block-sections-labels.ll +++ b/llvm/test/CodeGen/X86/basic-block-sections-labels.ll @@ -1,23 +1,29 @@ ; Check the basic block sections labels option -; RUN: llc < %s -mtriple=x86_64-pc-linux -function-sections -basic-block-sections=labels | FileCheck %s -check-prefix=LINUX-LABELS +; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -function-sections -basic-block-sections=labels | FileCheck %s -check-prefix=LINUX-LABELS -define void @_Z3bazb(i1 zeroext) { +define void @_Z3bazb(i1 zeroext) personality i32 (...)* @__gxx_personality_v0 { %2 = alloca i8, align 1 %3 = zext i1 %0 to i8 store i8 %3, i8* %2, align 1 %4 = load i8, i8* %2, align 1 %5 = trunc i8 %4 to i1 - br i1 %5, label %6, label %8 + br i1 %5, label %6, label %11 -6: ; preds = %1 - %7 = call i32 @_Z3barv() - br label %10 +6: + %7 = invoke i32 @_Z3barv() + to label %11 unwind label %9 + br label %13 -8: ; preds = %1 - %9 = call i32 @_Z3foov() - br label %10 +9: + landingpad { i8*, i32 } + catch i8* null + br label %13 -10: ; preds = %8, %6 +11: + %12 = call i32 @_Z3foov() + br label %13 + +13: ret void } @@ -25,9 +31,31 @@ declare i32 @_Z3foov() #1 -; LINUX-LABELS: .section -; LINUX-LABELS: _Z3bazb: -; LINUX-LABELS-NOT: .section -; LINUX-LABELS: r.BB._Z3bazb: -; LINUX-LABELS-NOT: .section -; LINUX-LABELS: rr.BB._Z3bazb: +declare i32 @__gxx_personality_v0(...) + +; LINUX-LABELS-LABEL: _Z3bazb: +; LINUX-LABELS: .Lfunc_begin0: +; LINUX-LABELS: .LBB_END0_[[L1:[0-9]+]]: +; LINUX-LABELS: .LBB0_[[L2:[0-9]+]]: +; LINUX-LABELS: .LBB_END0_[[L2]]: +; LINUX-LABELS: .LBB0_[[L3:[0-9]+]]: +; LINUX-LABELS: .LBB_END0_[[L3]]: +; LINUX-LABELS: .LBB0_[[L4:[0-9]+]]: +; LINUX-LABELS: .LBB_END0_[[L4]]: +; LINUX-LABELS: .Lfunc_end0: + +; LINUX-LABELS: .section .bb_addr_map,"o",@progbits,.text +; LINUX-LABELS-NEXT: .quad .Lfunc_begin0 +; LINUX-LABELS-NEXT: .byte 4 +; LINUX-LABELS-NEXT: .uleb128 .Lfunc_begin0-.Lfunc_begin0 +; LINUX-LABELS-NEXT: .uleb128 .LBB_END0_[[L1]]-.Lfunc_begin0 +; LINUX-LABELS-NEXT: .byte 0 +; LINUX-LABELS-NEXT: .uleb128 .LBB0_[[L2]]-.Lfunc_begin0 +; LINUX-LABELS-NEXT: .uleb128 .LBB_END0_[[L2]]-.LBB0_[[L2]] +; LINUX-LABELS-NEXT: .byte 0 +; LINUX-LABELS-NEXT: .uleb128 .LBB0_[[L3]]-.Lfunc_begin0 +; LINUX-LABELS-NEXT: .uleb128 .LBB_END0_[[L3]]-.LBB0_[[L3]] +; LINUX-LABELS-NEXT: .byte 1 +; LINUX-LABELS-NEXT: .uleb128 .LBB0_[[L4]]-.Lfunc_begin0 +; LINUX-LABELS-NEXT: .uleb128 .LBB_END0_[[L4]]-.LBB0_[[L4]] +; LINUX-LABELS-NEXT: .byte 5