diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst index 7c30570437e8b..0a8a2381082a3 100644 --- a/clang/docs/UsersManual.rst +++ b/clang/docs/UsersManual.rst @@ -2292,7 +2292,7 @@ are listed below. $ cd $P/bar && clang -c -funique-internal-linkage-names name_conflict.c $ cd $P && clang foo/name_conflict.o && bar/name_conflict.o -.. option:: -fbasic-block-sections=[labels, all, list=, none] +.. option:: -fbasic-block-sections=[labels, all, list=, listwithlabels=, none] Controls how Clang emits text sections for basic blocks. With values ``all`` and ``list=``, each basic block or a subset of basic blocks can be placed diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h index 6952b48e898a8..dbf550a6d1df2 100644 --- a/clang/include/clang/Basic/CodeGenOptions.h +++ b/clang/include/clang/Basic/CodeGenOptions.h @@ -117,6 +117,8 @@ class CodeGenOptions : public CodeGenOptionsBase { // "list=": Generate basic block sections for a subset of basic blocks. // The functions and the machine basic block ids are specified // in the file. + // "listwithlabels=": + // Mix of list and labels. // "none": Disable sections/labels for basic blocks. std::string BBSections; diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 2b93ddf033499..286956122f424 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3956,7 +3956,7 @@ def fbasic_block_sections_EQ : Joined<["-"], "fbasic-block-sections=">, Group, HelpText<"Place each function's basic blocks in unique sections (ELF Only)">, DocBrief<[{Generate labels for each basic block or place each basic block or a subset of basic blocks in its own section.}]>, - Values<"all,labels,none,list=">, + Values<"all,labels,none,list=,listwithlabels=">, MarshallingInfoString, [{"none"}]>; defm data_sections : BoolFOption<"data-sections", CodeGenOpts<"DataSections">, DefaultFalse, diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index a6142d99f3b68..b248ae3c56ae7 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -380,11 +380,15 @@ static bool initTargetOptions(DiagnosticsEngine &Diags, .Case("labels", llvm::BasicBlockSection::Labels) .StartsWith("list=", llvm::BasicBlockSection::List) .Case("none", llvm::BasicBlockSection::None) + .StartsWith("listwithlabels=", + llvm::BasicBlockSection::ListWithLabels) .Default(llvm::BasicBlockSection::None); - if (Options.BBSections == llvm::BasicBlockSection::List) { + if (Options.BBSections == llvm::BasicBlockSection::List || + Options.BBSections == llvm::BasicBlockSection::ListWithLabels) { ErrorOr> MBOrErr = - MemoryBuffer::getFile(CodeGenOpts.BBSections.substr(5)); + MemoryBuffer::getFile(CodeGenOpts.BBSections.substr( + Options.BBSections == llvm::BasicBlockSection::List ? 5 : 15)); if (!MBOrErr) { Diags.Report(diag::err_fe_unable_to_load_basic_block_sections_file) << MBOrErr.getError().message(); diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index acfa119805068..038c24d46fdd3 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -5888,7 +5888,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, StringRef Val = A->getValue(); if (Triple.isX86() && Triple.isOSBinFormatELF()) { if (Val != "all" && Val != "labels" && Val != "none" && - !Val.starts_with("list=")) + !Val.startswith("list=") && !Val.startswith("listwithlabels=")) D.Diag(diag::err_drv_invalid_value) << A->getAsString(Args) << A->getValue(); else diff --git a/clang/test/CodeGen/basic-block-sections.c b/clang/test/CodeGen/basic-block-sections.c index a61b8dd4ac376..e0e275fca662d 100644 --- a/clang/test/CodeGen/basic-block-sections.c +++ b/clang/test/CodeGen/basic-block-sections.c @@ -10,6 +10,8 @@ // RUN: not %clang_cc1 -fbasic-block-sections=list= -emit-obj -o %t %s 2>&1 | FileCheck -DMSG=%errc_ENOENT %s --check-prefix=ERROR // RUN: not ls %t +// RUN: %clang_cc1 -triple x86_64 -S -fbasic-block-sections=listwithlabels=%S/Inputs/basic-block-sections.funcnames -o - < %s | FileCheck %s --check-prefix=BB_WORLD --check-prefix=BB_LIST + int world(int a) { if (a > 10) return 10; @@ -37,7 +39,6 @@ int another(int a) { // BB_LIST-NOT: .section .text.another,"ax",@progbits // BB_LIST: another: // BB_LIST-NOT: another.__part.1: -// // UNIQUE: .section .text.world.world.__part.1, // UNIQUE: .section .text.another.another.__part.1, // ERROR: error: unable to load basic block sections function list: '[[MSG]]' diff --git a/clang/test/Driver/fbasic-block-sections.c b/clang/test/Driver/fbasic-block-sections.c index 24262209d1e4d..6a55977f99668 100644 --- a/clang/test/Driver/fbasic-block-sections.c +++ b/clang/test/Driver/fbasic-block-sections.c @@ -1,15 +1,18 @@ -// RUN: %clang -### --target=x86_64 -fbasic-block-sections=none %s -S 2>&1 | FileCheck -check-prefix=CHECK-OPT-NONE %s -// RUN: %clang -### --target=x86_64 -fbasic-block-sections=all %s -S 2>&1 | FileCheck -check-prefix=CHECK-OPT-ALL %s -// RUN: %clang -### --target=x86_64 -fbasic-block-sections=list=%s %s -S 2>&1 | FileCheck -check-prefix=CHECK-OPT-LIST %s -// RUN: %clang -### --target=x86_64 -fbasic-block-sections=labels %s -S 2>&1 | FileCheck -check-prefix=CHECK-OPT-LABELS %s -// RUN: not %clang -c --target=arm-unknown-linux -fbasic-block-sections=all %s -S 2>&1 | FileCheck -check-prefix=CHECK-TRIPLE %s -// RUN: %clang -### --target=arm-unknown-linux -fbasic-block-sections=all -fbasic-block-sections=none %s -S 2>&1 \ +// RUN: %clang -### -target x86_64 -fbasic-block-sections=none %s -S 2>&1 | FileCheck -check-prefix=CHECK-OPT-NONE %s +// RUN: %clang -### -target x86_64 -fbasic-block-sections=all %s -S 2>&1 | FileCheck -check-prefix=CHECK-OPT-ALL %s +// RUN: %clang -### -target x86_64 -fbasic-block-sections=list=%s %s -S 2>&1 | FileCheck -check-prefix=CHECK-OPT-LIST %s +// RUN: %clang -### -target x86_64 -fbasic-block-sections=listwithlabels=%s %s -S 2>&1 | FileCheck -check-prefix=CHECK-OPT-LISTWITHLABELS %s +// RUN: %clang -### -target x86_64 -fbasic-block-sections=labels %s -S 2>&1 | FileCheck -check-prefix=CHECK-OPT-LABELS %s +// RUN: not %clang -c -target arm-unknown-linux -fbasic-block-sections=all %s -S 2>&1 | FileCheck -check-prefix=CHECK-TRIPLE %s +// RUN: %clang -### -target arm-unknown-linux -fbasic-block-sections=all -fbasic-block-sections=none %s -S 2>&1 \ // RUN: | FileCheck -check-prefix=CHECK-NOOPT %s -// RUN: not %clang -c --target=x86_64-apple-darwin10 -fbasic-block-sections=all %s -S 2>&1 | FileCheck -check-prefix=CHECK-TRIPLE %s -// RUN: not %clang -### --target=x86_64 -fbasic-block-sections=alll %s -S 2>&1 | FileCheck -check-prefix=CHECK-INVALID-VALUE %s -// RUN: not %clang -### --target=x86_64 -fbasic-block-sections=list %s -S 2>&1 | FileCheck -check-prefix=CHECK-INVALID-VALUE %s -// RUN: %clang -### --target=x86_64 -fbasic-block-sections=list= %s -S 2>&1 | FileCheck -check-prefix=CHECK-OPT-NULL-LIST %s -// RUN: %clang -### --target=x86_64 -fbasic-block-sections=none %s -S 2>&1 | FileCheck -check-prefix=CHECK-OPT-NONE %s +// RUN: not %clang -c -target x86_64-apple-darwin10 -fbasic-block-sections=all %s -S 2>&1 | FileCheck -check-prefix=CHECK-TRIPLE %s +// RUN: not %clang -### -target x86_64 -fbasic-block-sections=alll %s -S 2>&1 | FileCheck -check-prefix=CHECK-INVALID-VALUE %s +// RUN: not %clang -### -target x86_64 -fbasic-block-sections=list %s -S 2>&1 | FileCheck -check-prefix=CHECK-INVALID-VALUE %s +// RUN: not %clang -### -target x86_64 -fbasic-block-sections=listwithlabels %s -S 2>&1 | FileCheck -check-prefix=CHECK-INVALID-VALUE %s +// RUN: %clang -### -target x86_64 -fbasic-block-sections=list= %s -S 2>&1 | FileCheck -check-prefix=CHECK-OPT-NULL-LIST %s +// RUN: %clang -### -target x86_64 -fbasic-block-sections=listwithlabels= %s -S 2>&1 | FileCheck -check-prefix=CHECK-OPT-NULL-LISTWITHLABELS %s +// RUN: %clang -### -target x86_64 -fbasic-block-sections=none %s -S 2>&1 | FileCheck -check-prefix=CHECK-OPT-NONE %s // RUN: %clang -### -x cuda -nocudainc -nocudalib --target=x86_64 -fbasic-block-sections=all --cuda-path=%S/Inputs/CUDA/usr/local/cuda %s -c 2>&1 \ // RUN: | FileCheck -check-prefix=CHECK-CUDA %s @@ -18,10 +21,12 @@ // CHECK-OPT-NONE: "-fbasic-block-sections=none" // CHECK-OPT-ALL: "-fbasic-block-sections=all" // CHECK-OPT-LIST: "-fbasic-block-sections={{[^ ]*}}fbasic-block-sections.c" +// CHECK-OPT-LISTWITHLABELS: "-fbasic-block-sections={{[^ ]*}}fbasic-block-sections.c" // CHECK-OPT-LABELS: "-fbasic-block-sections=labels" // CHECK-TRIPLE: error: unsupported option '-fbasic-block-sections=all' for target // CHECK-INVALID-VALUE: error: invalid value {{[^ ]*}} in '-fbasic-block-sections={{.*}}' // CHECK-OPT-NULL-LIST: "-fbasic-block-sections=list=" +// CHECK-OPT-NULL-LISTWITHLABELS: "-fbasic-block-sections=listwithlabels=" // GPU-side compilations should have no -fbasic-block-sections. It should only // be passed to the host compilation diff --git a/lld/ELF/LTO.cpp b/lld/ELF/LTO.cpp index 504c12aac6c56..3c0fb2b945a60 100644 --- a/lld/ELF/LTO.cpp +++ b/lld/ELF/LTO.cpp @@ -71,15 +71,19 @@ static lto::Config createConfig() { } else if (config->ltoBasicBlockSections == "none") { c.Options.BBSections = BasicBlockSection::None; } else { + if (config->ltoBasicBlockSections.startswith("listwithlabels")) + c.Options.BBSections = BasicBlockSection::ListWithLabels; + else + c.Options.BBSections = BasicBlockSection::List; ErrorOr> MBOrErr = - MemoryBuffer::getFile(config->ltoBasicBlockSections.str()); + MemoryBuffer::getFile(config->ltoBasicBlockSections.substr( + c.Options.BBSections == BasicBlockSection::List ? 0 : 15)); if (!MBOrErr) { error("cannot open " + config->ltoBasicBlockSections + ":" + MBOrErr.getError().message()); } else { c.Options.BBSectionsFuncListBuf = std::move(*MBOrErr); } - c.Options.BBSections = BasicBlockSection::List; } } diff --git a/llvm/include/llvm/CodeGen/MachineFunction.h b/llvm/include/llvm/CodeGen/MachineFunction.h index 05c9b14a423cd..74e2a044dc111 100644 --- a/llvm/include/llvm/CodeGen/MachineFunction.h +++ b/llvm/include/llvm/CodeGen/MachineFunction.h @@ -694,12 +694,14 @@ class LLVM_EXTERNAL_VISIBILITY MachineFunction { bool hasBBSections() const { return (BBSectionsType == BasicBlockSection::All || BBSectionsType == BasicBlockSection::List || - BBSectionsType == BasicBlockSection::Preset); + BBSectionsType == BasicBlockSection::Preset || + BBSectionsType == BasicBlockSection::ListWithLabels); } /// Returns true if basic block labels are to be generated for this function. bool hasBBLabels() const { - return BBSectionsType == BasicBlockSection::Labels; + return BBSectionsType == BasicBlockSection::Labels || + BBSectionsType == BasicBlockSection::ListWithLabels; } void setBBSectionsType(BasicBlockSection V) { BBSectionsType = V; } diff --git a/llvm/include/llvm/Target/TargetOptions.h b/llvm/include/llvm/Target/TargetOptions.h index 4df897c047a38..2b0bc586e3030 100644 --- a/llvm/include/llvm/Target/TargetOptions.h +++ b/llvm/include/llvm/Target/TargetOptions.h @@ -70,7 +70,8 @@ namespace llvm { Preset, // Similar to list but the blocks are identified by passes which // seek to use Basic Block Sections, e.g. MachineFunctionSplitter. // This option cannot be set via the command line. - None // Do not use Basic Block Sections. + ListWithLabels, // Mix of list and labels. + None // Do not use Basic Block Sections. }; enum class EABI { diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 4dd27702786e4..67733ab6e1f5b 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -128,7 +128,6 @@ #include #include #include - using namespace llvm; #define DEBUG_TYPE "asm-printer" @@ -1370,25 +1369,35 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) { MCSection *BBAddrMapSection = getObjFileLowering().getBBAddrMapSection(*MF.getSection()); assert(BBAddrMapSection && ".llvm_bb_addr_map section is not initialized."); - - const MCSymbol *FunctionSymbol = getFunctionBegin(); - - OutStreamer->pushSection(); - OutStreamer->switchSection(BBAddrMapSection); - OutStreamer->AddComment("version"); uint8_t BBAddrMapVersion = OutStreamer->getContext().getBBAddrMapVersion(); - OutStreamer->emitInt8(BBAddrMapVersion); - OutStreamer->AddComment("feature"); - OutStreamer->emitInt8(0); - OutStreamer->AddComment("function address"); - OutStreamer->emitSymbolValue(FunctionSymbol, getPointerSize()); - OutStreamer->AddComment("number of basic blocks"); - OutStreamer->emitULEB128IntValue(MF.size()); - const MCSymbol *PrevMBBEndSymbol = FunctionSymbol; - // Emit BB Information for each basic block in the function. + std::unordered_map SectionSize; + MCSymbol *BeginMBBSymbol = nullptr; + MCSymbol *PrevMBBEndSymbol = nullptr; for (const MachineBasicBlock &MBB : MF) { - const MCSymbol *MBBSymbol = - MBB.isEntryBlock() ? FunctionSymbol : MBB.getSymbol(); + if (MBB.isBeginSection() || MBB.isEntryBlock()) { + BeginMBBSymbol = + MBB.isEntryBlock() ? getFunctionBegin() : MBB.getSymbol(); + } + SectionSize[BeginMBBSymbol]++; + } + unsigned int i = 0; + for (const MachineBasicBlock &MBB : MF) { + MCSymbol *MBBSymbol = + MBB.isEntryBlock() ? getFunctionBegin() : MBB.getSymbol(); + if (MBB.isBeginSection() || MBB.isEntryBlock()) { + OutStreamer->pushSection(); + OutStreamer->switchSection(BBAddrMapSection); + OutStreamer->AddComment("version"); + OutStreamer->emitInt8(BBAddrMapVersion); + OutStreamer->AddComment("feature"); + OutStreamer->emitInt8(0); + OutStreamer->AddComment("function address"); + OutStreamer->emitSymbolValue(MBBSymbol, getPointerSize()); + OutStreamer->AddComment("number of basic blocks"); + OutStreamer->emitULEB128IntValue(SectionSize[MBBSymbol]); + BeginMBBSymbol = MBBSymbol; + PrevMBBEndSymbol = MBBSymbol; + } // TODO: Remove this check when version 1 is deprecated. if (BBAddrMapVersion > 1) { OutStreamer->AddComment("BB id"); @@ -1408,8 +1417,11 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) { // Emit the Metadata. OutStreamer->emitULEB128IntValue(getBBAddrMapMetadata(MBB)); PrevMBBEndSymbol = MBB.getEndSymbol(); + if (MBB.isEndSection() || i == MF.size() - 1) { + OutStreamer->popSection(); + } + ++i; } - OutStreamer->popSection(); } void AsmPrinter::emitKCFITrapEntry(const MachineFunction &MF, diff --git a/llvm/lib/CodeGen/BasicBlockPathCloning.cpp b/llvm/lib/CodeGen/BasicBlockPathCloning.cpp index 5d5f3c3da4816..92591e493b753 100644 --- a/llvm/lib/CodeGen/BasicBlockPathCloning.cpp +++ b/llvm/lib/CodeGen/BasicBlockPathCloning.cpp @@ -225,7 +225,9 @@ INITIALIZE_PASS_END( false) bool BasicBlockPathCloning::runOnMachineFunction(MachineFunction &MF) { - assert(MF.getTarget().getBBSectionsType() == BasicBlockSection::List && + assert((MF.getTarget().getBBSectionsType() == BasicBlockSection::List || + MF.getTarget().getBBSectionsType() == + BasicBlockSection::ListWithLabels) && "BB Sections list not enabled!"); if (hasInstrProfHashMismatch(MF)) return false; diff --git a/llvm/lib/CodeGen/BasicBlockSections.cpp b/llvm/lib/CodeGen/BasicBlockSections.cpp index 42997d2287d61..7f0e93eb225cf 100644 --- a/llvm/lib/CodeGen/BasicBlockSections.cpp +++ b/llvm/lib/CodeGen/BasicBlockSections.cpp @@ -291,7 +291,8 @@ bool BasicBlockSections::runOnMachineFunction(MachineFunction &MF) { // clusters of basic blocks using basic block ids. Source drift can // invalidate these groupings leading to sub-optimal code generation with // regards to performance. - if (BBSectionsType == BasicBlockSection::List && + if ((BBSectionsType == BasicBlockSection::List || + BBSectionsType == BasicBlockSection::ListWithLabels) && hasInstrProfHashMismatch(MF)) return false; // Renumber blocks before sorting them. This is useful for accessing the @@ -304,7 +305,8 @@ bool BasicBlockSections::runOnMachineFunction(MachineFunction &MF) { } DenseMap FuncClusterInfo; - if (BBSectionsType == BasicBlockSection::List) { + if (BBSectionsType == BasicBlockSection::List || + BBSectionsType == BasicBlockSection::ListWithLabels) { auto [HasProfile, ClusterInfo] = getAnalysis() .getClusterInfoForFunction(MF.getName()); diff --git a/llvm/lib/CodeGen/CommandFlags.cpp b/llvm/lib/CodeGen/CommandFlags.cpp index c6d7827f36dfd..1bfcbb47c4cfb 100644 --- a/llvm/lib/CodeGen/CommandFlags.cpp +++ b/llvm/lib/CodeGen/CommandFlags.cpp @@ -517,13 +517,17 @@ codegen::getBBSectionsMode(llvm::TargetOptions &Options) { return BasicBlockSection::None; else { ErrorOr> MBOrErr = - MemoryBuffer::getFile(getBBSections()); + MemoryBuffer::getFile(getBBSections().substr( + getBBSections().find("listwithlabels=") == std::string::npos ? 0 + : 15)); if (!MBOrErr) { errs() << "Error loading basic block sections function list file: " << MBOrErr.getError().message() << "\n"; } else { Options.BBSectionsFuncListBuf = std::move(*MBOrErr); } + if (getBBSections().find("listwithlabels=") != std::string::npos) + return BasicBlockSection::ListWithLabels; return BasicBlockSection::List; } } diff --git a/llvm/lib/CodeGen/MachineFunction.cpp b/llvm/lib/CodeGen/MachineFunction.cpp index 57af571ed9bfd..8df7af876fadd 100644 --- a/llvm/lib/CodeGen/MachineFunction.cpp +++ b/llvm/lib/CodeGen/MachineFunction.cpp @@ -467,7 +467,8 @@ MachineFunction::CreateMachineBasicBlock(const BasicBlock *BB, // `-basic-block-sections=list` to allow robust mapping of profiles to basic // blocks. if (Target.getBBSectionsType() == BasicBlockSection::Labels || - Target.getBBSectionsType() == BasicBlockSection::List) + Target.getBBSectionsType() == BasicBlockSection::List || + Target.getBBSectionsType() == BasicBlockSection::ListWithLabels) MBB->setBBID(BBID.has_value() ? *BBID : UniqueBBID{NextBBID++, 0}); return MBB; } diff --git a/llvm/lib/CodeGen/TargetPassConfig.cpp b/llvm/lib/CodeGen/TargetPassConfig.cpp index 4003a08a5422d..9f34285f39965 100644 --- a/llvm/lib/CodeGen/TargetPassConfig.cpp +++ b/llvm/lib/CodeGen/TargetPassConfig.cpp @@ -1270,7 +1270,8 @@ void TargetPassConfig::addMachinePasses() { // FIXME: In principle, BasicBlockSection::Labels and splitting can used // together. Update this check once we have addressed any issues. if (TM->getBBSectionsType() != llvm::BasicBlockSection::None) { - if (TM->getBBSectionsType() == llvm::BasicBlockSection::List) { + if (TM->getBBSectionsType() == llvm::BasicBlockSection::List || + TM->getBBSectionsType() == llvm::BasicBlockSection::ListWithLabels) { addPass(llvm::createBasicBlockSectionsProfileReaderPass( TM->getBBSectionsFuncListBuf())); addPass(llvm::createBasicBlockPathCloningPass()); diff --git a/llvm/test/CodeGen/X86/basic-block-sections-cold.ll b/llvm/test/CodeGen/X86/basic-block-sections-cold.ll index 58cec1b658c1e..e498710c1be0f 100644 --- a/llvm/test/CodeGen/X86/basic-block-sections-cold.ll +++ b/llvm/test/CodeGen/X86/basic-block-sections-cold.ll @@ -13,6 +13,7 @@ ; RUN: llc < %s -mtriple=x86_64 -function-sections -basic-block-sections=%t1 -unique-basic-block-section-names | FileCheck %s -check-prefix=LINUX-SECTIONS ; RUN: llc < %s -mtriple=x86_64 -function-sections -basic-block-sections=%t2 -unique-basic-block-section-names | FileCheck %s -check-prefix=LINUX-SECTIONS ; RUN: llc < %s -mtriple=x86_64 -function-sections -basic-block-sections=%t1 -unique-basic-block-section-names -bbsections-cold-text-prefix=".text.unlikely." | FileCheck %s -check-prefix=LINUX-SPLIT +; RUN: llc < %s -mtriple=x86_64 -function-sections -basic-block-sections=listwithlabels=%t1 -unique-basic-block-section-names | FileCheck %s -check-prefix=LINUX-SECTIONS -check-prefix=LABELS define void @_Z3bazb(i1 zeroext %0) nounwind { br i1 %0, label %2, label %4 @@ -49,3 +50,10 @@ declare i32 @_Z3foov() #1 ; LINUX-SPLIT-NEXT: callq _Z3barv ; LINUX-SPLIT: .LBB0_2: ; LINUX-SPLIT: .LBB_END0_2: + +; LABELS: .uleb128 .Lfunc_begin0-.Lfunc_begin0 +; LABELS: .uleb128 .LBB_END0_0-.Lfunc_begin0 +; LABELS: .uleb128 _Z3bazb.cold-_Z3bazb.cold +; LABELS: .uleb128 .LBB_END0_1-_Z3bazb.cold +; LABELS: .uleb128 .LBB0_2-.LBB_END0_1 +; LABELS: .uleb128 .LBB_END0_2-.LBB0_2