1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-25 04:02:41 +01:00

[XCOFF] Handle the case when personality routine is an alias

Summary:
Personality routine could be an alias to another personality routine.
Fix the situation when we compile the file that contains the personality
routine and the file also have functions that need to refer to the
personality routine.

Reviewed By: hubert.reinterpretcast

Differential Revision: https://reviews.llvm.org/D101401
This commit is contained in:
jasonliu 2021-04-29 20:39:43 +00:00
parent 748b2260be
commit f6fc5dd17d
4 changed files with 82 additions and 7 deletions

View File

@ -19,9 +19,9 @@ using namespace llvm;
/// See if the given exception handling personality function is one that we
/// understand. If so, return a description of it; otherwise return Unknown.
EHPersonality llvm::classifyEHPersonality(const Value *Pers) {
const Function *F =
Pers ? dyn_cast<Function>(Pers->stripPointerCasts()) : nullptr;
if (!F)
const GlobalValue *F =
Pers ? dyn_cast<GlobalValue>(Pers->stripPointerCasts()) : nullptr;
if (!F || !F->getValueType() || !F->getValueType()->isFunctionTy())
return EHPersonality::Unknown;
return StringSwitch<EHPersonality>(F->getName())
.Case("__gnat_eh_personality", EHPersonality::GNU_Ada)

View File

@ -69,8 +69,8 @@ void AIXException::endFunction(const MachineFunction *MF) {
const Function &F = MF->getFunction();
assert(F.hasPersonalityFn() &&
"Landingpads are presented, but no personality routine is found.");
const Function *Per =
dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts());
const GlobalValue *Per =
dyn_cast<GlobalValue>(F.getPersonalityFn()->stripPointerCasts());
const MCSymbol *PerSym = Asm->TM.getSymbol(Per);
emitExceptionInfoTable(LSDALabel, PerSym);

View File

@ -2144,8 +2144,9 @@ bool TargetLoweringObjectFileXCOFF::ShouldEmitEHBlock(
if (!F.hasPersonalityFn() || !F.needsUnwindTableEntry())
return false;
const Function *Per =
dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts());
const GlobalValue *Per =
dyn_cast<GlobalValue>(F.getPersonalityFn()->stripPointerCasts());
assert(Per && "Personality routine is not a GlobalValue type.");
if (isNoOpWithoutInvoke(classifyEHPersonality(Per)))
return false;

View File

@ -0,0 +1,74 @@
;; Test if we are still able to compile even when the personality routine is just an alias.
; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mattr=-altivec \
; RUN: -mtriple powerpc-ibm-aix-xcoff < %s | FileCheck %s --check-prefixes=SYM,SYM32
; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mattr=-altivec \
; RUN: -mtriple powerpc64-ibm-aix-xcoff < %s | FileCheck %s --check-prefixes=SYM,SYM64
@__xlcxx_personality_v1 = alias i32 (), i32 ()* @__gxx_personality_v0
define i32 @__gxx_personality_v0() {
entry:
ret i32 1
}
define dso_local signext i32 @_Z3foov() #0 personality i8* bitcast (i32 ()* @__xlcxx_personality_v1 to i8*) {
entry:
%retval = alloca i32, align 4
%exn.slot = alloca i8*, align 8
%ehselector.slot = alloca i32, align 4
invoke void @_Z3barv()
to label %invoke.cont unwind label %lpad
invoke.cont: ; preds = %entry
br label %try.cont
lpad: ; preds = %entry
%0 = landingpad { i8*, i32 }
catch i8* null
%1 = extractvalue { i8*, i32 } %0, 0
store i8* %1, i8** %exn.slot, align 8
%2 = extractvalue { i8*, i32 } %0, 1
store i32 %2, i32* %ehselector.slot, align 4
br label %catch
catch: ; preds = %lpad
%exn = load i8*, i8** %exn.slot, align 8
br label %return
try.cont: ; preds = %invoke.cont
store i32 2, i32* %retval, align 4
br label %return
return: ; preds = %try.cont, %catch
ret i32 1
}
declare void @_Z3barv()
; SYM: .globl __gxx_personality_v0[DS] # -- Begin function __gxx_personality_v0
; SYM: .globl .__gxx_personality_v0
; SYM: .align 4
; SYM: .csect __gxx_personality_v0[DS]
; SYM: __xlcxx_personality_v1: # @__gxx_personality_v0
; SYM32: .vbyte 4, .__gxx_personality_v0
; SYM32: .vbyte 4, TOC[TC0]
; SYM32: .vbyte 4, 0
; SYM64: .vbyte 8, .__gxx_personality_v0
; SYM64: .vbyte 8, TOC[TC0]
; SYM64: .vbyte 8, 0
; SYM: .csect .text[PR],2
; SYM: .__gxx_personality_v0:
; SYM: .__xlcxx_personality_v1:
; SYM: # %bb.0: # %entry
; SYM: li 3, 1
; SYM: blr
; SYM: .csect .eh_info_table[RW],2
; SYM: __ehinfo.1:
; SYM: .vbyte 4, 0
; SYM32: .align 2
; SYM32: .vbyte 4, GCC_except_table1
; SYM32: .vbyte 4, __xlcxx_personality_v1
; SYM64: .align 3
; SYM64: .vbyte 8, GCC_except_table1
; SYM64: .vbyte 8, __xlcxx_personality_v1