jasonliu updated this revision to Diff 308653.
jasonliu added a comment.

Address comment.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D91455/new/

https://reviews.llvm.org/D91455

Files:
  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/AIXException.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
  llvm/test/CodeGen/PowerPC/aix-exception.ll

Index: llvm/test/CodeGen/PowerPC/aix-exception.ll
===================================================================
--- /dev/null
+++ 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
+
+@_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 = <unknown encoding>
+; ASM64:  .byte	188                             # @TType Encoding = <unknown encoding>
+; 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()
Index: llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -3109,6 +3109,7 @@
   case EHPersonality::MSVC_CXX:
   case EHPersonality::CoreCLR:
   case EHPersonality::Wasm_CXX:
+  case EHPersonality::XL_CXX:
     return TypeInfo->isNullValue();
   }
   llvm_unreachable("invalid enum");
Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
===================================================================
--- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -195,6 +195,8 @@
   void emitInstruction(const MachineInstr *MI) override;
 
   bool doFinalization(Module &M) override;
+
+  void emitTTypeReference(const GlobalValue *GV, unsigned Encoding) override;
 };
 
 } // end anonymous namespace
@@ -2019,6 +2021,23 @@
   }
 }
 
+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));
+}
+
 /// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code
 /// for a MachineFunction to the given output stream, in a format that the
 /// Darwin assembler can deal with.
Index: llvm/lib/MC/MCObjectFileInfo.cpp
===================================================================
--- llvm/lib/MC/MCObjectFileInfo.cpp
+++ llvm/lib/MC/MCObjectFileInfo.cpp
@@ -881,6 +881,14 @@
   // 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.
Index: llvm/lib/MC/MCAsmInfoXCOFF.cpp
===================================================================
--- llvm/lib/MC/MCAsmInfoXCOFF.cpp
+++ llvm/lib/MC/MCAsmInfoXCOFF.cpp
@@ -37,6 +37,8 @@
   HasDotTypeDotSizeDirective = false;
   UseIntegratedAssembler = false;
   NeedsFunctionDescriptors = true;
+
+  ExceptionsType = ExceptionHandling::AIX;
 }
 
 bool MCAsmInfoXCOFF::isAcceptableChar(char C) const {
Index: llvm/lib/CodeGen/TargetPassConfig.cpp
===================================================================
--- llvm/lib/CodeGen/TargetPassConfig.cpp
+++ llvm/lib/CodeGen/TargetPassConfig.cpp
@@ -735,6 +735,7 @@
     LLVM_FALLTHROUGH;
   case ExceptionHandling::DwarfCFI:
   case ExceptionHandling::ARM:
+  case ExceptionHandling::AIX:
     addPass(createDwarfEHPass(getOptLevel()));
     break;
   case ExceptionHandling::WinEH:
Index: llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
===================================================================
--- llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -2236,9 +2236,13 @@
 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(
Index: llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp
===================================================================
--- llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp
+++ llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp
@@ -288,11 +288,13 @@
       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;
       }
Index: llvm/lib/CodeGen/AsmPrinter/DwarfException.h
===================================================================
--- llvm/lib/CodeGen/AsmPrinter/DwarfException.h
+++ llvm/lib/CodeGen/AsmPrinter/DwarfException.h
@@ -92,6 +92,20 @@
   /// 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
Index: llvm/lib/CodeGen/AsmPrinter/CMakeLists.txt
===================================================================
--- llvm/lib/CodeGen/AsmPrinter/CMakeLists.txt
+++ 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
Index: llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
===================================================================
--- llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
+++ llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
@@ -138,8 +138,7 @@
   }
 }
 
-void AsmPrinter::emitTTypeReference(const GlobalValue *GV,
-                                    unsigned Encoding) const {
+void AsmPrinter::emitTTypeReference(const GlobalValue *GV, unsigned Encoding) {
   if (GV) {
     const TargetLoweringObjectFile &TLOF = getObjFileLowering();
 
Index: llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
===================================================================
--- llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -368,6 +368,9 @@
   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,
Index: llvm/lib/CodeGen/AsmPrinter/AIXException.cpp
===================================================================
--- /dev/null
+++ 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;  /* Pointerto 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
Index: llvm/lib/Analysis/EHPersonalities.cpp
===================================================================
--- llvm/lib/Analysis/EHPersonalities.cpp
+++ llvm/lib/Analysis/EHPersonalities.cpp
@@ -39,6 +39,7 @@
       .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 @@
   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!");
   }
 
Index: llvm/include/llvm/MC/MCTargetOptions.h
===================================================================
--- llvm/include/llvm/MC/MCTargetOptions.h
+++ llvm/include/llvm/MC/MCTargetOptions.h
@@ -22,6 +22,7 @@
   ARM,      ///< ARM EHABI
   WinEH,    ///< Windows Exception Handling
   Wasm,     ///< WebAssembly Exception Handling
+  AIX,      ///< AIX Exception Handling
 };
 
 enum class DebugCompressionType {
Index: llvm/include/llvm/CodeGen/AsmPrinter.h
===================================================================
--- llvm/include/llvm/CodeGen/AsmPrinter.h
+++ llvm/include/llvm/CodeGen/AsmPrinter.h
@@ -603,7 +603,7 @@
   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 different ways. Some use a relocation others encode
Index: llvm/include/llvm/Analysis/EHPersonalities.h
===================================================================
--- llvm/include/llvm/Analysis/EHPersonalities.h
+++ llvm/include/llvm/Analysis/EHPersonalities.h
@@ -32,7 +32,8 @@
   MSVC_CXX,
   CoreCLR,
   Rust,
-  Wasm_CXX
+  Wasm_CXX,
+  XL_CXX
 };
 
 /// See if the given exception handling personality function is one
Index: clang/test/CodeGenCXX/personality.cpp
===================================================================
--- clang/test/CodeGenCXX/personality.cpp
+++ 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 @@
 
 // CHECK-WIN: personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
 
+// CHECK-AIX: personality i8* bitcast (i32 (...)* @__xlcxx_personality_v1 to i8*)
+
 void f() {
   try {
     g();
Index: clang/lib/CodeGen/CGException.cpp
===================================================================
--- clang/lib/CodeGen/CGException.cpp
+++ clang/lib/CodeGen/CGException.cpp
@@ -113,6 +113,8 @@
 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 @@
   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)
Index: clang/lib/CodeGen/CGCleanup.h
===================================================================
--- clang/lib/CodeGen/CGCleanup.h
+++ clang/lib/CodeGen/CGCleanup.h
@@ -612,6 +612,7 @@
   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?
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to