Skip to content

Conversation

@arsenm
Copy link
Contributor

@arsenm arsenm commented Nov 7, 2025

These are floating-point functions recorded in TargetLibraryInfo,
but missing from RuntimeLibcalls.

@llvmbot
Copy link
Member

llvmbot commented Nov 7, 2025

@llvm/pr-subscribers-llvm-transforms
@llvm/pr-subscribers-llvm-selectiondag

@llvm/pr-subscribers-llvm-ir

Author: Matt Arsenault (arsenm)

Changes

These are floating-point functions recorded in TargetLibraryInfo,
but missing from RuntimeLibcalls.


Full diff: https://github.com/llvm/llvm-project/pull/167049.diff

2 Files Affected:

  • (modified) llvm/include/llvm/IR/RuntimeLibcalls.td (+40)
  • (modified) llvm/test/Transforms/Util/DeclareRuntimeLibcalls/basic.ll (+32)
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td b/llvm/include/llvm/IR/RuntimeLibcalls.td
index 54d67249c3c1c..6186e0bf21895 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.td
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.td
@@ -149,6 +149,8 @@ foreach FPTy = ["F32", "F64", "F80", "F128", "PPCF128"] in {
   def ATAN_#FPTy : RuntimeLibcall;
   def ATAN2_#FPTy : RuntimeLibcall;
   def SINCOS_#FPTy : RuntimeLibcall;
+  def REMQUO_#FPTy : RuntimeLibcall;
+  def FDIM_#FPTy : RuntimeLibcall;
 }
 
 foreach FPTy = [ "F32", "F64" ] in {
@@ -180,6 +182,12 @@ foreach FPTy = ["F32", "F64", "F80", "F128", "PPCF128"] in {
   def FREXP_#FPTy : RuntimeLibcall;
   def SINCOSPI_#FPTy : RuntimeLibcall;
   def MODF_#FPTy : RuntimeLibcall;
+  def NAN_#FPTy : RuntimeLibcall;
+  def NEXTTOWARD_#FPTy : RuntimeLibcall;
+  def REMAINDER_#FPTy : RuntimeLibcall;
+  def SCALBLN_#FPTy : RuntimeLibcall;
+  def SCALBN_#FPTy : RuntimeLibcall;
+  def TGAMMA_#FPTy : RuntimeLibcall;
 }
 
 defvar F32VectorSuffixes = ["V2F32", "V4F32", "V8F32", "V16F32", "NXV2F32",
@@ -1035,6 +1043,38 @@ def modff : RuntimeLibcallImpl<MODF_F32>;
 def modf : RuntimeLibcallImpl<MODF_F64>;
 defm modfl : LibmLongDoubleLibCall;
 
+def nanf : RuntimeLibcallImpl<NAN_F32>;
+def nan : RuntimeLibcallImpl<NAN_F64>;
+defm nanl : LibmLongDoubleLibCall;
+
+def nexttowardf : RuntimeLibcallImpl<NEXTTOWARD_F32>;
+def nexttoward : RuntimeLibcallImpl<NEXTTOWARD_F64>;
+defm nexttowardl : LibmLongDoubleLibCall;
+
+def remainderf : RuntimeLibcallImpl<REMAINDER_F32>;
+def remainder : RuntimeLibcallImpl<REMAINDER_F64>;
+defm remainderl : LibmLongDoubleLibCall;
+
+def remquof : RuntimeLibcallImpl<REMQUO_F32>;
+def remquo : RuntimeLibcallImpl<REMQUO_F64>;
+defm remquol : LibmLongDoubleLibCall;
+
+def fdimf : RuntimeLibcallImpl<FDIM_F32>;
+def fdim : RuntimeLibcallImpl<FDIM_F64>;
+defm fdiml : LibmLongDoubleLibCall;
+
+def scalbnf : RuntimeLibcallImpl<SCALBN_F32>;
+def scalbn : RuntimeLibcallImpl<SCALBN_F64>;
+defm scalbnl : LibmLongDoubleLibCall;
+
+def scalblnf : RuntimeLibcallImpl<SCALBLN_F32>;
+def scalbln : RuntimeLibcallImpl<SCALBLN_F64>;
+defm scalblnl : LibmLongDoubleLibCall;
+
+def tgammaf : RuntimeLibcallImpl<TGAMMA_F32>;
+def tgamma : RuntimeLibcallImpl<TGAMMA_F64>;
+defm tgammal : LibmLongDoubleLibCall;
+
 // Floating point environment
 def fegetenv : RuntimeLibcallImpl<FEGETENV>;
 def fesetenv : RuntimeLibcallImpl<FESETENV>;
diff --git a/llvm/test/Transforms/Util/DeclareRuntimeLibcalls/basic.ll b/llvm/test/Transforms/Util/DeclareRuntimeLibcalls/basic.ll
index 4c8c829a59f3c..be8cae261c7bf 100644
--- a/llvm/test/Transforms/Util/DeclareRuntimeLibcalls/basic.ll
+++ b/llvm/test/Transforms/Util/DeclareRuntimeLibcalls/basic.ll
@@ -16,9 +16,41 @@ define float @sinf(float %x) {
 
 ; CHECK: declare void @acosf(...)
 
+; CHECK: declare void @fdim(...)
+; CHECK: declare void @fdimf(...)
+; CHECK: declare void @fdiml(...)
+
+; CHECK: declare void @nan(...)
+; CHECK: declare void @nanf(...)
+; CHECK: declare void @nanl(...)
+
+; CHECK: declare void @nexttoward(...)
+; CHECK: declare void @nexttowardf(...)
+; CHECK: declare void @nexttowardl(...)
+
+; CHECK: declare void @remainder(...)
+; CHECK: declare void @remainderf(...)
+; CHECK: declare void @remainderl(...)
+
+; CHECK: declare void @remquo(...)
+; CHECK: declare void @remquof(...)
+; CHECK: declare void @remquol(...)
+
+; CHECK: declare void @scalbln(...)
+; CHECK: declare void @scalblnf(...)
+; CHECK: declare void @scalblnl(...)
+
+; CHECK: declare void @scalbn(...)
+; CHECK: declare void @scalbnf(...)
+; CHECK: declare void @scalbnl(...)
+
 ; CHECK: declare nofpclass(ninf nsub nnorm) double @sqrt(double) [[SQRT_ATTRS:#[0-9]+]]
 
 ; CHECK: declare nofpclass(ninf nsub nnorm) float @sqrtf(float) [[SQRT_ATTRS:#[0-9]+]]
 
+; CHECK: declare void @tgamma(...)
+; CHECK: declare void @tgammaf(...)
+; CHECK: declare void @tgammal(...)
+
 ; CHECK: declare void @truncl(...)
 

Copy link
Contributor Author

arsenm commented Nov 7, 2025

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more

This stack of pull requests is managed by Graphite. Learn more about stacking.

@arsenm arsenm force-pushed the users/arsenm/runtime-libcalls/add-vector-library-functions branch from 9cb5465 to b983fd3 Compare November 10, 2025 18:18
@arsenm arsenm force-pushed the users/arsenm/runtime-libcalls/add-libm-functions-from-targetlibraryinfo branch from 8ddc3c6 to ae48224 Compare November 10, 2025 18:18
@arsenm arsenm force-pushed the users/arsenm/runtime-libcalls/add-vector-library-functions branch from b983fd3 to b6e6f8d Compare November 10, 2025 19:22
@arsenm arsenm force-pushed the users/arsenm/runtime-libcalls/add-libm-functions-from-targetlibraryinfo branch from ae48224 to 5a3c882 Compare November 10, 2025 19:22
Copy link
Collaborator

@efriedma-quic efriedma-quic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding the symbols, even if we don't do anything else, has an immediate impact, I think? Anything we add to RuntimeLibcalls gets added to LTO::getRuntimeLibcallSymbols. I don't really want to extend getRuntimeLibcallSymbols with symbols that might not actually be relevant, at least until we work out how we want to handle such symbols.

There's a historical distinction here: RuntimeLibcalls only had calls generated by the LLVM backend, and TargetLibraryInfo had calls generated by IR-level optimizations. And I think there are still good reasons to distinguish... at least, between functions which can be disabled with no-builtin attributes, and functions which can't be disabled because the backend generates them unconditionally.

@arsenm
Copy link
Contributor Author

arsenm commented Nov 11, 2025

Adding the symbols, even if we don't do anything else, has an immediate impact, I think? Anything we add to RuntimeLibcalls gets added to LTO::getRuntimeLibcallSymbols. I don't really want to extend getRuntimeLibcallSymbols with symbols that might not actually be relevant, at least until we work out how we want to handle such symbols.

Yes, that's a top reason to include these here.

There's a historical distinction here: RuntimeLibcalls only had calls generated by the LLVM backend, and TargetLibraryInfo had calls generated by IR-level optimizations.

I don't see a semantic distinction between "IR optimization" and "LLVM backend". getRuntimeLibcallSymbols needs to know all possible symbols the compiler may emit, regardless of where.

And I think there are still good reasons to distinguish... at least, between functions which can be disabled with no-builtin attributes, and functions which can't be disabled because the backend generates them unconditionally.

I do think it's worthwhile to distinguish calls which are recognized vs. calls which could be emitted, but the status quo is these are not well distinguished. The TargetLibraryInfo functions aren't necessarily all introduced. Some are merely recognized.

Eventually I want to have RuntimeLibcalls directly distinguish symbols that may be emitted and those that are recognized. But for now I think it's far better to err on the side of including everything towards the eventual merger

@efriedma-quic
Copy link
Collaborator

I do think it's worthwhile to distinguish calls which are recognized vs. calls which could be emitted

That's not the only distinction here. Some functions are only recognized, some functions are emitted unless you have an appropriate "no-builtins" attribute, and some functions are emitted no matter what attributes you use.

Yes, that's a top reason to include these here.

My concern is that stuff ends up getting pulled into the link which would actually never be used, which could cause breakage. Particularly for embedded users building with -fno-builtins, where these functions aren't relevant. And if there is breakage, we probably won't hear about it for a while; there are very few embedded users closely tracking main.

Eventually we probably want to reach a state where we can compute a conservative list of libcalls pre-LTO on a per-object-file basis... and then we can stop worrying about what exactly is and is not included in LTO::getRuntimeLibcallSymbols. But until we reach that point, we need to be careful.

@arsenm arsenm force-pushed the users/arsenm/runtime-libcalls/add-libm-functions-from-targetlibraryinfo branch from 5a3c882 to dc9eae3 Compare November 12, 2025 00:57
@arsenm arsenm force-pushed the users/arsenm/runtime-libcalls/add-vector-library-functions branch from b6e6f8d to 0aaa77d Compare November 12, 2025 00:57
@arsenm arsenm force-pushed the users/arsenm/runtime-libcalls/add-libm-functions-from-targetlibraryinfo branch from dc9eae3 to cf7c5ea Compare November 12, 2025 02:11
@arsenm arsenm force-pushed the users/arsenm/runtime-libcalls/add-vector-library-functions branch from 0aaa77d to 691fac5 Compare November 12, 2025 02:11
These are floating-point functions recorded in TargetLibraryInfo,
but missing from RuntimeLibcalls.
@arsenm arsenm force-pushed the users/arsenm/runtime-libcalls/add-libm-functions-from-targetlibraryinfo branch from cf7c5ea to 57b5e69 Compare November 12, 2025 03:24
@arsenm arsenm force-pushed the users/arsenm/runtime-libcalls/add-vector-library-functions branch from 691fac5 to 4a7df0a Compare November 12, 2025 03:24
@arsenm
Copy link
Contributor Author

arsenm commented Nov 12, 2025

My concern is that stuff ends up getting pulled into the link which would actually never be used, which could cause breakage.

The real problem now is the opposite; not retaining calls which will be used.

Eventually we probably want to reach a state where we can compute a conservative list of libcalls pre-LTO on a per-object-file basis... and then we can stop worrying about what exactly is and is not included in LTO::getRuntimeLibcallSymbols. But until we reach that point, we need to be careful.

The conservative direction is to assume a function will be needed, not that it won't be (i.e., we should conservatively be listing every possible call). Dropping something which was there is the optional optimization.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants