[llvm-branch-commits] [llvm] a65d8c5 - [XCOFF][AIX] Generate LSDA data and compact unwind section on AIX
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Dec 2 10:47:44 PST 2020
Author: jasonliu
Date: 2020-12-02T18:42:44Z
New Revision: a65d8c5d720db8c646adb0ad9dac54da5d5fa230
URL: https://github.com/llvm/llvm-project/commit/a65d8c5d720db8c646adb0ad9dac54da5d5fa230
DIFF: https://github.com/llvm/llvm-project/commit/a65d8c5d720db8c646adb0ad9dac54da5d5fa230.diff
LOG: [XCOFF][AIX] Generate LSDA data and compact unwind section on AIX
Summary:
AIX uses the existing EH infrastructure in clang and llvm.
The major differences would be
1. AIX do not have CFI instructions.
2. AIX uses a new personality routine, named __xlcxx_personality_v1.
It doesn't use the GCC personality rountine, because the
interoperability is not there yet on AIX.
3. AIX do not use eh_frame sections. Instead, it would use a eh_info
section (compat unwind section) to store the information about
personality routine and LSDA data address.
Reviewed By: daltenty, hubert.reinterpretcast
Differential Revision: https://reviews.llvm.org/D91455
Added:
llvm/lib/CodeGen/AsmPrinter/AIXException.cpp
llvm/test/CodeGen/PowerPC/aix-exception.ll
Modified:
clang/lib/CodeGen/CGCleanup.h
clang/lib/CodeGen/CGException.cpp
clang/test/CodeGenCXX/personality.cpp
llvm/include/llvm/Analysis/EHPersonalities.h
llvm/include/llvm/CodeGen/AsmPrinter.h
llvm/include/llvm/MC/MCTargetOptions.h
llvm/lib/Analysis/EHPersonalities.cpp
llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
llvm/lib/CodeGen/AsmPrinter/CMakeLists.txt
llvm/lib/CodeGen/AsmPrinter/DwarfException.h
llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp
llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
llvm/lib/CodeGen/TargetPassConfig.cpp
llvm/lib/MC/MCAsmInfoXCOFF.cpp
llvm/lib/MC/MCObjectFileInfo.cpp
llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
Removed:
################################################################################
diff --git a/clang/lib/CodeGen/CGCleanup.h b/clang/lib/CodeGen/CGCleanup.h
index ef4f6b9ec133..1b54c0018d27 100644
--- a/clang/lib/CodeGen/CGCleanup.h
+++ b/clang/lib/CodeGen/CGCleanup.h
@@ -612,6 +612,7 @@ struct EHPersonality {
static const EHPersonality MSVC_C_specific_handler;
static const EHPersonality MSVC_CxxFrameHandler3;
static const EHPersonality GNU_Wasm_CPlusPlus;
+ static const EHPersonality XL_CPlusPlus;
/// Does this personality use landingpads or the family of pad instructions
/// designed to form funclets?
diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp
index bdf70252b5ad..85604cf5e611 100644
--- a/clang/lib/CodeGen/CGException.cpp
+++ b/clang/lib/CodeGen/CGException.cpp
@@ -113,6 +113,8 @@ const EHPersonality
EHPersonality::MSVC_CxxFrameHandler3 = { "__CxxFrameHandler3", nullptr };
const EHPersonality
EHPersonality::GNU_Wasm_CPlusPlus = { "__gxx_wasm_personality_v0", nullptr };
+const EHPersonality EHPersonality::XL_CPlusPlus = {"__xlcxx_personality_v1",
+ nullptr};
static const EHPersonality &getCPersonality(const TargetInfo &Target,
const LangOptions &L) {
@@ -161,6 +163,8 @@ static const EHPersonality &getCXXPersonality(const TargetInfo &Target,
const llvm::Triple &T = Target.getTriple();
if (T.isWindowsMSVCEnvironment())
return EHPersonality::MSVC_CxxFrameHandler3;
+ if (T.isOSAIX())
+ return EHPersonality::XL_CPlusPlus;
if (L.SjLjExceptions)
return EHPersonality::GNU_CPlusPlus_SJLJ;
if (L.DWARFExceptions)
diff --git a/clang/test/CodeGenCXX/personality.cpp b/clang/test/CodeGenCXX/personality.cpp
index ce4bad370d91..1bdc7736c4da 100644
--- a/clang/test/CodeGenCXX/personality.cpp
+++ b/clang/test/CodeGenCXX/personality.cpp
@@ -12,6 +12,9 @@
// RUN: %clang_cc1 -triple i686-unknown-windows-gnu -fexceptions -fseh-exceptions -fcxx-exceptions -S -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-GNU-SEH
// RUN: %clang_cc1 -triple i686-unknown-windows-gnu -fexceptions -fsjlj-exceptions -fcxx-exceptions -S -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-GNU-SJLJ
+// RUN: %clang_cc1 -triple powerpc-unknown-aix-xcoff -fexceptions -fcxx-exceptions -S -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-AIX
+// RUN: %clang_cc1 -triple powerpc64-unknown-aix-xcoff -fexceptions -fcxx-exceptions -S -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-AIX
+
extern void g();
// CHECK-GNU: personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
@@ -21,6 +24,8 @@ extern void g();
// CHECK-WIN: personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
+// CHECK-AIX: personality i8* bitcast (i32 (...)* @__xlcxx_personality_v1 to i8*)
+
void f() {
try {
g();
diff --git a/llvm/include/llvm/Analysis/EHPersonalities.h b/llvm/include/llvm/Analysis/EHPersonalities.h
index 1905e0543fee..eaada6627494 100644
--- a/llvm/include/llvm/Analysis/EHPersonalities.h
+++ b/llvm/include/llvm/Analysis/EHPersonalities.h
@@ -32,7 +32,8 @@ enum class EHPersonality {
MSVC_CXX,
CoreCLR,
Rust,
- Wasm_CXX
+ Wasm_CXX,
+ XL_CXX
};
/// See if the given exception handling personality function is one
diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h
index 5223f6ec9898..7fac3613251b 100644
--- a/llvm/include/llvm/CodeGen/AsmPrinter.h
+++ b/llvm/include/llvm/CodeGen/AsmPrinter.h
@@ -603,7 +603,7 @@ class AsmPrinter : public MachineFunctionPass {
unsigned GetSizeOfEncodedValue(unsigned Encoding) const;
/// Emit reference to a ttype global with a specified encoding.
- void emitTTypeReference(const GlobalValue *GV, unsigned Encoding) const;
+ virtual void emitTTypeReference(const GlobalValue *GV, unsigned Encoding);
/// Emit a reference to a symbol for use in dwarf. Different object formats
/// represent this in
diff erent ways. Some use a relocation others encode
diff --git a/llvm/include/llvm/MC/MCTargetOptions.h b/llvm/include/llvm/MC/MCTargetOptions.h
index 4b786751dbd1..d29a74905ebf 100644
--- a/llvm/include/llvm/MC/MCTargetOptions.h
+++ b/llvm/include/llvm/MC/MCTargetOptions.h
@@ -22,6 +22,7 @@ enum class ExceptionHandling {
ARM, ///< ARM EHABI
WinEH, ///< Windows Exception Handling
Wasm, ///< WebAssembly Exception Handling
+ AIX, ///< AIX Exception Handling
};
enum class DebugCompressionType {
diff --git a/llvm/lib/Analysis/EHPersonalities.cpp b/llvm/lib/Analysis/EHPersonalities.cpp
index 7fcfd03fa99f..a982f266b2d6 100644
--- a/llvm/lib/Analysis/EHPersonalities.cpp
+++ b/llvm/lib/Analysis/EHPersonalities.cpp
@@ -39,6 +39,7 @@ EHPersonality llvm::classifyEHPersonality(const Value *Pers) {
.Case("ProcessCLRException", EHPersonality::CoreCLR)
.Case("rust_eh_personality", EHPersonality::Rust)
.Case("__gxx_wasm_personality_v0", EHPersonality::Wasm_CXX)
+ .Case("__xlcxx_personality_v1", EHPersonality::XL_CXX)
.Default(EHPersonality::Unknown);
}
@@ -57,6 +58,8 @@ StringRef llvm::getEHPersonalityName(EHPersonality Pers) {
case EHPersonality::CoreCLR: return "ProcessCLRException";
case EHPersonality::Rust: return "rust_eh_personality";
case EHPersonality::Wasm_CXX: return "__gxx_wasm_personality_v0";
+ case EHPersonality::XL_CXX:
+ return "__xlcxx_personality_v1";
case EHPersonality::Unknown: llvm_unreachable("Unknown EHPersonality!");
}
diff --git a/llvm/lib/CodeGen/AsmPrinter/AIXException.cpp b/llvm/lib/CodeGen/AsmPrinter/AIXException.cpp
new file mode 100644
index 000000000000..21615d47f634
--- /dev/null
+++ b/llvm/lib/CodeGen/AsmPrinter/AIXException.cpp
@@ -0,0 +1,82 @@
+//===-- CodeGen/AsmPrinter/AIXException.cpp - AIX Exception Impl ----------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains support for writing AIX exception info into asm files.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DwarfException.h"
+#include "llvm/CodeGen/AsmPrinter.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/MC/MCSectionXCOFF.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/Target/TargetMachine.h"
+
+namespace llvm {
+
+AIXException::AIXException(AsmPrinter *A) : DwarfCFIExceptionBase(A) {}
+
+void AIXException::emitExceptionInfoTable(const MCSymbol *LSDA,
+ const MCSymbol *PerSym) {
+ // Generate EH Info Table.
+ // The EH Info Table, aka, 'compat unwind section' on AIX, have the following
+ // format: struct eh_info_t {
+ // unsigned version; /* EH info verion 0 */
+ // #if defined(__64BIT__)
+ // char _pad[4]; /* padding */
+ // #endif
+ // unsigned long lsda; /* Pointer to LSDA */
+ // unsigned long personality; /* Pointer to the personality routine */
+ // }
+
+ Asm->OutStreamer->SwitchSection(
+ Asm->getObjFileLowering().getCompactUnwindSection());
+ MCSymbol *EHInfoLabel = MMI->getContext().getOrCreateSymbol(
+ "__ehinfo." + Twine(Asm->getFunctionNumber()));
+ Asm->OutStreamer->emitLabel(EHInfoLabel);
+
+ // Version number.
+ Asm->emitInt32(0);
+
+ const DataLayout &DL = MMI->getModule()->getDataLayout();
+ const unsigned PointerSize = DL.getPointerSize();
+
+ // Add necessary paddings in 64 bit mode.
+ Asm->OutStreamer->emitValueToAlignment(PointerSize);
+
+ // LSDA location.
+ Asm->OutStreamer->emitValue(MCSymbolRefExpr::create(LSDA, Asm->OutContext),
+ PointerSize);
+
+ // Personality routine.
+ Asm->OutStreamer->emitValue(MCSymbolRefExpr::create(PerSym, Asm->OutContext),
+ PointerSize);
+}
+
+void AIXException::endFunction(const MachineFunction *MF) {
+ const Function &F = MF->getFunction();
+ bool HasLandingPads = !MF->getLandingPads().empty();
+ const Function *Per = nullptr;
+ if (F.hasPersonalityFn())
+ Per = dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts());
+ bool EmitEHBlock =
+ HasLandingPads || (F.hasPersonalityFn() &&
+ !isNoOpWithoutInvoke(classifyEHPersonality(Per)) &&
+ F.needsUnwindTableEntry());
+
+ if (!EmitEHBlock)
+ return;
+
+ const MCSymbol *LSDALabel = emitExceptionTable();
+ const MCSymbol *PerSym = Asm->TM.getSymbol(Per);
+
+ emitExceptionInfoTable(LSDALabel, PerSym);
+}
+
+} // End of namespace llvm
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 12090fc370c9..3e3aabf81494 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -380,6 +380,9 @@ bool AsmPrinter::doInitialization(Module &M) {
case ExceptionHandling::Wasm:
ES = new WasmException(this);
break;
+ case ExceptionHandling::AIX:
+ ES = new AIXException(this);
+ break;
}
if (ES)
Handlers.emplace_back(std::unique_ptr<EHStreamer>(ES), EHTimerName,
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
index 594b41bcea53..c6e43445e7d0 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
@@ -98,6 +98,12 @@ static const char *DecodeDWARFEncoding(unsigned Encoding) {
case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8
:
return "indirect pcrel sdata8";
+ case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_datarel |
+ dwarf::DW_EH_PE_sdata4:
+ return "indirect datarel sdata4";
+ case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_datarel |
+ dwarf::DW_EH_PE_sdata8:
+ return "indirect datarel sdata8";
}
return "<unknown encoding>";
@@ -138,8 +144,7 @@ unsigned AsmPrinter::GetSizeOfEncodedValue(unsigned Encoding) const {
}
}
-void AsmPrinter::emitTTypeReference(const GlobalValue *GV,
- unsigned Encoding) const {
+void AsmPrinter::emitTTypeReference(const GlobalValue *GV, unsigned Encoding) {
if (GV) {
const TargetLoweringObjectFile &TLOF = getObjFileLowering();
diff --git a/llvm/lib/CodeGen/AsmPrinter/CMakeLists.txt b/llvm/lib/CodeGen/AsmPrinter/CMakeLists.txt
index a79b846f4fc2..3dbad402abe5 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CMakeLists.txt
+++ b/llvm/lib/CodeGen/AsmPrinter/CMakeLists.txt
@@ -1,6 +1,7 @@
add_llvm_component_library(LLVMAsmPrinter
AccelTable.cpp
AddressPool.cpp
+ AIXException.cpp
ARMException.cpp
AsmPrinter.cpp
AsmPrinterDwarf.cpp
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfException.h b/llvm/lib/CodeGen/AsmPrinter/DwarfException.h
index c2956380438f..b19b4365383f 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfException.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfException.h
@@ -92,6 +92,20 @@ class LLVM_LIBRARY_VISIBILITY ARMException : public DwarfCFIExceptionBase {
/// Gather and emit post-function exception information.
void endFunction(const MachineFunction *) override;
};
+
+class LLVM_LIBRARY_VISIBILITY AIXException : public DwarfCFIExceptionBase {
+ /// This is AIX's compat unwind section, which unwinder would use
+ /// to find the location of LSDA area and personality rountine.
+ void emitExceptionInfoTable(const MCSymbol *LSDA, const MCSymbol *PerSym);
+
+public:
+ AIXException(AsmPrinter *A);
+
+ void endModule() override {}
+ void beginFunction(const MachineFunction *MF) override {}
+
+ void endFunction(const MachineFunction *MF) override;
+};
} // End of namespace llvm
#endif
diff --git a/llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp b/llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp
index a9eeb8f7c61a..b6fc83285a20 100644
--- a/llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp
@@ -288,11 +288,13 @@ void EHStreamer::computeCallSiteTable(
assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] &&
"Inconsistent landing pad map!");
- // For Dwarf exception handling (SjLj handling doesn't use this). If some
- // instruction between the previous try-range and this one may throw,
- // create a call-site entry with no landing pad for the region between the
- // try-ranges.
- if (SawPotentiallyThrowing && Asm->MAI->usesCFIForEH()) {
+ // For Dwarf and AIX exception handling (SjLj handling doesn't use this).
+ // If some instruction between the previous try-range and this one may
+ // throw, create a call-site entry with no landing pad for the region
+ // between the try-ranges.
+ if (SawPotentiallyThrowing &&
+ (Asm->MAI->usesCFIForEH() ||
+ Asm->MAI->getExceptionHandlingType() == ExceptionHandling::AIX)) {
CallSites.push_back({LastLabel, BeginLabel, nullptr, 0});
PreviousIsInvoke = false;
}
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index a6c5a26bcd6b..4c8caa0497e4 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -2272,9 +2272,13 @@ MCSection *TargetLoweringObjectFileXCOFF::getSectionForConstant(
void TargetLoweringObjectFileXCOFF::Initialize(MCContext &Ctx,
const TargetMachine &TgtM) {
TargetLoweringObjectFile::Initialize(Ctx, TgtM);
- TTypeEncoding = 0;
+ TTypeEncoding =
+ dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_datarel |
+ (TgtM.getTargetTriple().isArch32Bit() ? dwarf::DW_EH_PE_sdata4
+ : dwarf::DW_EH_PE_sdata8);
PersonalityEncoding = 0;
LSDAEncoding = 0;
+ CallSiteEncoding = dwarf::DW_EH_PE_udata4;
}
MCSection *TargetLoweringObjectFileXCOFF::getStaticCtorSection(
diff --git a/llvm/lib/CodeGen/TargetPassConfig.cpp b/llvm/lib/CodeGen/TargetPassConfig.cpp
index 3a1a82fadaa5..b877954ca270 100644
--- a/llvm/lib/CodeGen/TargetPassConfig.cpp
+++ b/llvm/lib/CodeGen/TargetPassConfig.cpp
@@ -735,6 +735,7 @@ void TargetPassConfig::addPassesToHandleExceptions() {
LLVM_FALLTHROUGH;
case ExceptionHandling::DwarfCFI:
case ExceptionHandling::ARM:
+ case ExceptionHandling::AIX:
addPass(createDwarfEHPass(getOptLevel()));
break;
case ExceptionHandling::WinEH:
diff --git a/llvm/lib/MC/MCAsmInfoXCOFF.cpp b/llvm/lib/MC/MCAsmInfoXCOFF.cpp
index 04982af4af31..eb46deedcd11 100644
--- a/llvm/lib/MC/MCAsmInfoXCOFF.cpp
+++ b/llvm/lib/MC/MCAsmInfoXCOFF.cpp
@@ -37,6 +37,8 @@ MCAsmInfoXCOFF::MCAsmInfoXCOFF() {
HasDotTypeDotSizeDirective = false;
UseIntegratedAssembler = false;
NeedsFunctionDescriptors = true;
+
+ ExceptionsType = ExceptionHandling::AIX;
}
bool MCAsmInfoXCOFF::isAcceptableChar(char C) const {
diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp
index fbc7cf1efcdb..a67e4b33a33b 100644
--- a/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -883,6 +883,14 @@ void MCObjectFileInfo::initXCOFFMCObjectFileInfo(const Triple &T) {
// The TOC-base always has 0 size, but 4 byte alignment.
TOCBaseSection->setAlignment(Align(4));
+ LSDASection = Ctx->getXCOFFSection(".gcc_except_table",
+ XCOFF::StorageMappingClass::XMC_RO,
+ XCOFF::XTY_SD, SectionKind::getReadOnly());
+
+ CompactUnwindSection =
+ Ctx->getXCOFFSection(".eh_info_table", XCOFF::StorageMappingClass::XMC_RW,
+ XCOFF::XTY_SD, SectionKind::getData());
+
// DWARF sections for XCOFF are not csects. They are special STYP_DWARF
// sections, and the individual DWARF sections are distinguished by their
// section subtype.
diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
index f75182ca5319..748a66285857 100644
--- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -193,6 +193,8 @@ class PPCAIXAsmPrinter : public PPCAsmPrinter {
void emitInstruction(const MachineInstr *MI) override;
bool doFinalization(Module &M) override;
+
+ void emitTTypeReference(const GlobalValue *GV, unsigned Encoding) override;
};
} // end anonymous namespace
@@ -2056,6 +2058,23 @@ void PPCAIXAsmPrinter::emitXXStructorList(const DataLayout &DL,
}
}
+void PPCAIXAsmPrinter::emitTTypeReference(const GlobalValue *GV,
+ unsigned Encoding) {
+ if (GV) {
+ MCSymbol *TypeInfoSym = TM.getSymbol(GV);
+ MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(TypeInfoSym);
+ const MCSymbol *TOCBaseSym =
+ cast<MCSectionXCOFF>(getObjFileLowering().getTOCBaseSection())
+ ->getQualNameSymbol();
+ auto &Ctx = OutStreamer->getContext();
+ const MCExpr *Exp =
+ MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCEntry, Ctx),
+ MCSymbolRefExpr::create(TOCBaseSym, Ctx), Ctx);
+ OutStreamer->emitValue(Exp, GetSizeOfEncodedValue(Encoding));
+ } else
+ OutStreamer->emitIntValue(0, GetSizeOfEncodedValue(Encoding));
+}
+
// Return a pass that prints the PPC assembly code for a MachineFunction to the
// given output stream.
static AsmPrinter *
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index b679d90eda42..92504da01cbf 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -3109,6 +3109,7 @@ static bool isCatchAll(EHPersonality Personality, Constant *TypeInfo) {
case EHPersonality::MSVC_CXX:
case EHPersonality::CoreCLR:
case EHPersonality::Wasm_CXX:
+ case EHPersonality::XL_CXX:
return TypeInfo->isNullValue();
}
llvm_unreachable("invalid enum");
diff --git a/llvm/test/CodeGen/PowerPC/aix-exception.ll b/llvm/test/CodeGen/PowerPC/aix-exception.ll
new file mode 100644
index 000000000000..edef76c75c68
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/aix-exception.ll
@@ -0,0 +1,152 @@
+; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff -mcpu=pwr4 \
+; RUN: -mattr=-altivec < %s | \
+; RUN: FileCheck --check-prefixes=ASM,ASM32 %s
+
+; RUN: llc -verify-machineinstrs -mtriple powerpc64-ibm-aix-xcoff -mcpu=pwr4 \
+; RUN: -mattr=-altivec < %s | \
+; RUN: FileCheck --check-prefixes=ASM,ASM64 %s
+
+ at _ZTIi = external constant i8*
+
+define void @_Z9throwFuncv() {
+entry:
+ %exception = call i8* @__cxa_allocate_exception(i32 4) #2
+ %0 = bitcast i8* %exception to i32*
+ store i32 1, i32* %0, align 16
+ call void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null) #3
+ unreachable
+}
+
+; ASM: ._Z9throwFuncv:
+; ASM: bl .__cxa_allocate_exception[PR]
+; ASM: nop
+; ASM32: lwz 4, L..C0(2)
+; ASM64: ld 4, L..C0(2)
+; ASM: bl .__cxa_throw[PR]
+; ASM: nop
+
+define i32 @_Z9catchFuncv() personality i8* bitcast (i32 (...)* @__xlcxx_personality_v1 to i8*) {
+entry:
+ %retval = alloca i32, align 4
+ %exn.slot = alloca i8*, align 4
+ %ehselector.slot = alloca i32, align 4
+ %0 = alloca i32, align 4
+ invoke void @_Z9throwFuncv()
+ to label %invoke.cont unwind label %lpad
+
+invoke.cont: ; preds = %entry
+ br label %try.cont
+
+lpad: ; preds = %entry
+ %1 = landingpad { i8*, i32 }
+ catch i8* bitcast (i8** @_ZTIi to i8*)
+ %2 = extractvalue { i8*, i32 } %1, 0
+ store i8* %2, i8** %exn.slot, align 4
+ %3 = extractvalue { i8*, i32 } %1, 1
+ store i32 %3, i32* %ehselector.slot, align 4
+ br label %catch.dispatch
+
+catch.dispatch: ; preds = %lpad
+ %sel = load i32, i32* %ehselector.slot, align 4
+ %4 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) #2
+ %matches = icmp eq i32 %sel, %4
+ br i1 %matches, label %catch, label %eh.resume
+
+catch: ; preds = %catch.dispatch
+ %exn = load i8*, i8** %exn.slot, align 4
+ %5 = call i8* @__cxa_begin_catch(i8* %exn) #2
+ %6 = bitcast i8* %5 to i32*
+ %7 = load i32, i32* %6, align 4
+ store i32 %7, i32* %0, align 4
+ store i32 2, i32* %retval, align 4
+ call void @__cxa_end_catch() #2
+ br label %return
+
+try.cont: ; preds = %invoke.cont
+ store i32 1, i32* %retval, align 4
+ br label %return
+
+return: ; preds = %try.cont, %catch
+ %8 = load i32, i32* %retval, align 4
+ ret i32 %8
+
+eh.resume: ; preds = %catch.dispatch
+ %exn1 = load i8*, i8** %exn.slot, align 4
+ %sel2 = load i32, i32* %ehselector.slot, align 4
+ %lpad.val = insertvalue { i8*, i32 } undef, i8* %exn1, 0
+ %lpad.val3 = insertvalue { i8*, i32 } %lpad.val, i32 %sel2, 1
+ resume { i8*, i32 } %lpad.val3
+}
+
+; ASM: ._Z9catchFuncv:
+; ASM: L..func_begin0:
+; ASM: # %bb.0: # %entry
+; ASM: mflr 0
+; ASM: L..tmp0:
+; ASM: bl ._Z9throwFuncv
+; ASM: nop
+; ASM: L..tmp1:
+; ASM: # %bb.1: # %invoke.cont
+; ASM: li 3, 1
+; ASM: L..BB1_2: # %return
+; ASM: mtlr 0
+; ASM: blr
+; ASM: L..BB1_3: # %lpad
+; ASM: L..tmp2:
+; ASM: bl .__cxa_begin_catch[PR]
+; ASM: nop
+; ASM: bl .__cxa_end_catch[PR]
+; ASM: nop
+; ASM: b L..BB1_2
+; ASM: L..func_end0:
+
+; ASM: .csect .gcc_except_table[RO],2
+; ASM: .align 2
+; ASM: GCC_except_table1:
+; ASM: L..exception0:
+; ASM: .byte 255 # @LPStart Encoding = omit
+; ASM32: .byte 187 # @TType Encoding = indirect datarel sdata4
+; ASM64: .byte 188 # @TType Encoding = indirect datarel sdata8
+; ASM: .uleb128 L..ttbase0-L..ttbaseref0
+; ASM: L..ttbaseref0:
+; ASM: .byte 3 # Call site Encoding = udata4
+; ASM: .uleb128 L..cst_end0-L..cst_begin0
+; ASM: L..cst_begin0:
+; ASM: .vbyte 4, L..tmp0-L..func_begin0 # >> Call Site 1 <<
+; ASM: .vbyte 4, L..tmp1-L..tmp0 # Call between L..tmp0 and L..tmp1
+; ASM: .vbyte 4, L..tmp2-L..func_begin0 # jumps to L..tmp2
+; ASM: .byte 1 # On action: 1
+; ASM: .vbyte 4, L..tmp1-L..func_begin0 # >> Call Site 2 <<
+; ASM: .vbyte 4, L..func_end0-L..tmp1 # Call between L..tmp1 and L..func_end0
+; ASM: .vbyte 4, 0 # has no landing pad
+; ASM: .byte 0 # On action: cleanup
+; ASM: L..cst_end0:
+; ASM: .byte 1 # >> Action Record 1 <<
+; ASM: # Catch TypeInfo 1
+; ASM: .byte 0 # No further actions
+; ASM: .align 2
+; ASM: # >> Catch TypeInfos <<
+; ASM32: .vbyte 4, L..C0-TOC[TC0] # TypeInfo 1
+; ASM64: .vbyte 8, L..C0-TOC[TC0] # TypeInfo 1
+; ASM: L..ttbase0:
+; ASM: .align 2
+; ASM: .csect .eh_info_table[RW],2
+; ASM: __ehinfo.1:
+; ASM: .vbyte 4, 0
+; ASM32: .align 2
+; ASM32: .vbyte 4, GCC_except_table1
+; ASM32: .vbyte 4, __xlcxx_personality_v1[DS]
+; ASM64: .align 3
+; ASM64: .vbyte 8, GCC_except_table1
+; ASM64: .vbyte 8, __xlcxx_personality_v1[DS]
+
+; ASM: .toc
+; ASM: L..C0:
+; ASM: .tc _ZTIi[TC],_ZTIi[UA]
+
+declare i8* @__cxa_allocate_exception(i32)
+declare void @__cxa_throw(i8*, i8*, i8*)
+declare i32 @__xlcxx_personality_v1(...)
+declare i32 @llvm.eh.typeid.for(i8*)
+declare i8* @__cxa_begin_catch(i8*)
+declare void @__cxa_end_catch()
More information about the llvm-branch-commits
mailing list