diff --git a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h --- a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -174,6 +174,15 @@ MCSection *getSectionForJumpTable(const Function &F, const TargetMachine &TM) const override; + MCSection * + getSectionForMachineBasicBlock(const Function &F, + const MachineBasicBlock &MBB, + const TargetMachine &TM) const override; + + MCSection * + getUniqueSectionForFunction(const Function &F, + const TargetMachine &TM) const override; + /// Emit Obj-C garbage collection and linker options. void emitModuleMetadata(MCStreamer &Streamer, Module &M) const override; 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 @@ -411,7 +411,8 @@ }; sortBasicBlocksAndUpdateBranches(MF, Comparator); - avoidZeroOffsetLandingPad(MF); + if (MF.getTarget().getTargetTriple().isOSBinFormatELF()) + avoidZeroOffsetLandingPad(MF); return true; } diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -1693,6 +1693,59 @@ COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE, UniqueID); } +/// Returns a unique section for the given machine basic block. +MCSection *TargetLoweringObjectFileCOFF::getSectionForMachineBasicBlock( + const Function &F, const MachineBasicBlock &MBB, + const TargetMachine &TM) const { + assert(MBB.isBeginSection() && "Basic block does not start a section!"); + SectionKind Kind = SectionKind::getText(); + unsigned Characteristics = getCOFFSectionFlags(Kind, TM); + // If we have -ffunction-sections then we should emit the global value to a + // uniqued section specifically for it. + if (TM.getFunctionSections() || F.hasComdat()) + Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; + unsigned UniqueID = MCContext::GenericSectionID; + StringRef COMDATSymName; + if (TM.getUniqueBasicBlockSectionNames()) + COMDATSymName = MBB.getSymbol()->getName(); + else { + UniqueID = NextUniqueID++; + COMDATSymName = MBB.getParent()->getName(); + } + + // TODO: construct exception section in the case of section ID of MBB is + // MBBSectionID::ExceptionSectionID and cold section in the case of section + // ID of MBB is MBBSectionID::ColdSectionID + SmallString<128> Name; + Name += getCOFFSectionNameForUniqueGlobal(SectionKind::getText()); + + // Append "$symbol" to the section name *before* IR-level mangling is + // applied when targetting mingw. This is what GCC does, and the ld.bfd + // COFF linker will not properly handle comdats otherwise. + if (getTargetTriple().isWindowsGNUEnvironment()) { + Name += '$'; + Name += COMDATSymName; + } + + return getContext().getCOFFSection( + Name, Characteristics, SectionKind::getText(), COMDATSymName, + COFF::IMAGE_COMDAT_SELECT_NODUPLICATES, UniqueID); +} + +MCSection *TargetLoweringObjectFileCOFF::getUniqueSectionForFunction( + const Function &F, const TargetMachine &TM) const { + SectionKind Kind = SectionKind::getText(); + unsigned Characteristics = getCOFFSectionFlags(Kind, TM); + // If we have -ffunction-sections then we should emit the global value to a + // uniqued section specifically for it. + if (TM.getFunctionSections() || F.hasComdat()) + Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; + return getContext().getCOFFSection( + getCOFFSectionNameForUniqueGlobal(Kind), Characteristics, Kind, + TM.getSymbol(&F)->getName(), COFF::IMAGE_COMDAT_SELECT_NODUPLICATES, + NextUniqueID++); +} + void TargetLoweringObjectFileCOFF::emitModuleMetadata(MCStreamer &Streamer, Module &M) const { emitLinkerDirectives(Streamer, M); diff --git a/llvm/test/MC/COFF/seh-bbs.ll b/llvm/test/MC/COFF/seh-bbs.ll new file mode 100644 --- /dev/null +++ b/llvm/test/MC/COFF/seh-bbs.ll @@ -0,0 +1,337 @@ +; RUN: llc -simplifycfg-require-and-preserve-domtree=1 < %s -mtriple=x86_64-windows-msvc -function-sections -basic-block-sections=all -unique-basic-block-section-names | llvm-mc -triple=x86_64-windows-msvc -filetype=obj - | llvm-readobj -S --sd --sr -u - | FileCheck %s + +; CHECK: Sections [ +; CHECK: Section { +; CHECK: Name: .xdata +; CHECK: RawDataSize: 36 +; CHECK: RelocationCount: 4 +; CHECK: Characteristics [ +; CHECK-NEXT: IMAGE_SCN_ALIGN_4BYTES +; CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA +; CHECK-NEXT: IMAGE_SCN_LNK_COMDAT +; CHECK-NEXT: IMAGE_SCN_MEM_READ +; CHECK-NEXT: ] +; CHECK: Relocations [ +; CHECK-NEXT: 0xC IMAGE_REL_AMD64_ADDR32NB __C_specific_handler +; CHECK-NEXT: 0x14 IMAGE_REL_AMD64_ADDR32NB .text +; CHECK-NEXT: 0x18 IMAGE_REL_AMD64_ADDR32NB .text +; CHECK-NEXT: 0x20 IMAGE_REL_AMD64_ADDR32NB ?TestCPPEX@@YAXH@Z.__part.3 +; CHECK-NEXT: ] +; CHECK: SectionData ( +; CHECK-NEXT: 0000: 190A0345 0A030572 01500000 00000000 +; CHECK-NEXT: 0010: 01000000 01000000 11000000 01000000 +; CHECK-NEXT: 0020: 00000000 +; CHECK-NEXT: ) +; CHECK-NEXT: } +; CHECK: Section { +; CHECK: Name: .pdata +; CHECK: RawDataSize: 12 +; CHECK: RelocationCount: 3 +; CHECK: Characteristics [ (0x40301040) +; CHECK-NEXT: IMAGE_SCN_ALIGN_4BYTES (0x300000) +; CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA (0x40) +; CHECK-NEXT: IMAGE_SCN_LNK_COMDAT (0x1000) +; CHECK-NEXT: IMAGE_SCN_MEM_READ (0x40000000) +; CHECK-NEXT: ] +; CHECK: Relocations [ +; CHECK-NEXT: 0x0 IMAGE_REL_AMD64_ADDR32NB ?TestCPPEX@@YAXH@Z +; CHECK-NEXT: 0x4 IMAGE_REL_AMD64_ADDR32NB ?TestCPPEX@@YAXH@Z +; CHECK-NEXT: 0x8 IMAGE_REL_AMD64_ADDR32NB .xdata +; CHECK-NEXT: ] +; CHECK: SectionData ( +; CHECK-NEXT: 0000: 00000000 1C000000 00000000 +; CHECK-NEXT: ) +; CHECK-NEXT: } +; CHECK: ] +; CHECK: UnwindInformation [ +; CHECK: RuntimeFunction { +; CHECK-NEXT: StartAddress: ?TestCPPEX@@YAXH@Z (0x0) +; CHECK-NEXT: EndAddress: ?TestCPPEX@@YAXH@Z +0x1C (0x4) +; CHECK-NEXT: UnwindInfoAddress: .xdata (0x8) +; CHECK-NEXT: UnwindInfo { +; CHECK-NEXT: Version: 1 +; CHECK-NEXT: Flags [ (0x3) +; CHECK-NEXT: ExceptionHandler (0x1) +; CHECK-NEXT: TerminateHandler (0x2) +; CHECK-NEXT: ] +; CHECK-NEXT: PrologSize: 10 +; CHECK-NEXT: FrameRegister: RBP (0x5) +; CHECK-NEXT: FrameOffset: 0x4 +; CHECK-NEXT: UnwindCodeCount: 3 +; CHECK-NEXT: UnwindCodes [ +; CHECK-NEXT: 0x0A: SET_FPREG reg=RBP, offset=0x40 +; CHECK-NEXT: 0x05: ALLOC_SMALL size=64 +; CHECK-NEXT: 0x01: PUSH_NONVOL reg=RBP +; CHECK-NEXT: ] +; CHECK-NEXT: Handler: __C_specific_handler (0xC) +; CHECK-NEXT: } +; CHECK-NEXT: } +; CHECK: ] + +; Generated with this C++ source: +; #include +; #include +; #include +; __declspec(noinline) void TestCPPEX(int index) +; { +; __try +; { +; if (index > 10) { +; throw std::exception(""); +; } +; } +; __except (EXCEPTION_EXECUTE_HANDLER) +; { +; } +; } + +; ModuleID = 'wineh.cpp' +source_filename = "wineh.cpp" +target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-windows-msvc19.0.24245" + +%rtti.TypeDescriptor19 = type { i8**, i8*, [20 x i8] } +%eh.CatchableType = type { i32, i32, i32, i32, i32, i32, i32 } +%eh.CatchableTypeArray.1 = type { i32, [1 x i32] } +%eh.ThrowInfo = type { i32, i32, i32, i32 } +%rtti.CompleteObjectLocator = type { i32, i32, i32, i32, i32, i32 } +%rtti.ClassHierarchyDescriptor = type { i32, i32, i32, i32 } +%rtti.BaseClassDescriptor = type { i32, i32, i32, i32, i32, i32, i32 } +%"class.std::exception" = type { i32 (...)**, %struct.__std_exception_data } +%struct.__std_exception_data = type { i8*, i8 } + +$"??0exception@std@@QEAA@QEBD@Z" = comdat any + +$"??0exception@std@@QEAA@AEBV01@@Z" = comdat any + +$"??1exception@std@@UEAA@XZ" = comdat any + +$"??_Gexception@std@@UEAAPEAXI@Z" = comdat any + +$"?what@exception@std@@UEBAPEBDXZ" = comdat any + +$"??_C@_00CNPNBAHC@?$AA@" = comdat any + +$"??_R0?AVexception@std@@@8" = comdat any + +$"_CT??_R0?AVexception@std@@@824" = comdat any + +$"_CTA1?AVexception@std@@" = comdat any + +$"_TI1?AVexception@std@@" = comdat any + +$"??_7exception@std@@6B@" = comdat largest + +$"??_R4exception@std@@6B@" = comdat any + +$"??_R3exception@std@@8" = comdat any + +$"??_R2exception@std@@8" = comdat any + +$"??_R1A@?0A@EA@exception@std@@8" = comdat any + +$"??_C@_0BC@EOODALEL@Unknown?5exception?$AA@" = comdat any + +@"??_C@_00CNPNBAHC@?$AA@" = linkonce_odr dso_local unnamed_addr constant [1 x i8] zeroinitializer, comdat, align 1 +@"??_7type_info@@6B@" = external constant i8* +@"??_R0?AVexception@std@@@8" = linkonce_odr global %rtti.TypeDescriptor19 { i8** @"??_7type_info@@6B@", i8* null, [20 x i8] c".?AVexception@std@@\00" }, comdat +@__ImageBase = external dso_local constant i8 +@"_CT??_R0?AVexception@std@@@824" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor19* @"??_R0?AVexception@std@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 -1, i32 0, i32 24, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%"class.std::exception"* (%"class.std::exception"*, %"class.std::exception"*)* @"??0exception@std@@QEAA@AEBV01@@Z" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, section ".xdata", comdat +@"_CTA1?AVexception@std@@" = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.1 { i32 1, [1 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%eh.CatchableType* @"_CT??_R0?AVexception@std@@@824" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32)] }, section ".xdata", comdat +@"_TI1?AVexception@std@@" = linkonce_odr unnamed_addr constant %eh.ThrowInfo { i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (void (%"class.std::exception"*)* @"??1exception@std@@UEAA@XZ" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%eh.CatchableTypeArray.1* @"_CTA1?AVexception@std@@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, section ".xdata", comdat +@0 = private unnamed_addr constant { [3 x i8*] } { [3 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"??_R4exception@std@@6B@" to i8*), i8* bitcast (i8* (%"class.std::exception"*, i32)* @"??_Gexception@std@@UEAAPEAXI@Z" to i8*), i8* bitcast (i8* (%"class.std::exception"*)* @"?what@exception@std@@UEBAPEBDXZ" to i8*)] }, comdat($"??_7exception@std@@6B@") +@"??_R4exception@std@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor19* @"??_R0?AVexception@std@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3exception@std@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"??_R4exception@std@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +@"??_R3exception@std@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([2 x i32]* @"??_R2exception@std@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +@"??_R2exception@std@@8" = linkonce_odr constant [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@exception@std@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0], comdat +@"??_R1A@?0A@EA@exception@std@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor19* @"??_R0?AVexception@std@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3exception@std@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +@"??_C@_0BC@EOODALEL@Unknown?5exception?$AA@" = linkonce_odr dso_local unnamed_addr constant [18 x i8] c"Unknown exception\00", comdat, align 1 + +@"??_7exception@std@@6B@" = unnamed_addr alias i8*, getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @0, i32 0, i32 0, i32 1) + +; Function Attrs: noinline optnone uwtable mustprogress +define dso_local void @"?TestCPPEX@@YAXH@Z"(i32 %0) #0 personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) { + %2 = alloca i32, align 4 + %3 = alloca i32, align 4 + %4 = alloca %"class.std::exception", align 8 + store i32 %0, i32* %2, align 4 + %5 = load i32, i32* %2, align 4 + %6 = icmp sgt i32 %5, 10 + br i1 %6, label %7, label %18 + +7: ; preds = %1 + %8 = invoke %"class.std::exception"* @"??0exception@std@@QEAA@QEBD@Z"(%"class.std::exception"* nonnull dereferenceable(24) %4, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @"??_C@_00CNPNBAHC@?$AA@", i64 0, i64 0)) #7 + to label %9 unwind label %11 + +9: ; preds = %7 + %10 = bitcast %"class.std::exception"* %4 to i8* + invoke void @_CxxThrowException(i8* %10, %eh.ThrowInfo* @"_TI1?AVexception@std@@") #8 + to label %19 unwind label %11 + +11: ; preds = %9, %7 + %12 = catchswitch within none [label %13] unwind to caller + +13: ; preds = %11 + %14 = catchpad within %12 [i8* null] + catchret from %14 to label %15 + +15: ; preds = %13 + %16 = call i32 @llvm.eh.exceptioncode(token %14) + store i32 %16, i32* %3, align 4 + br label %17 + +17: ; preds = %15, %18 + ret void + +18: ; preds = %1 + br label %17 + +19: ; preds = %9 + unreachable +} + +; Function Attrs: noinline nounwind optnone uwtable +define linkonce_odr dso_local %"class.std::exception"* @"??0exception@std@@QEAA@QEBD@Z"(%"class.std::exception"* nonnull returned dereferenceable(24) %0, i8* %1) unnamed_addr #1 comdat align 2 { + %3 = alloca i8*, align 8 + %4 = alloca %"class.std::exception"*, align 8 + %5 = alloca %struct.__std_exception_data, align 8 + store i8* %1, i8** %3, align 8 + store %"class.std::exception"* %0, %"class.std::exception"** %4, align 8 + %6 = load %"class.std::exception"*, %"class.std::exception"** %4, align 8 + %7 = bitcast %"class.std::exception"* %6 to i32 (...)*** + store i32 (...)** bitcast (i8** @"??_7exception@std@@6B@" to i32 (...)**), i32 (...)*** %7, align 8 + %8 = getelementptr inbounds %"class.std::exception", %"class.std::exception"* %6, i32 0, i32 1 + %9 = bitcast %struct.__std_exception_data* %8 to i8* + call void @llvm.memset.p0i8.i64(i8* align 8 %9, i8 0, i64 16, i1 false) + %10 = getelementptr inbounds %struct.__std_exception_data, %struct.__std_exception_data* %5, i32 0, i32 0 + %11 = load i8*, i8** %3, align 8 + store i8* %11, i8** %10, align 8 + %12 = getelementptr inbounds %struct.__std_exception_data, %struct.__std_exception_data* %5, i32 0, i32 1 + store i8 1, i8* %12, align 8 + %13 = getelementptr inbounds %"class.std::exception", %"class.std::exception"* %6, i32 0, i32 1 + call void @__std_exception_copy(%struct.__std_exception_data* %5, %struct.__std_exception_data* %13) + ret %"class.std::exception"* %6 +} + +declare dso_local i32 @__C_specific_handler(...) + +; Function Attrs: noinline nounwind optnone uwtable +define linkonce_odr dso_local %"class.std::exception"* @"??0exception@std@@QEAA@AEBV01@@Z"(%"class.std::exception"* nonnull returned dereferenceable(24) %0, %"class.std::exception"* nonnull align 8 dereferenceable(24) %1) unnamed_addr #1 comdat align 2 { + %3 = alloca %"class.std::exception"*, align 8 + %4 = alloca %"class.std::exception"*, align 8 + store %"class.std::exception"* %1, %"class.std::exception"** %3, align 8 + store %"class.std::exception"* %0, %"class.std::exception"** %4, align 8 + %5 = load %"class.std::exception"*, %"class.std::exception"** %4, align 8 + %6 = bitcast %"class.std::exception"* %5 to i32 (...)*** + store i32 (...)** bitcast (i8** @"??_7exception@std@@6B@" to i32 (...)**), i32 (...)*** %6, align 8 + %7 = getelementptr inbounds %"class.std::exception", %"class.std::exception"* %5, i32 0, i32 1 + %8 = bitcast %struct.__std_exception_data* %7 to i8* + call void @llvm.memset.p0i8.i64(i8* align 8 %8, i8 0, i64 16, i1 false) + %9 = getelementptr inbounds %"class.std::exception", %"class.std::exception"* %5, i32 0, i32 1 + %10 = load %"class.std::exception"*, %"class.std::exception"** %3, align 8 + %11 = getelementptr inbounds %"class.std::exception", %"class.std::exception"* %10, i32 0, i32 1 + call void @__std_exception_copy(%struct.__std_exception_data* %11, %struct.__std_exception_data* %9) + ret %"class.std::exception"* %5 +} + +; Function Attrs: noinline nounwind optnone uwtable +define linkonce_odr dso_local void @"??1exception@std@@UEAA@XZ"(%"class.std::exception"* nonnull dereferenceable(24) %0) unnamed_addr #1 comdat align 2 { + %2 = alloca %"class.std::exception"*, align 8 + store %"class.std::exception"* %0, %"class.std::exception"** %2, align 8 + %3 = load %"class.std::exception"*, %"class.std::exception"** %2, align 8 + %4 = bitcast %"class.std::exception"* %3 to i32 (...)*** + store i32 (...)** bitcast (i8** @"??_7exception@std@@6B@" to i32 (...)**), i32 (...)*** %4, align 8 + %5 = getelementptr inbounds %"class.std::exception", %"class.std::exception"* %3, i32 0, i32 1 + call void @__std_exception_destroy(%struct.__std_exception_data* %5) + ret void +} + +declare dso_local void @_CxxThrowException(i8*, %eh.ThrowInfo*) + +; Function Attrs: nounwind readnone +declare i32 @llvm.eh.exceptioncode(token) #2 + +; Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly +declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i1 immarg) #3 + +declare dso_local void @__std_exception_copy(%struct.__std_exception_data*, %struct.__std_exception_data*) #4 + +; Function Attrs: noinline nounwind optnone uwtable +define linkonce_odr dso_local i8* @"??_Gexception@std@@UEAAPEAXI@Z"(%"class.std::exception"* nonnull dereferenceable(24) %0, i32 %1) unnamed_addr #1 comdat align 2 { + %3 = alloca i8*, align 8 + %4 = alloca i32, align 4 + %5 = alloca %"class.std::exception"*, align 8 + store i32 %1, i32* %4, align 4 + store %"class.std::exception"* %0, %"class.std::exception"** %5, align 8 + %6 = load %"class.std::exception"*, %"class.std::exception"** %5, align 8 + %7 = bitcast %"class.std::exception"* %6 to i8* + store i8* %7, i8** %3, align 8 + %8 = load i32, i32* %4, align 4 + call void @"??1exception@std@@UEAA@XZ"(%"class.std::exception"* nonnull dereferenceable(24) %6) #9 + %9 = icmp eq i32 %8, 0 + br i1 %9, label %12, label %10 + +10: ; preds = %2 + %11 = bitcast %"class.std::exception"* %6 to i8* + call void @"??3@YAXPEAX@Z"(i8* %11) #10 + br label %12 + +12: ; preds = %10, %2 + %13 = load i8*, i8** %3, align 8 + ret i8* %13 +} + +; Function Attrs: noinline nounwind optnone uwtable mustprogress +define linkonce_odr dso_local i8* @"?what@exception@std@@UEBAPEBDXZ"(%"class.std::exception"* nonnull dereferenceable(24) %0) unnamed_addr #5 comdat align 2 { + %2 = alloca %"class.std::exception"*, align 8 + store %"class.std::exception"* %0, %"class.std::exception"** %2, align 8 + %3 = load %"class.std::exception"*, %"class.std::exception"** %2, align 8 + %4 = getelementptr inbounds %"class.std::exception", %"class.std::exception"* %3, i32 0, i32 1 + %5 = getelementptr inbounds %struct.__std_exception_data, %struct.__std_exception_data* %4, i32 0, i32 0 + %6 = load i8*, i8** %5, align 8 + %7 = icmp ne i8* %6, null + br i1 %7, label %8, label %12 + +8: ; preds = %1 + %9 = getelementptr inbounds %"class.std::exception", %"class.std::exception"* %3, i32 0, i32 1 + %10 = getelementptr inbounds %struct.__std_exception_data, %struct.__std_exception_data* %9, i32 0, i32 0 + %11 = load i8*, i8** %10, align 8 + br label %13 + +12: ; preds = %1 + br label %13 + +13: ; preds = %12, %8 + %14 = phi i8* [ %11, %8 ], [ getelementptr inbounds ([18 x i8], [18 x i8]* @"??_C@_0BC@EOODALEL@Unknown?5exception?$AA@", i64 0, i64 0), %12 ] + ret i8* %14 +} + +; Function Attrs: nobuiltin nounwind +declare dso_local void @"??3@YAXPEAX@Z"(i8*) #6 + +declare dso_local void @__std_exception_destroy(%struct.__std_exception_data*) #4 + +attributes #0 = { noinline optnone uwtable mustprogress "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { noinline nounwind optnone uwtable "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind readnone } +attributes #3 = { argmemonly nofree nosync nounwind willreturn writeonly } +attributes #4 = { "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #5 = { noinline nounwind optnone uwtable mustprogress "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #6 = { nobuiltin nounwind "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #7 = { noinline nounwind } +attributes #8 = { noreturn } +attributes #9 = { nounwind } +attributes #10 = { builtin nounwind } + +!llvm.linker.options = !{!0, !1, !1, !2, !3, !4, !5} +!llvm.module.flags = !{!6, !7} +!llvm.ident = !{!8} + +!0 = !{!"/FAILIFMISMATCH:\22_CRT_STDIO_ISO_WIDE_SPECIFIERS=0\22"} +!1 = !{!"/DEFAULTLIB:uuid.lib"} +!2 = !{!"/FAILIFMISMATCH:\22_MSC_VER=1900\22"} +!3 = !{!"/FAILIFMISMATCH:\22_ITERATOR_DEBUG_LEVEL=0\22"} +!4 = !{!"/FAILIFMISMATCH:\22RuntimeLibrary=MT_StaticRelease\22"} +!5 = !{!"/DEFAULTLIB:libcpmt.lib"} +!6 = !{i32 1, !"wchar_size", i32 2} +!7 = !{i32 7, !"PIC Level", i32 2} +!8 = !{!"clang version 12.0.0 (https://github.com/llvm/llvm-project.git 5207f19d103dc3e0ec974fa64d2c031d84d497a8)"}