Skip to content

[flang] fix flang builds with clang 20 after #100692 #106718

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 30, 2024

Conversation

jeanPerier
Copy link
Contributor

#100692 changes clang template deduction, and an error was now emitted when building flang with top of the tree clang when mapping std::pow in intrinsics-library.cpp for constant folding error: address of overloaded function 'pow' is ambiguous

See https://lab.llvm.org/buildbot/#/builders/4/builds/1670

I I am not expert enough to understand if the new error is justified or not here, but it is easy to help the compiler here with explicit wrappers to fix the builds.

@llvmbot llvmbot added flang Flang issues not falling into any other category flang:semantics labels Aug 30, 2024
@llvmbot
Copy link
Member

llvmbot commented Aug 30, 2024

@llvm/pr-subscribers-flang-semantics

Author: None (jeanPerier)

Changes

#100692 changes clang template deduction, and an error was now emitted when building flang with top of the tree clang when mapping std::pow in intrinsics-library.cpp for constant folding error: address of overloaded function 'pow' is ambiguous

See https://lab.llvm.org/buildbot/#/builders/4/builds/1670

I I am not expert enough to understand if the new error is justified or not here, but it is easy to help the compiler here with explicit wrappers to fix the builds.


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

1 Files Affected:

  • (modified) flang/lib/Evaluate/intrinsics-library.cpp (+22-3)
diff --git a/flang/lib/Evaluate/intrinsics-library.cpp b/flang/lib/Evaluate/intrinsics-library.cpp
index 65636b9956e780..ed28d8130808fa 100644
--- a/flang/lib/Evaluate/intrinsics-library.cpp
+++ b/flang/lib/Evaluate/intrinsics-library.cpp
@@ -255,6 +255,25 @@ struct HostRuntimeLibrary<HostT, LibraryVersion::Libm> {
   static constexpr HostRuntimeMap map{table};
   static_assert(map.Verify(), "map must be sorted");
 };
+
+// Helpers to map complex std::pow whose resolution in F2{std::pow} is
+// ambiguous as of clang++ 20.
+template <typename HostT>
+static std::complex<HostT> StdPowF2(
+    const std::complex<HostT> &x, const std::complex<HostT> &y) {
+  return std::pow(x, y);
+}
+template <typename HostT>
+static std::complex<HostT> StdPowF2A(
+    const HostT &x, const std::complex<HostT> &y) {
+  return std::pow(x, y);
+}
+template <typename HostT>
+static std::complex<HostT> StdPowF2B(
+    const std::complex<HostT> &x, const HostT &y) {
+  return std::pow(x, y);
+}
+
 template <typename HostT>
 struct HostRuntimeLibrary<std::complex<HostT>, LibraryVersion::Libm> {
   using F = FuncPointer<std::complex<HostT>, const std::complex<HostT> &>;
@@ -275,9 +294,9 @@ struct HostRuntimeLibrary<std::complex<HostT>, LibraryVersion::Libm> {
       FolderFactory<F, F{std::cosh}>::Create("cosh"),
       FolderFactory<F, F{std::exp}>::Create("exp"),
       FolderFactory<F, F{std::log}>::Create("log"),
-      FolderFactory<F2, F2{std::pow}>::Create("pow"),
-      FolderFactory<F2A, F2A{std::pow}>::Create("pow"),
-      FolderFactory<F2B, F2B{std::pow}>::Create("pow"),
+      FolderFactory<F2, F2{StdPowF2}>::Create("pow"),
+      FolderFactory<F2A, F2A{StdPowF2A}>::Create("pow"),
+      FolderFactory<F2B, F2B{StdPowF2B}>::Create("pow"),
       FolderFactory<F, F{std::sin}>::Create("sin"),
       FolderFactory<F, F{std::sinh}>::Create("sinh"),
       FolderFactory<F, F{std::sqrt}>::Create("sqrt"),

@tblah
Copy link
Contributor

tblah commented Aug 30, 2024

What is special about std::pow here? Is this because it has two arguments?

@jeanPerier
Copy link
Contributor Author

What is special about std::pow here? Is this because it has two arguments?

Yes, and it has three overloads: pow(complex<T>, complex<T>), pow(T, complex<T>), and pow(complex<T>, T) while other complex intrinsic only have complex<T> arguments.

I am trying to send a reproducer to the clang dev, but I think we should fix the builds (they have been broken for two days now).

Copy link
Member

@DavidTruby DavidTruby left a comment

Choose a reason for hiding this comment

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

I think the change looks fine to fix the bots, but I don't see anything wrong with the existing code myself.
At a glance I suspect we're hitting some ordering issue between overloads 1-4 and A-C as listed here: https://en.cppreference.com/w/cpp/numeric/complex/pow
I'm not even clear whether 1-4 should be considered more specialised than A-C here, but I feel that they should be!

I agree you should go ahead and merge this to make the bots green again while we find out more though.

@jeanPerier jeanPerier merged commit 4a10b4c into llvm:main Aug 30, 2024
11 checks passed
@jeanPerier jeanPerier deleted the fix-pow-issue-clang20 branch August 30, 2024 13:43
@jeanPerier
Copy link
Contributor Author

Thanks @DavidTruby, I reported the issue in the clang patch with a reproducer.

I also think the C++ compiler should be able to resolve it since it is given the expected function type (after all, it is able to resolve it in call, and we are giving it more info here).

@DavidTruby
Copy link
Member

I agree it should be resolvable, but I think what's happening is after resolving all the templates:

template< class T >
std::complex<T> pow( const std::complex<T>& x, const std::complex<T>& y );

and

template< class T1, class T2 >
std::complex<std::common_type_t<T1, T2>>
    pow( const std::complex<T1>& x, const std::complex<T2>& y );

have the same type, since std::common_type_t<T, T> == T. I might be wrong and the issue is somewhere else though!

@DavidTruby
Copy link
Member

We could revert this now as this has been fixed in clang. It has been pointed out to me though that taking the address of most functions in std:: is actually undefined; I doubt any compiler would enforce this but it's technically the case for some reason.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flang:semantics flang Flang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants