[llvm] c6e16a4 - [TLI] Add support for inferring attr `cold`/`noreturn` on `std::terminate` and `__cxa_throw`
Noah Goldstein via llvm-commits
llvm-commits at lists.llvm.org
Sun Aug 18 15:38:14 PDT 2024
Author: Noah Goldstein
Date: 2024-08-18T15:37:56-07:00
New Revision: c6e16a49ef41261b01aabc27f4b806af6cc81a20
URL: https://github.com/llvm/llvm-project/commit/c6e16a49ef41261b01aabc27f4b806af6cc81a20
DIFF: https://github.com/llvm/llvm-project/commit/c6e16a49ef41261b01aabc27f4b806af6cc81a20.diff
LOG: [TLI] Add support for inferring attr `cold`/`noreturn` on `std::terminate` and `__cxa_throw`
These functions are both inherently on the error path so `cold` seems
appropriate. `noreturn` is definitional.
Closes #101622
Added:
Modified:
llvm/include/llvm/Analysis/TargetLibraryInfo.def
llvm/lib/Transforms/Utils/BuildLibCalls.cpp
llvm/test/Transforms/InferFunctionAttrs/annotate.ll
llvm/test/tools/llvm-tli-checker/ps4-tli-check.yaml
llvm/unittests/Analysis/TargetLibraryInfoTest.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/Analysis/TargetLibraryInfo.def b/llvm/include/llvm/Analysis/TargetLibraryInfo.def
index e1cb1e5c557eae..5914324b286c05 100644
--- a/llvm/include/llvm/Analysis/TargetLibraryInfo.def
+++ b/llvm/include/llvm/Analysis/TargetLibraryInfo.def
@@ -517,6 +517,16 @@ TLI_DEFINE_ENUM_INTERNAL(Exit)
TLI_DEFINE_STRING_INTERNAL("_Exit")
TLI_DEFINE_SIG_INTERNAL(Void, Int)
+/// void std::terminate();
+TLI_DEFINE_ENUM_INTERNAL(terminate)
+TLI_DEFINE_STRING_INTERNAL("_ZSt9terminatev")
+TLI_DEFINE_SIG_INTERNAL(Void)
+
+/// void __cxa_throw(void *, void *, void (*)(void *));
+TLI_DEFINE_ENUM_INTERNAL(cxa_throw)
+TLI_DEFINE_STRING_INTERNAL("__cxa_throw")
+TLI_DEFINE_SIG_INTERNAL(Void, Ptr, Ptr, Ptr)
+
/// void __cxa_guard_abort(guard_t *guard);
/// guard_t is int64_t in Itanium ABI or int32_t on ARM eabi.
TLI_DEFINE_ENUM_INTERNAL(cxa_guard_abort)
diff --git a/llvm/lib/Transforms/Utils/BuildLibCalls.cpp b/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
index c23d53f7111d21..b0da19813f0a4b 100644
--- a/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
@@ -50,6 +50,7 @@ STATISTIC(NumNoUndef, "Number of function returns inferred as noundef returns");
STATISTIC(NumReturnedArg, "Number of arguments inferred as returned");
STATISTIC(NumWillReturn, "Number of functions inferred as willreturn");
STATISTIC(NumCold, "Number of functions inferred as cold");
+STATISTIC(NumNoReturn, "Number of functions inferred as no return");
static bool setDoesNotAccessMemory(Function &F) {
if (F.doesNotAccessMemory())
@@ -67,6 +68,14 @@ static bool setIsCold(Function &F) {
return true;
}
+static bool setNoReturn(Function &F) {
+ if (F.hasFnAttribute(Attribute::NoReturn))
+ return false;
+ F.addFnAttr(Attribute::NoReturn);
+ ++NumNoReturn;
+ return true;
+}
+
static bool setOnlyAccessesInaccessibleMemory(Function &F) {
if (F.onlyAccessesInaccessibleMemory())
return false;
@@ -1103,6 +1112,15 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
case LibFunc_abort:
Changed |= setIsCold(F);
break;
+ case LibFunc_terminate:
+ Changed |= setIsCold(F);
+ Changed |= setNoReturn(F);
+ break;
+ case LibFunc_cxa_throw:
+ Changed |= setIsCold(F);
+ Changed |= setNoReturn(F);
+ // Don't add `nofree` on `__cxa_throw`
+ return Changed;
// int __nvvm_reflect(const char *)
case LibFunc_nvvm_reflect:
Changed |= setRetAndArgsNoUndef(F);
diff --git a/llvm/test/Transforms/InferFunctionAttrs/annotate.ll b/llvm/test/Transforms/InferFunctionAttrs/annotate.ll
index 3b914dc29ca41c..bc0d7a509e1f5d 100644
--- a/llvm/test/Transforms/InferFunctionAttrs/annotate.ll
+++ b/llvm/test/Transforms/InferFunctionAttrs/annotate.ll
@@ -1100,6 +1100,12 @@ declare i64 @write(i32, ptr, i64)
; CHECK: declare void @abort() [[NOFREE_COLD:#[0-9]+]]
declare void @abort()
+; CHECK: declare void @__cxa_throw(ptr, ptr, ptr) [[COLD_NORETURN:#[0-9]+]]
+declare void @__cxa_throw(ptr, ptr, ptr)
+
+; CHECK: declare void @_ZSt9terminatev() [[NOFREE_COLD_NORETURN:#[0-9]+]]
+declare void @_ZSt9terminatev()
+
; memset_pattern{4,8,16} aren't available everywhere.
; CHECK-DARWIN: declare void @memset_pattern4(ptr nocapture writeonly, ptr nocapture readonly, i64) [[ARGMEMONLY_NOFREE_NOUNWIND_WILLRETURN]]
declare void @memset_pattern4(ptr, ptr, i64)
@@ -1126,6 +1132,8 @@ declare void @memset_pattern16(ptr, ptr, i64)
; CHECK-DAG: attributes [[INACCESSIBLEMEMORARGMEMONLY_NOUNWIND_WILLRETURN_ALLOCKIND_REALLOC_ALLOCSIZE1_FAMILY_MALLOC]] = { mustprogress nounwind willreturn allockind("realloc") allocsize(1) memory(argmem: readwrite, inaccessiblemem: readwrite) "alloc-family"="malloc" }
; CHECK-DAG: attributes [[INACCESSIBLEMEMORARGONLY_NOFREE_NOUNWIND_WILLRETURN_FAMILY_MALLOC]] = { mustprogress nofree nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) "alloc-family"="malloc" }
; CHECK-DAG: attributes [[NOFREE_COLD]] = { cold nofree }
+; CHECK-DAG: attributes [[NOFREE_COLD_NORETURN]] = { cold nofree noreturn }
+; CHECK-DAG: attributes [[COLD_NORETURN]] = { cold noreturn }
; CHECK-NVPTX-DAG: attributes [[NOFREE_NOUNWIND_READNONE]] = { nofree nosync nounwind memory(none) }
diff --git a/llvm/test/tools/llvm-tli-checker/ps4-tli-check.yaml b/llvm/test/tools/llvm-tli-checker/ps4-tli-check.yaml
index cff5019f8e6ee4..47aeb0ad8fdef9 100644
--- a/llvm/test/tools/llvm-tli-checker/ps4-tli-check.yaml
+++ b/llvm/test/tools/llvm-tli-checker/ps4-tli-check.yaml
@@ -34,7 +34,7 @@
#
# CHECK: << Total TLI yes SDK no: 18
# CHECK: >> Total TLI no SDK yes: 0
-# CHECK: == Total TLI yes SDK yes: 248
+# CHECK: == Total TLI yes SDK yes: 250
#
# WRONG_DETAIL: << TLI yes SDK no : '_ZdaPv' aka operator delete[](void*)
# WRONG_DETAIL: >> TLI no SDK yes: '_ZdaPvj' aka operator delete[](void*, unsigned int)
@@ -48,14 +48,14 @@
# WRONG_DETAIL: << TLI yes SDK no : 'fminimum_numl'
# WRONG_SUMMARY: << Total TLI yes SDK no: 19{{$}}
# WRONG_SUMMARY: >> Total TLI no SDK yes: 1{{$}}
-# WRONG_SUMMARY: == Total TLI yes SDK yes: 247
+# WRONG_SUMMARY: == Total TLI yes SDK yes: 249
#
## The -COUNT suffix doesn't care if there are too many matches, so check
## the exact count first; the two directives should add up to that.
## Yes, this means additions to TLI will fail this test, but the argument
## to -COUNT can't be an expression.
-# AVAIL: TLI knows 499 symbols, 266 available
-# AVAIL-COUNT-266: {{^}} available
+# AVAIL: TLI knows 501 symbols, 268 available
+# AVAIL-COUNT-268: {{^}} available
# AVAIL-NOT: {{^}} available
# UNAVAIL-COUNT-233: not available
# UNAVAIL-NOT: not available
@@ -174,6 +174,10 @@ DynamicSymbols:
Type: STT_FUNC
Section: .text
Binding: STB_GLOBAL
+ - Name: __cxa_throw
+ Type: STT_FUNC
+ Section: .text
+ Binding: STB_GLOBAL
- Name: __cxa_guard_release
Type: STT_FUNC
Section: .text
@@ -286,6 +290,10 @@ DynamicSymbols:
Type: STT_FUNC
Section: .text
Binding: STB_GLOBAL
+ - Name: _ZSt9terminatev
+ Type: STT_FUNC
+ Section: .text
+ Binding: STB_GLOBAL
- Name: atof
Type: STT_FUNC
Section: .text
diff --git a/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp b/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp
index ff7dec5bee31df..abaedf9c210b8c 100644
--- a/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp
+++ b/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp
@@ -535,12 +535,14 @@ TEST_F(TargetLibraryInfoTest, ValidProto) {
"declare void @__cxa_guard_abort(%struct*)\n"
"declare i32 @__cxa_guard_acquire(%struct*)\n"
"declare void @__cxa_guard_release(%struct*)\n"
+ "declare void @__cxa_throw(ptr, ptr, ptr)\n"
"declare i32 @atexit(void ()*)\n"
"declare void @abort()\n"
"declare void @exit(i32)\n"
"declare void @_Exit(i32)\n"
+ "declare void @_ZSt9terminatev()\n"
"declare i32 @__nvvm_reflect(i8*)\n"
More information about the llvm-commits
mailing list