llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-hexagon
@llvm/pr-subscribers-backend-mips
Author: Jameson Nash (vtjnash)
<details>
<summary>Changes</summary>
The purpose of this change is to remove a couple places that rely on
`GlobalValue->getValueType()` being semantically meaningful. This is an RFC
to get feedback on whether this is the right direction to go with restricting
the valid IR format for personalities, or whether there is consensus whether
this should instead gain better support taking a different approach.
Force the personality function of a function to be exactly Function, not any
arbitrary constant or alias. This change tries to enforce this at the type
level by changing Function::setPersonalityFn to take Function* instead of
Constant*. While a couple backends had test that the front-end would accept
arbitrary values here, the backends generally had bad support for that, since
on many backends (WASM, COFF) this must be emitted as a PCrel value, and on
many passes, this value is unconditionally cast to Function or GlobalValue. If
it cannot be cast, it is instead simply dropped by some passes or asserts.
Key changes:
- Function::getPersonalityFn() now returns Function* instead of Constant*
- Function::setPersonalityFn() now takes Function* instead of Constant*
- LLParser creates Function forward references when parsing personality
- LLParser validates that forward refs used as personality resolve to functions
- BitCode reader warns and drops invalid personalities (null, undef, aliases,
arbitrary constants) for backward compatibility with old bitcode
- Verifier checks that personality is a Function (no longer accepts aliases)
- Updated all target-specific code and tests
This is a breaking change for code that relied on using aliases or other
constants as personality functions. Such usage doesn't appear that it would
previously be well-supported, but might have worked in some cases. For example,
llvm-reduce relies on doing RAUW of functions with `ptr null`, even though it
appears that this could cause various backends to crash, such as
`DwarfCFIException` which needs to dereference `P` to construct a symbol
pointing to it:
```
@@ -124,8 +122,7 @@ void DwarfCFIException::beginBasicBlockSection(const
MachineBasicBlock &MBB) {
auto &F = MBB.getParent()->getFunction();
auto *P =
dyn_cast<GlobalValue>(F.getPersonalityFn()->stripPointerCasts());
assert(P && "Expected personality function");
// Record the personality function.
addPersonality(P);
```
One alternative I considered is to make this only a verifier error, which
defers the error detection until later, though may require more effort in other
passes to more carefully handle malformed IR. The advantage of that however is
that if something does RAUW this to an unsupported kind of value, the printer
itself crashes (the cast in getPersonalityFn is invalid), making it hard to
inspect what happened that it going wrong.
Since the purpose of this change is to remove some uses of
`GlobalValue->getValueType()`, a second alternative I considered is simply
to assume that the personality does in fact points at a function, and remove
the code that tries to ignore any personalities that might not point at a
function based on the getValueType result.
-[ ] TODO: need to prevent llvm-reduce from trying to RAUW a personality to a
constant ptr null.
-[ ] TODO: determine if either proposed alternative is preferred
---
Patch is 205.65 KiB, truncated to 20.00 KiB below, full version:
https://github.com/llvm/llvm-project/pull/176952.diff
182 Files Affected:
- (modified) clang/lib/CodeGen/CGException.cpp (+3-3)
- (modified) llvm/docs/LangRef.rst (+1-1)
- (modified) llvm/include/llvm/AsmParser/LLParser.h (+9-4)
- (modified) llvm/include/llvm/CodeGen/TargetLowering.h (+2-2)
- (modified) llvm/include/llvm/IR/EHPersonalities.h (+1-1)
- (modified) llvm/include/llvm/IR/Function.h (+2-2)
- (modified) llvm/lib/Analysis/MustExecute.cpp (+1-1)
- (modified) llvm/lib/AsmParser/LLParser.cpp (+70-12)
- (modified) llvm/lib/Bitcode/Reader/BitcodeReader.cpp (+23-3)
- (modified) llvm/lib/CodeGen/AsmPrinter/AIXException.cpp (+1-2)
- (modified) llvm/lib/CodeGen/AsmPrinter/ARMException.cpp (+1-3)
- (modified) llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp (+2-5)
- (modified) llvm/lib/CodeGen/AsmPrinter/WinException.cpp (+5-5)
- (modified) llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp (+1-1)
- (modified) llvm/lib/CodeGen/MachineLICM.cpp (+1-1)
- (modified) llvm/lib/CodeGen/RDFGraph.cpp (+1-1)
- (modified) llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (+1-1)
- (modified) llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (+1-1)
- (modified) llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp (+1-3)
- (modified) llvm/lib/IR/Core.cpp (+1-1)
- (modified) llvm/lib/IR/EHPersonalities.cpp (+4-6)
- (modified) llvm/lib/IR/Function.cpp (+3-3)
- (modified) llvm/lib/IR/Verifier.cpp (+4-5)
- (modified) llvm/lib/Target/AArch64/AArch64Arm64ECCallLowering.cpp (+4-7)
- (modified) llvm/lib/Target/AArch64/AArch64ISelLowering.cpp (+2-2)
- (modified) llvm/lib/Target/AArch64/AArch64ISelLowering.h (+2-2)
- (modified) llvm/lib/Target/ARM/ARMISelLowering.cpp (+2-2)
- (modified) llvm/lib/Target/ARM/ARMISelLowering.h (+2-2)
- (modified) llvm/lib/Target/CSKY/CSKYISelLowering.cpp (+2-2)
- (modified) llvm/lib/Target/CSKY/CSKYISelLowering.h (+2-2)
- (modified) llvm/lib/Target/Hexagon/HexagonISelLowering.h (+2-2)
- (modified) llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp (+2-2)
- (modified) llvm/lib/Target/LoongArch/LoongArchISelLowering.h (+2-2)
- (modified) llvm/lib/Target/M68k/M68kISelLowering.cpp (+2-2)
- (modified) llvm/lib/Target/M68k/M68kISelLowering.h (+2-2)
- (modified) llvm/lib/Target/Mips/MipsISelLowering.h (+2-2)
- (modified) llvm/lib/Target/PowerPC/PPCISelLowering.cpp (+2-2)
- (modified) llvm/lib/Target/PowerPC/PPCISelLowering.h (+2-2)
- (modified) llvm/lib/Target/RISCV/RISCVISelLowering.cpp (+2-2)
- (modified) llvm/lib/Target/RISCV/RISCVISelLowering.h (+2-2)
- (modified) llvm/lib/Target/Sparc/SparcISelLowering.h (+2-2)
- (modified) llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp (+1-2)
- (modified) llvm/lib/Target/SystemZ/SystemZISelLowering.cpp (+2-2)
- (modified) llvm/lib/Target/SystemZ/SystemZISelLowering.h (+2-2)
- (modified) llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
(+2-3)
- (modified) llvm/lib/Target/X86/X86ISelLowering.cpp (+2-2)
- (modified) llvm/lib/Target/X86/X86ISelLowering.h (+2-2)
- (modified) llvm/lib/Target/X86/X86WinEHState.cpp (+1-3)
- (modified) llvm/lib/Target/XCore/XCoreFrameLowering.cpp (+3-3)
- (modified) llvm/lib/Target/XCore/XCoreISelLowering.h (+2-2)
- (modified) llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp (+3-5)
- (modified) llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp (+3-4)
- (modified) llvm/lib/Transforms/Utils/CloneFunction.cpp (+3-3)
- (modified) llvm/lib/Transforms/Utils/CloneModule.cpp (+2-1)
- (modified) llvm/lib/Transforms/Utils/EscapeEnumerator.cpp (+6-5)
- (modified) llvm/lib/Transforms/Utils/InlineFunction.cpp (+6-12)
- (modified) llvm/test/Analysis/BlockFrequencyInfo/loop_with_invoke.ll (+2-1)
- (modified) llvm/test/Analysis/BranchProbabilityInfo/loop.ll (+2-1)
- (modified) llvm/test/Analysis/CallGraph/do-nothing-intrinsic.ll (+2-1)
- (modified)
llvm/test/Analysis/ScalarEvolution/backedge-taken-count-guard-info-with-multiple-predecessors.ll
(+3-1)
- (modified) llvm/test/Assembler/function-operand-uselistorder.ll (+3-2)
- (added) llvm/test/Assembler/personality-alias.ll (+20)
- (added) llvm/test/Assembler/personality-constant.ll (+16)
- (added) llvm/test/Assembler/personality-forward-ref-not-function.ll (+20)
- (added) llvm/test/Assembler/personality-forward-ref.ll (+26)
- (added) llvm/test/Assembler/personality-generic-then-not-function.ll (+28)
- (added) llvm/test/Assembler/personality-not-function.ll (+18)
- (added) llvm/test/Assembler/personality-null.ll (+7)
- (modified) llvm/test/Bitcode/compatibility-3.7.ll (+2-2)
- (modified) llvm/test/Bitcode/compatibility-3.8.ll (+2-2)
- (modified) llvm/test/Bitcode/compatibility-3.9.ll (+2-2)
- (modified) llvm/test/Bitcode/compatibility-4.0.ll (+2-2)
- (modified) llvm/test/Bitcode/compatibility-5.0.ll (+2-2)
- (modified) llvm/test/Bitcode/compatibility-6.0.ll (+2-2)
- (modified) llvm/test/Bitcode/compatibility.ll (+13-13)
- (modified) llvm/test/Bitcode/function-address-space-fwd-decl.ll (+3-1)
- (modified) llvm/test/Bitcode/operand-bundles.ll (+7-6)
- (modified) llvm/test/Bitcode/use-list-order2.ll (+3-2)
- (modified) llvm/test/CodeGen/AArch64/aarch64-fixup-statepoint-regs-crash.ll
(+4-4)
- (modified) llvm/test/CodeGen/AArch64/unwind-preserved-from-mir.mir (+2-1)
- (modified) llvm/test/CodeGen/AArch64/unwind-preserved.ll (+11-2)
- (removed) llvm/test/CodeGen/PowerPC/aix-personality-alias.ll (-74)
- (modified) llvm/test/CodeGen/X86/deopt-bundles.ll (+3-2)
- (modified) llvm/test/CodeGen/X86/eh-null-personality.ll (+2-1)
- (modified) llvm/test/CodeGen/X86/stack-protector-no-return.ll (+3-1)
- (modified) llvm/test/CodeGen/X86/x86-no_callee_saved_registers.ll (+2-1)
- (modified) llvm/test/Feature/OperandBundles/merge-func.ll (+3-2)
- (modified) llvm/test/Instrumentation/HWAddressSanitizer/personality-bti.ll
(+12-24)
- (modified) llvm/test/Instrumentation/HWAddressSanitizer/personality.ll
(+12-24)
- (modified) llvm/test/Linker/drop-attribute.ll (+2-1)
- (modified) llvm/test/Transforms/CodeGenPrepare/X86/fold-loop-of-urem.ll
(+2-2)
- (modified) llvm/test/Transforms/CodeGenPrepare/X86/sink-addr-recreate.ll
(+3-2)
- (modified) llvm/test/Transforms/ConstantHoisting/ARM/bad-cases.ll (+3-1)
- (modified) llvm/test/Transforms/ConstraintElimination/reproducer-remarks.ll
(+2-1)
- (modified) llvm/test/Transforms/Coroutines/coro-await-suspend-lower-invoke.ll
(+2-1)
- (modified) llvm/test/Transforms/Coroutines/coro-catchswitch.ll (+2-1)
- (modified) llvm/test/Transforms/Coroutines/coro-debug.ll (+6-5)
- (modified) llvm/test/Transforms/Coroutines/coro-eh-aware-edge-split-00.ll
(+2-1)
- (modified) llvm/test/Transforms/Coroutines/coro-eh-aware-edge-split-01.ll
(+2-1)
- (modified) llvm/test/Transforms/Coroutines/coro-eh-aware-edge-split-02.ll
(+2-1)
- (modified) llvm/test/Transforms/Coroutines/coro-elide-stat.ll (+2-1)
- (modified) llvm/test/Transforms/Coroutines/coro-elide.ll (+2-1)
- (modified) llvm/test/Transforms/Coroutines/coro-frame-unreachable.ll (+2-1)
- (modified) llvm/test/Transforms/Coroutines/coro-frame.ll (+2-1)
- (modified) llvm/test/Transforms/Coroutines/coro-heap-elide.ll (+4-3)
- (modified) llvm/test/Transforms/Coroutines/coro-resume-destroy.ll (+3-1)
- (modified)
llvm/test/Transforms/Coroutines/coro-spill-defs-before-corobegin.ll (+2-1)
- (modified) llvm/test/Transforms/Coroutines/coro-split-eh-00.ll (+2-1)
- (modified) llvm/test/Transforms/Coroutines/coro-split-eh-01.ll (+2-1)
- (modified) llvm/test/Transforms/Coroutines/coro-split-final-suspend.ll (+3-2)
- (modified) llvm/test/Transforms/Coroutines/coro-split-musttail13.ll (+2-1)
- (modified) llvm/test/Transforms/Coroutines/no-suspend.ll (+4-3)
- (modified) llvm/test/Transforms/DeadArgElim/aggregates.ll (+2-1)
- (modified) llvm/test/Transforms/DeadStoreElimination/captures-before-call.ll
(+2-1)
- (modified) llvm/test/Transforms/DeadStoreElimination/inter-procedural.ll
(+2-1)
- (modified) llvm/test/Transforms/DivRemPairs/X86/div-rem-pairs.ll (+3-2)
- (modified) llvm/test/Transforms/GVN/calloc-load-removal.ll (+2-1)
- (modified) llvm/test/Transforms/GVN/mssa-update-dead-def.ll (+3-2)
- (modified) llvm/test/Transforms/GVN/preserve-memoryssa.ll (+2-1)
- (modified) llvm/test/Transforms/GlobalOpt/invoke.ll (+2-1)
- (modified) llvm/test/Transforms/HotColdSplit/eh-pads.ll (+4-3)
- (modified) llvm/test/Transforms/HotColdSplit/resume.ll (+2-1)
- (modified) llvm/test/Transforms/HotColdSplit/unwind.ll (+2-1)
- (modified) llvm/test/Transforms/IROutliner/illegal-catchpad.ll (+3-2)
- (modified) llvm/test/Transforms/IROutliner/illegal-cleanup.ll (+3-2)
- (modified) llvm/test/Transforms/IROutliner/illegal-invoke.ll (+3-2)
- (modified) llvm/test/Transforms/IROutliner/illegal-landingpad.ll (+3-2)
- (modified) llvm/test/Transforms/IndVarSimplify/AArch64/widen-loop-comp.ll
(+2-1)
- (modified) llvm/test/Transforms/IndVarSimplify/pr55925.ll (+3-2)
- (modified) llvm/test/Transforms/Inline/X86/inline-landing-pad.ll (+6-4)
- (modified) llvm/test/Transforms/Inline/deopt-bundles.ll (+7-6)
- (modified) llvm/test/Transforms/Inline/deoptimize-intrinsic.ll (+2-1)
- (modified) llvm/test/Transforms/Inline/guard-intrinsic.ll (+2-1)
- (modified) llvm/test/Transforms/Inline/inline_returns_twice.ll (+3-2)
- (modified) llvm/test/Transforms/Inline/invoke-cleanup.ll (+3-2)
- (modified) llvm/test/Transforms/Inline/invoke-combine-clauses.ll (+7-6)
- (modified) llvm/test/Transforms/Inline/pr53206.ll (+3-2)
- (modified) llvm/test/Transforms/InstCombine/debuginfo-invoke.ll (+3-2)
- (modified) llvm/test/Transforms/InstCombine/fabs.ll (+2-1)
- (modified) llvm/test/Transforms/InstCombine/freeze-landingpad.ll (+3-1)
- (modified) llvm/test/Transforms/InstCombine/freeze.ll (+11-10)
- (modified) llvm/test/Transforms/InstSimplify/freeze.ll (+2-1)
- (modified)
llvm/test/Transforms/InstSimplify/invalid-load-operand-infinite-loop.ll (+2-1)
- (modified) llvm/test/Transforms/InstSimplify/known-never-nan.ll (+2-1)
- (modified) llvm/test/Transforms/LoopDeletion/loop-with-ehpad-not-executed.ll
(+4-2)
- (modified) llvm/test/Transforms/LoopDeletion/pr62160.ll (+3-2)
- (modified)
llvm/test/Transforms/LoopStrengthReduce/X86/eh-insertion-point-2.ll (+2-1)
- (modified) llvm/test/Transforms/LoopStrengthReduce/X86/eh-insertion-point.ll
(+2-1)
- (modified)
llvm/test/Transforms/LoopStrengthReduce/phi_ehpad_ignore_sameval.ll (+3-1)
- (modified) llvm/test/Transforms/LoopUnroll/peel-loop-conditions.ll (+2-1)
- (modified) llvm/test/Transforms/LoopVectorize/expand-scev-after-invoke.ll
(+3-2)
- (modified) llvm/test/Transforms/LowerInvoke/lowerinvoke.ll (+2-1)
- (modified) llvm/test/Transforms/MemCpyOpt/stack-move.ll (+3-2)
- (modified) llvm/test/Transforms/MergeFunc/call-and-invoke-with-ranges-attr.ll
(+4-4)
- (modified) llvm/test/Transforms/MergeFunc/call-and-invoke-with-ranges.ll
(+4-4)
- (modified) llvm/test/Transforms/RewriteStatepointsForGC/basic.ll (+3-2)
- (modified) llvm/test/Transforms/RewriteStatepointsForGC/preprocess.ll (+2-1)
- (modified) llvm/test/Transforms/SCCP/landingpad.ll (+2-1)
- (modified)
llvm/test/Transforms/SLPVectorizer/RISCV/small-tree-not-schedulable-bv-node.ll
(+6-4)
- (modified) llvm/test/Transforms/SLPVectorizer/X86/catchswitch-block-in-use.ll
(+4-2)
- (modified)
llvm/test/Transforms/SLPVectorizer/X86/extractelement-phi-in-landingpad.ll
(+4-2)
- (modified)
llvm/test/Transforms/SLPVectorizer/X86/landing-pad-for-split-node.ll (+4-2)
- (modified)
llvm/test/Transforms/SLPVectorizer/X86/no-schedule-terminate-inst.ll (+4-2)
- (modified)
llvm/test/Transforms/SimplifyCFG/FoldValueComparisonIntoPredecessors-domtree-preservation-edgecase-2.ll
(+2-1)
- (modified) llvm/test/Transforms/SimplifyCFG/X86/bug-25299.ll (+3-1)
- (modified) llvm/test/Transforms/SimplifyCFG/X86/debugloc-invoke-to-call-br.ll
(+3-2)
- (modified)
llvm/test/Transforms/SimplifyCFG/X86/merge-compatible-invokes-of-landingpad.ll
(+2-2)
- (modified) llvm/test/Transforms/SimplifyCFG/dbgloc-merge-invoke.ll (+3-2)
- (modified)
llvm/test/Transforms/SimplifyCFG/unreachable-multi-basic-block-funclet.ll
(+16-14)
- (modified) llvm/test/Transforms/TailCallElim/deopt-bundle.ll (+2-1)
- (modified) llvm/test/Transforms/Util/strip-gc-relocates.ll (+2-1)
- (modified) llvm/test/Verifier/deoptimize-intrinsic.ll (+2-1)
- (modified) llvm/test/Verifier/guard-intrinsic.ll (+2-1)
- (modified) llvm/test/Verifier/invalid-cleanuppad-chain.ll (+3-1)
- (modified) llvm/test/Verifier/operand-bundles.ll (+2-1)
- (modified)
llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/mips64_eh.ll
(+1-1)
- (modified)
llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/mips64_eh.ll.expected
(+1-1)
- (modified) llvm/test/tools/llvm-reduce/invoke-with-missing-landingpad.ll
(+3-2)
- (modified) llvm/unittests/Analysis/IRSimilarityIdentifierTest.cpp (+4-2)
- (modified) llvm/unittests/Transforms/Utils/CodeExtractorTest.cpp (+4-2)
- (modified) mlir/lib/Target/LLVMIR/ModuleImport.cpp (+2-16)
- (modified) mlir/lib/Target/LLVMIR/ModuleTranslation.cpp (+1-1)
``````````diff
diff --git a/clang/lib/CodeGen/CGException.cpp
b/clang/lib/CodeGen/CGException.cpp
index e9d20672ce185..e3338e619e68d 100644
--- a/clang/lib/CodeGen/CGException.cpp
+++ b/clang/lib/CodeGen/CGException.cpp
@@ -270,10 +270,10 @@ static llvm::FunctionCallee
getPersonalityFn(CodeGenModule &CGM,
llvm::AttributeList(), /*Local=*/true);
}
-static llvm::Constant *getOpaquePersonalityFn(CodeGenModule &CGM,
- const EHPersonality &Personality) {
+static llvm::Function *getOpaquePersonalityFn(CodeGenModule &CGM,
+ const EHPersonality
&Personality) {
llvm::FunctionCallee Fn = getPersonalityFn(CGM, Personality);
- return cast<llvm::Constant>(Fn.getCallee());
+ return cast<llvm::Function>(Fn.getCallee());
}
/// Check whether a landingpad instruction only uses C++ features.
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index a6881099f81f4..62ae9f4b76411 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -986,7 +986,7 @@ Syntax::
<ResultType> @<FunctionName> ([argument list])
[(unnamed_addr|local_unnamed_addr)] [AddrSpace] [fn Attrs]
[section "name"] [partition "name"] [comdat [($name)]] [align N]
- [gc] [prefix Constant] [prologue Constant] [personality Constant]
+ [gc] [prefix Constant] [prologue Constant] [personality Function]
(!name !N)* { ... }
The argument list is a comma-separated sequence of arguments where each
diff --git a/llvm/include/llvm/AsmParser/LLParser.h
b/llvm/include/llvm/AsmParser/LLParser.h
index 9eb31d7e0a451..17210a755bd8e 100644
--- a/llvm/include/llvm/AsmParser/LLParser.h
+++ b/llvm/include/llvm/AsmParser/LLParser.h
@@ -227,9 +227,12 @@ namespace llvm {
/// getGlobalVal - Get a value with the specified name or ID, creating a
/// forward reference record if needed. This can return null if the value
- /// exists but does not have the right type.
- GlobalValue *getGlobalVal(const std::string &N, Type *Ty, LocTy Loc);
- GlobalValue *getGlobalVal(unsigned ID, Type *Ty, LocTy Loc);
+ /// exists but does not have the right type. If ExpectFunction is true,
+ /// forward references will be created as Function placeholders.
+ GlobalValue *getGlobalVal(const std::string &N, Type *Ty, LocTy Loc,
+ bool ExpectFunction = false);
+ GlobalValue *getGlobalVal(unsigned ID, Type *Ty, LocTy Loc,
+ bool ExpectFunction = false);
/// Get a Comdat with the specified name, creating a forward reference
/// record if needed.
@@ -520,7 +523,8 @@ namespace llvm {
};
bool convertValIDToValue(Type *Ty, ValID &ID, Value *&V,
- PerFunctionState *PFS);
+ PerFunctionState *PFS,
+ bool ExpectFunction = false);
Value *checkValidVariableType(LocTy Loc, const Twine &Name, Type *Ty,
Value *Val);
@@ -577,6 +581,7 @@ namespace llvm {
Type *ExpectedTy = nullptr);
bool parseGlobalValue(Type *Ty, Constant *&C);
bool parseGlobalTypeAndValue(Constant *&V);
+ bool parsePersonality(Function *&F);
bool parseGlobalValueVector(SmallVectorImpl<Constant *> &Elts);
bool parseOptionalComdat(StringRef GlobalName, Comdat *&C);
bool parseSanitizer(GlobalVariable *GV);
diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h
b/llvm/include/llvm/CodeGen/TargetLowering.h
index 3bbeee5e1616b..15ee20943fba0 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -2099,14 +2099,14 @@ class LLVM_ABI TargetLoweringBase {
/// If a physical register, this returns the register that receives the
/// exception address on entry to an EH pad.
virtual Register
- getExceptionPointerRegister(const Constant *PersonalityFn) const {
+ getExceptionPointerRegister(const Function *PersonalityFn) const {
return Register();
}
/// If a physical register, this returns the register that receives the
/// exception typeid on entry to a landing pad.
virtual Register
- getExceptionSelectorRegister(const Constant *PersonalityFn) const {
+ getExceptionSelectorRegister(const Function *PersonalityFn) const {
return Register();
}
diff --git a/llvm/include/llvm/IR/EHPersonalities.h
b/llvm/include/llvm/IR/EHPersonalities.h
index 39f6817b3dc38..895eb5f778881 100644
--- a/llvm/include/llvm/IR/EHPersonalities.h
+++ b/llvm/include/llvm/IR/EHPersonalities.h
@@ -40,7 +40,7 @@ enum class EHPersonality {
/// See if the given exception handling personality function is one
/// that we understand. If so, return a description of it; otherwise return
/// Unknown.
-LLVM_ABI EHPersonality classifyEHPersonality(const Value *Pers);
+LLVM_ABI EHPersonality classifyEHPersonality(const Function *Pers);
LLVM_ABI StringRef getEHPersonalityName(EHPersonality Pers);
diff --git a/llvm/include/llvm/IR/Function.h b/llvm/include/llvm/IR/Function.h
index d3497716ca844..e9d0ef3dd0946 100644
--- a/llvm/include/llvm/IR/Function.h
+++ b/llvm/include/llvm/IR/Function.h
@@ -905,8 +905,8 @@ class LLVM_ABI Function : public GlobalObject, public
ilist_node<Function> {
}
/// Get the personality function associated with this function.
- Constant *getPersonalityFn() const;
- void setPersonalityFn(Constant *Fn);
+ Function *getPersonalityFn() const;
+ void setPersonalityFn(Function *Fn);
/// Check whether this function has prefix data.
bool hasPrefixData() const {
diff --git a/llvm/lib/Analysis/MustExecute.cpp
b/llvm/lib/Analysis/MustExecute.cpp
index fde6bbf9eb181..4a48f0bd89b3e 100644
--- a/llvm/lib/Analysis/MustExecute.cpp
+++ b/llvm/lib/Analysis/MustExecute.cpp
@@ -104,7 +104,7 @@ void LoopSafetyInfo::computeBlockColors(const Loop
*CurLoop) {
// personality routine.
Function *Fn = CurLoop->getHeader()->getParent();
if (Fn->hasPersonalityFn())
- if (Constant *PersonalityFn = Fn->getPersonalityFn())
+ if (Function *PersonalityFn = Fn->getPersonalityFn())
if (isScopedEHPersonality(classifyEHPersonality(PersonalityFn)))
BlockColors = colorEHFunclets(*Fn);
}
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 03b808c4fdeef..d9231d8eb8837 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -1288,6 +1288,10 @@ bool LLParser::parseAliasOrIFunc(const std::string
&Name, unsigned NameID,
NumberedVals.add(NameID, GV);
if (GVal) {
+ if (isa<Function>(GVal))
+ return error(NameLoc,
+ "forward reference used as personality must be a function");
+
// Verify that types agree.
if (GVal->getType() != GV->getType())
return error(
@@ -1445,6 +1449,10 @@ bool LLParser::parseGlobal(const std::string &Name,
unsigned NameID,
GV->setUnnamedAddr(UnnamedAddr);
if (GVal) {
+ if (isa<Function>(GVal))
+ return error(NameLoc,
+ "forward reference used as personality must be a function");
+
if (GVal->getAddressSpace() != AddrSpace)
return error(
TyLoc,
@@ -1759,9 +1767,14 @@ bool LLParser::parseFnAttributeValuePairs(AttrBuilder &B,
// GlobalValue Reference/Resolution Routines.
//===----------------------------------------------------------------------===//
-static inline GlobalValue *createGlobalFwdRef(Module *M, PointerType *PTy) {
+static inline GlobalValue *createGlobalFwdRef(Module *M, PointerType *PTy,
+ bool ExpectFunction = false) {
// The used global type does not matter. We will later RAUW it with a
// global/function of the correct type.
+ if (ExpectFunction)
+ return Function::Create(
+ FunctionType::get(Type::getVoidTy(M->getContext()), false),
+ GlobalValue::ExternalWeakLinkage, PTy->getAddressSpace(), "", M);
return new GlobalVariable(*M, Type::getInt8Ty(M->getContext()), false,
GlobalValue::ExternalWeakLinkage, nullptr, "",
nullptr, GlobalVariable::NotThreadLocal,
@@ -1786,7 +1799,7 @@ Value *LLParser::checkValidVariableType(LocTy Loc, const
Twine &Name, Type *Ty,
/// forward reference record if needed. This can return null if the value
/// exists but does not have the right type.
GlobalValue *LLParser::getGlobalVal(const std::string &Name, Type *Ty,
- LocTy Loc) {
+ LocTy Loc, bool ExpectFunction) {
PointerType *PTy = dyn_cast<PointerType>(Ty);
if (!PTy) {
error(Loc, "global variable reference must have pointer type");
@@ -1801,8 +1814,17 @@ GlobalValue *LLParser::getGlobalVal(const std::string
&Name, Type *Ty,
// forward ref record.
if (!Val) {
auto I = ForwardRefVals.find(Name);
- if (I != ForwardRefVals.end())
+ if (I != ForwardRefVals.end()) {
Val = I->second.first;
+ // If we expect a function but the forward ref is not one, RAUW it.
+ if (ExpectFunction && !isa<Function>(Val)) {
+ GlobalValue *FwdVal = createGlobalFwdRef(M, PTy,
/*ExpectFunction=*/true);
+ Val->replaceAllUsesWith(FwdVal);
+ Val->eraseFromParent();
+ ForwardRefVals[Name] = std::make_pair(FwdVal, I->second.second);
+ return FwdVal;
+ }
+ }
}
// If we have the value in the symbol table or fwd-ref table, return it.
@@ -1811,12 +1833,13 @@ GlobalValue *LLParser::getGlobalVal(const std::string
&Name, Type *Ty,
checkValidVariableType(Loc, "@" + Name, Ty, Val));
// Otherwise, create a new forward reference for this value and remember it.
- GlobalValue *FwdVal = createGlobalFwdRef(M, PTy);
+ GlobalValue *FwdVal = createGlobalFwdRef(M, PTy, ExpectFunction);
ForwardRefVals[Name] = std::make_pair(FwdVal, Loc);
return FwdVal;
}
-GlobalValue *LLParser::getGlobalVal(unsigned ID, Type *Ty, LocTy Loc) {
+GlobalValue *LLParser::getGlobalVal(unsigned ID, Type *Ty, LocTy Loc,
+ bool ExpectFunction) {
PointerType *PTy = dyn_cast<PointerType>(Ty);
if (!PTy) {
error(Loc, "global variable reference must have pointer type");
@@ -1829,8 +1852,17 @@ GlobalValue *LLParser::getGlobalVal(unsigned ID, Type
*Ty, LocTy Loc) {
// forward ref record.
if (!Val) {
auto I = ForwardRefValIDs.find(ID);
- if (I != ForwardRefValIDs.end())
+ if (I != ForwardRefValIDs.end()) {
Val = I->second.first;
+ // If we expect a function but the forward ref is not one, RAUW it.
+ if (ExpectFunction && !isa<Function>(Val)) {
+ GlobalValue *FwdVal = createGlobalFwdRef(M, PTy,
/*ExpectFunction=*/true);
+ Val->replaceAllUsesWith(FwdVal);
+ Val->eraseFromParent();
+ ForwardRefValIDs[ID] = std::make_pair(FwdVal, I->second.second);
+ return FwdVal;
+ }
+ }
}
// If we have the value in the symbol table or fwd-ref table, return it.
@@ -1839,7 +1871,7 @@ GlobalValue *LLParser::getGlobalVal(unsigned ID, Type
*Ty, LocTy Loc) {
checkValidVariableType(Loc, "@" + Twine(ID), Ty, Val));
// Otherwise, create a new forward reference for this value and remember it.
- GlobalValue *FwdVal = createGlobalFwdRef(M, PTy);
+ GlobalValue *FwdVal = createGlobalFwdRef(M, PTy, ExpectFunction);
ForwardRefValIDs[ID] = std::make_pair(FwdVal, Loc);
return FwdVal;
}
@@ -4615,6 +4647,31 @@ bool LLParser::parseGlobalTypeAndValue(Constant *&V) {
return parseType(Ty) || parseGlobalValue(Ty, V);
}
+/// parsePersonality
+/// ::= TypeAndValue (expecting a function, null, undef, or poison)
+bool LLParser::parsePersonality(Function *&F) {
+ Type *Ty = nullptr;
+ if (parseType(Ty))
+ return true;
+ F = nullptr;
+ ValID ID;
+ Value *V = nullptr;
+ LocTy Loc = Lex.getLoc();
+ bool Parsed = parseValID(ID, /*PFS=*/nullptr, Ty) ||
+ convertValIDToValue(Ty, ID, V, nullptr,
/*ExpectFunction=*/true);
+ if (Parsed)
+ return true;
+ if (!V)
+ return false;
+ // Allow null/zero/undef/poison constants and treat them as nullptr (no
personality) for parsing legacy IR.
+ if (isa<ConstantPointerNull>(V) || isa<UndefValue>(V) ||
+ (isa<Constant>(V) && cast<Constant>(V)->isNullValue()))
+ return false;
+ if (!(F = dyn_cast<Function>(V)))
+ return error(Loc, "expected function");
+ return false;
+}
+
bool LLParser::parseOptionalComdat(StringRef GlobalName, Comdat *&C) {
C = nullptr;
@@ -6494,7 +6551,8 @@ bool LLParser::parseMetadata(Metadata *&MD,
PerFunctionState *PFS) {
//===----------------------------------------------------------------------===//
bool LLParser::convertValIDToValue(Type *Ty, ValID &ID, Value *&V,
- PerFunctionState *PFS) {
+ PerFunctionState *PFS,
+ bool ExpectFunction) {
if (Ty->isFunctionTy())
return error(ID.Loc, "functions are not values, refer to them as
pointers");
@@ -6520,12 +6578,12 @@ bool LLParser::convertValIDToValue(Type *Ty, ValID &ID,
Value *&V,
return false;
}
case ValID::t_GlobalName:
- V = getGlobalVal(ID.StrVal, Ty, ID.Loc);
+ V = getGlobalVal(ID.StrVal, Ty, ID.Loc, ExpectFunction);
if (V && ID.NoCFI)
V = NoCFIValue::get(cast<GlobalValue>(V));
return V == nullptr;
case ValID::t_GlobalID:
- V = getGlobalVal(ID.UIntVal, Ty, ID.Loc);
+ V = getGlobalVal(ID.UIntVal, Ty, ID.Loc, ExpectFunction);
if (V && ID.NoCFI)
V = NoCFIValue::get(cast<GlobalValue>(V));
return V == nullptr;
@@ -6808,7 +6866,7 @@ bool LLParser::parseFunctionHeader(Function *&Fn, bool
IsDefine,
unsigned AddrSpace = 0;
Constant *Prefix = nullptr;
Constant *Prologue = nullptr;
- Constant *PersonalityFn = nullptr;
+ Function *PersonalityFn = nullptr;
Comdat *C;
if (parseArgumentList(ArgList, UnnamedArgNums, IsVarArg) ||
@@ -6824,7 +6882,7 @@ bool LLParser::parseFunctionHeader(Function *&Fn, bool
IsDefine,
(EatIfPresent(lltok::kw_prefix) && parseGlobalTypeAndValue(Prefix)) ||
(EatIfPresent(lltok::kw_prologue) && parseGlobalTypeAndValue(Prologue))
||
(EatIfPresent(lltok::kw_personality) &&
- parseGlobalTypeAndValue(PersonalityFn)))
+ parsePersonality(PersonalityFn)))
return true;
if (FuncAttrs.contains(Attribute::Builtin))
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index 34dcce92a8cdd..b3897b6eab1e8 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -3193,7 +3193,24 @@ Error
BitcodeReader::resolveGlobalAndIndirectSymbolInits() {
Expected<Constant *> MaybeC = getValueForInitializer(ValID);
if (!MaybeC)
return MaybeC.takeError();
- Info.F->setPersonalityFn(MaybeC.get());
+ Constant *C = MaybeC.get();
+ // Old bitcode may have null/undef/poison as personality - treat as
none.
+ // Also unwrap any ConstantExpr (bitcast, etc.) to get the underlying
+ // function.
+ if (!C->isNullValue() && !isa<UndefValue>(C)) {
+ C = C->stripPointerCasts();
+ if (!C->isNullValue() && !isa<UndefValue>(C)) {
+ Function *PersonalityFn = dyn_cast<Function>(C);
+ if (!PersonalityFn) {
+ // Warn and drop unsupported personality (e.g. alias, constant).
+ errs() << "warning: dropping unsupported personality for "
+ << Info.F->getName() << " (got "
+ << C->getNameOrAsOperand() << ")\n";
+ } else {
+ Info.F->setPersonalityFn(PersonalityFn);
+ }
+ }
+ }
Info.PersonalityFn = 0;
}
}
@@ -6204,9 +6221,12 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
nullptr))
return error("Invalid landingpad record");
+ Function *PersonalityFn = dyn_cast<Function>(PersFn);
+ if (!PersonalityFn)
+ return error("Personality function is not a Function");
if (!F->hasPersonalityFn())
- F->setPersonalityFn(cast<Constant>(PersFn));
- else if (F->getPersonalityFn() != cast<Constant>(PersFn))
+ F->setPersonalityFn(PersonalityFn);
+ else if (F->getPersonalityFn() != PersonalityFn)
return error("Personality function mismatch");
}
diff --git a/llvm/lib/CodeGen/AsmPrinter/AIXException.cpp
b/llvm/lib/CodeGen/AsmPrinter/AIXException.cpp
index 873ac8f05c1e0..534ca879d8138 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AIXException.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AIXException.cpp
@@ -84,8 +84,7 @@ void AIXException::endFunction(const MachineFunction *MF) {
const Function &F = MF->getFunction();
assert(F.hasPersonalityFn() &&
"Landingpads are presented, but no personality routine is found.");
- const auto *Per =
- cast<GlobalValue>(F.getPersonalityFn()->stripPointerCasts());
+ const Function *Per = F.getPersonalityFn();
const MCSymbol *PerSym = Asm->TM.getSymbol(Per);
emitExceptionInfoTable(LSDALabel, PerSym);
diff --git a/llvm/lib/CodeGen/AsmPrinter/ARMException.cpp
b/llvm/lib/CodeGen/AsmPrinter/ARMException.cpp
index 51342c6b91345..705320ed47113 100644
--- a/llvm/lib/CodeGen/AsmPrinter/ARMException.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/ARMException.cpp
@@ -58,9 +58,7 @@ void ARMException::markFunctionEnd() {
void ARMException::endFunction(const MachineFunction *MF) {
ARMTargetStreamer &ATS = getTargetStreamer();
const Function &F = MF->getFunction();
- const Function *Per = nullptr;
- if (F.hasPersonalityFn())
- Per = dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts());
+ const Function *Per = F.hasPersonalityFn() ? F.getPersonalityFn() : nullptr;
bool forceEmitPersonality =
F.hasPersonalityFn() && !isNoOpWithoutInvoke(classifyEHPersonality(Per)) &&
F.needsUnwindTableEntry();
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp
b/llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp
index 6b8d08cb201d6..803a2f763700a 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp
@@ -69,9 +69,7 @@ void DwarfCFIException::beginFunction(const MachineFunction
*MF) {
const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
unsigned PerEncoding = TLOF.getPersonalityEncoding();
- const GlobalValue *Per = nullptr;
- if (F.hasPersonalityFn())
- Per = dyn_cast<GlobalValue>(F.getPersonalityFn()->stripPointerCasts());
+ const Function *Per = F.hasPersonalityFn() ? F.getPersonalityFn() : nullptr;
// Emit a personality function even when there are no landing pads
forceEmitPersonality =
@@ -124,8 +122,7 @@ void DwarfCFIException::beginBasicBlockSection(const
MachineBasicBlock &MBB) {
return;
auto &F = MBB.getParent()->getFunction();
- auto *P = dyn_cast<GlobalValue>(F.getPersonalityFn()->stripPointerCasts());
- assert(P && "Expected personality function");
+ Function *P = F.getPersonalityFn();
// Record the personality function.
addPersonality(P);
diff --git a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
index 13fd270ec7410..372e14166d494 100644
--- a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
@@ -77,7 +77,7 @@ void WinException::beginFunction(const MachineFunction *MF) {
EHPersonality Per = EHPersonality::Unknown;
const Function *PerFn = nullptr;
if (F.hasPersonalityFn()) {
- PerFn = dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts());
+ PerFn = F.getPersonalityFn();
Per = classifyEHPersonality(PerFn);
}
@@ -128,7 +128,7 @@ void WinException::endFunction(const MachineFunction *MF) {
const Function &F = MF->getFunction();
EHPersonality Per = EHPersonality::Unknown;
if (F.hasPersonalityFn())
- Per = classifyEHPersonality(F.getPersonalityFn()->stripPointerCasts());
+ Per = classifyEHPersonality(F.getPersonalityFn());
endFuncletImpl();
@@ -223,7 +223,7 @@ void WinException::beginFunclet(const MachineBasicBlock
&MBB,
// Determine which personality routine we are using for this funclet.
if (F.hasPersonalityFn())
- PerFn ...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/176952
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits