-
Notifications
You must be signed in to change notification settings - Fork 14.4k
[Flang][AArch64][VecLib] Add libmvec support for Flang/AArch64 #146453
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
base: main
Are you sure you want to change the base?
[Flang][AArch64][VecLib] Add libmvec support for Flang/AArch64 #146453
Conversation
`-fveclib=libmvec` for AArch64 (NEON and SVE) in Clang was supported by llvm#143696. This patch does the same for Flang. Vector functions defined in `libmvec` are used for the following Fortran operator and functions currently. - Power operator (`**`) - Fortran intrinsic functions listed below for `real(kind=4)` and `real(kind=8)` (including their coresponding specific intrinsic functions) - Fortran intrinsic functions which are expanded using functions listed below (for example, `sin` for `complex(kind=8)`) ``` sin tan cos asin acos atan (both atan(x) and atan(y, x)) atan2 cosh tanh asinh acosh atanh erf erfc exp log log10 ``` As with Clang/AArch64, glibc 2.40 or higher is required to use all these functions.
@llvm/pr-subscribers-clang-driver @llvm/pr-subscribers-backend-aarch64 Author: KAWASHIMA Takahiro (kawashima-fj) Changes
Vector functions defined in
As with Clang/AArch64, glibc 2.40 or higher is required to use all these functions. Full diff: https://github.com/llvm/llvm-project/pull/146453.diff 4 Files Affected:
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp
index e4e321ba1e195..75ba2af543c7a 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -484,11 +484,18 @@ void Flang::addTargetOptions(const ArgList &Args,
Triple.getArch() != llvm::Triple::x86_64)
D.Diag(diag::err_drv_unsupported_opt_for_target)
<< Name << Triple.getArchName();
- } else if (Name == "libmvec" || Name == "AMDLIBM") {
+ } else if (Name == "AMDLIBM") {
if (Triple.getArch() != llvm::Triple::x86 &&
Triple.getArch() != llvm::Triple::x86_64)
D.Diag(diag::err_drv_unsupported_opt_for_target)
<< Name << Triple.getArchName();
+ } else if (Name == "libmvec") {
+ if (Triple.getArch() != llvm::Triple::x86 &&
+ Triple.getArch() != llvm::Triple::x86_64 &&
+ Triple.getArch() != llvm::Triple::aarch64 &&
+ Triple.getArch() != llvm::Triple::aarch64_be)
+ D.Diag(diag::err_drv_unsupported_opt_for_target)
+ << Name << Triple.getArchName();
} else if (Name == "SLEEF" || Name == "ArmPL") {
if (Triple.getArch() != llvm::Triple::aarch64 &&
Triple.getArch() != llvm::Triple::aarch64_be)
diff --git a/flang/docs/ReleaseNotes.md b/flang/docs/ReleaseNotes.md
index 35da8323e0a10..bd3a215323de2 100644
--- a/flang/docs/ReleaseNotes.md
+++ b/flang/docs/ReleaseNotes.md
@@ -34,6 +34,7 @@ page](https://llvm.org/releases/).
* -floop-interchange is now recognized by flang.
* -floop-interchange is enabled by default at -O2 and above.
+* -fveclib=libmvec is supported for AArch64 (same as Flang/x86 and Clang/AArch64)
## Windows Support
diff --git a/flang/test/Driver/fveclib-codegen.f90 b/flang/test/Driver/fveclib-codegen.f90
index 4cbb1e284f18e..88b31da40167e 100644
--- a/flang/test/Driver/fveclib-codegen.f90
+++ b/flang/test/Driver/fveclib-codegen.f90
@@ -1,6 +1,8 @@
! test that -fveclib= is passed to the backend
! RUN: %if aarch64-registered-target %{ %flang -S -Ofast -target aarch64-unknown-linux-gnu -fveclib=SLEEF -o - %s | FileCheck %s --check-prefix=SLEEF %}
! RUN: %if x86-registered-target %{ %flang -S -Ofast -target x86_64-unknown-linux-gnu -fveclib=libmvec -o - %s | FileCheck %s %}
+! RUN: %if aarch64-registered-target %{ %flang -S -Ofast -target aarch64-unknown-linux-gnu -fveclib=libmvec -march=armv8.2-a+nosve -o - %s | FileCheck %s --check-prefix=LIBMVEC-AARCH64-NEON %}
+! RUN: %if aarch64-registered-target %{ %flang -S -Ofast -target aarch64-unknown-linux-gnu -fveclib=libmvec -march=armv8.2-a+sve -o - %s | FileCheck %s --check-prefix=LIBMVEC-AARCH64-SVE %}
! RUN: %if x86-registered-target %{ %flang -S -O3 -ffast-math -target x86_64-unknown-linux-gnu -fveclib=AMDLIBM -o - %s | FileCheck %s --check-prefix=AMDLIBM %}
! RUN: %flang -S -Ofast -fveclib=NoLibrary -o - %s | FileCheck %s --check-prefix=NOLIB
@@ -11,6 +13,8 @@ subroutine sb(a, b)
! check that we used a vectorized call to powf()
! CHECK: _ZGVbN4vv_powf
! SLEEF: _ZGVnN4vv_powf
+! LIBMVEC-AARCH64-NEON: _ZGVnN4vv_powf
+! LIBMVEC-AARCH64-SVE: _ZGVsMxvv_powf
! AMDLIBM: amd_vrs4_powf
! NOLIB: powf
a(i) = a(i) ** b(i)
diff --git a/flang/test/Driver/fveclib.f90 b/flang/test/Driver/fveclib.f90
index 431a4bfc02522..d21e85e486f8d 100644
--- a/flang/test/Driver/fveclib.f90
+++ b/flang/test/Driver/fveclib.f90
@@ -1,6 +1,7 @@
! RUN: %flang -### -c -fveclib=none %s 2>&1 | FileCheck -check-prefix CHECK-NOLIB %s
! RUN: %flang -### -c -fveclib=Accelerate %s 2>&1 | FileCheck -check-prefix CHECK-ACCELERATE %s
! RUN: %flang -### -c --target=x86_64-unknown-linux-gnu -fveclib=libmvec %s 2>&1 | FileCheck -check-prefix CHECK-libmvec %s
+! RUN: %flang -### -c --target=aarch64-unknown-linux-gnu -fveclib=libmvec %s 2>&1 | FileCheck -check-prefix CHECK-libmvec %s
! RUN: %flang -### -c -fveclib=MASSV %s 2>&1 | FileCheck -check-prefix CHECK-MASSV %s
! RUN: %flang -### -c -fveclib=Darwin_libsystem_m %s 2>&1 | FileCheck -check-prefix CHECK-DARWIN_LIBSYSTEM_M %s
! RUN: %flang -### -c --target=aarch64-none-none -fveclib=SLEEF %s 2>&1 | FileCheck -check-prefix CHECK-SLEEF %s
@@ -23,7 +24,7 @@
! RUN: not %flang --target=x86-none-none -c -fveclib=SLEEF %s 2>&1 | FileCheck -check-prefix CHECK-ERROR %s
! RUN: not %flang --target=x86-none-none -c -fveclib=ArmPL %s 2>&1 | FileCheck -check-prefix CHECK-ERROR %s
-! RUN: not %flang --target=aarch64-none-none -c -fveclib=libmvec %s 2>&1 | FileCheck -check-prefix CHECK-ERROR %s
+! RUN: not %flang --target=riscv64-none-none -c -fveclib=libmvec %s 2>&1 | FileCheck -check-prefix CHECK-ERROR %s
! RUN: not %flang --target=aarch64-none-none -c -fveclib=SVML %s 2>&1 | FileCheck -check-prefix CHECK-ERROR %s
! RUN: not %flang --target=aarch64-none-none -c -fveclib=AMDLIBM %s 2>&1 | FileCheck -check-prefix CHECK-ERROR %s
! CHECK-ERROR: unsupported option {{.*}} for target
|
@llvm/pr-subscribers-flang-driver Author: KAWASHIMA Takahiro (kawashima-fj) Changes
Vector functions defined in
As with Clang/AArch64, glibc 2.40 or higher is required to use all these functions. Full diff: https://github.com/llvm/llvm-project/pull/146453.diff 4 Files Affected:
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp
index e4e321ba1e195..75ba2af543c7a 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -484,11 +484,18 @@ void Flang::addTargetOptions(const ArgList &Args,
Triple.getArch() != llvm::Triple::x86_64)
D.Diag(diag::err_drv_unsupported_opt_for_target)
<< Name << Triple.getArchName();
- } else if (Name == "libmvec" || Name == "AMDLIBM") {
+ } else if (Name == "AMDLIBM") {
if (Triple.getArch() != llvm::Triple::x86 &&
Triple.getArch() != llvm::Triple::x86_64)
D.Diag(diag::err_drv_unsupported_opt_for_target)
<< Name << Triple.getArchName();
+ } else if (Name == "libmvec") {
+ if (Triple.getArch() != llvm::Triple::x86 &&
+ Triple.getArch() != llvm::Triple::x86_64 &&
+ Triple.getArch() != llvm::Triple::aarch64 &&
+ Triple.getArch() != llvm::Triple::aarch64_be)
+ D.Diag(diag::err_drv_unsupported_opt_for_target)
+ << Name << Triple.getArchName();
} else if (Name == "SLEEF" || Name == "ArmPL") {
if (Triple.getArch() != llvm::Triple::aarch64 &&
Triple.getArch() != llvm::Triple::aarch64_be)
diff --git a/flang/docs/ReleaseNotes.md b/flang/docs/ReleaseNotes.md
index 35da8323e0a10..bd3a215323de2 100644
--- a/flang/docs/ReleaseNotes.md
+++ b/flang/docs/ReleaseNotes.md
@@ -34,6 +34,7 @@ page](https://llvm.org/releases/).
* -floop-interchange is now recognized by flang.
* -floop-interchange is enabled by default at -O2 and above.
+* -fveclib=libmvec is supported for AArch64 (same as Flang/x86 and Clang/AArch64)
## Windows Support
diff --git a/flang/test/Driver/fveclib-codegen.f90 b/flang/test/Driver/fveclib-codegen.f90
index 4cbb1e284f18e..88b31da40167e 100644
--- a/flang/test/Driver/fveclib-codegen.f90
+++ b/flang/test/Driver/fveclib-codegen.f90
@@ -1,6 +1,8 @@
! test that -fveclib= is passed to the backend
! RUN: %if aarch64-registered-target %{ %flang -S -Ofast -target aarch64-unknown-linux-gnu -fveclib=SLEEF -o - %s | FileCheck %s --check-prefix=SLEEF %}
! RUN: %if x86-registered-target %{ %flang -S -Ofast -target x86_64-unknown-linux-gnu -fveclib=libmvec -o - %s | FileCheck %s %}
+! RUN: %if aarch64-registered-target %{ %flang -S -Ofast -target aarch64-unknown-linux-gnu -fveclib=libmvec -march=armv8.2-a+nosve -o - %s | FileCheck %s --check-prefix=LIBMVEC-AARCH64-NEON %}
+! RUN: %if aarch64-registered-target %{ %flang -S -Ofast -target aarch64-unknown-linux-gnu -fveclib=libmvec -march=armv8.2-a+sve -o - %s | FileCheck %s --check-prefix=LIBMVEC-AARCH64-SVE %}
! RUN: %if x86-registered-target %{ %flang -S -O3 -ffast-math -target x86_64-unknown-linux-gnu -fveclib=AMDLIBM -o - %s | FileCheck %s --check-prefix=AMDLIBM %}
! RUN: %flang -S -Ofast -fveclib=NoLibrary -o - %s | FileCheck %s --check-prefix=NOLIB
@@ -11,6 +13,8 @@ subroutine sb(a, b)
! check that we used a vectorized call to powf()
! CHECK: _ZGVbN4vv_powf
! SLEEF: _ZGVnN4vv_powf
+! LIBMVEC-AARCH64-NEON: _ZGVnN4vv_powf
+! LIBMVEC-AARCH64-SVE: _ZGVsMxvv_powf
! AMDLIBM: amd_vrs4_powf
! NOLIB: powf
a(i) = a(i) ** b(i)
diff --git a/flang/test/Driver/fveclib.f90 b/flang/test/Driver/fveclib.f90
index 431a4bfc02522..d21e85e486f8d 100644
--- a/flang/test/Driver/fveclib.f90
+++ b/flang/test/Driver/fveclib.f90
@@ -1,6 +1,7 @@
! RUN: %flang -### -c -fveclib=none %s 2>&1 | FileCheck -check-prefix CHECK-NOLIB %s
! RUN: %flang -### -c -fveclib=Accelerate %s 2>&1 | FileCheck -check-prefix CHECK-ACCELERATE %s
! RUN: %flang -### -c --target=x86_64-unknown-linux-gnu -fveclib=libmvec %s 2>&1 | FileCheck -check-prefix CHECK-libmvec %s
+! RUN: %flang -### -c --target=aarch64-unknown-linux-gnu -fveclib=libmvec %s 2>&1 | FileCheck -check-prefix CHECK-libmvec %s
! RUN: %flang -### -c -fveclib=MASSV %s 2>&1 | FileCheck -check-prefix CHECK-MASSV %s
! RUN: %flang -### -c -fveclib=Darwin_libsystem_m %s 2>&1 | FileCheck -check-prefix CHECK-DARWIN_LIBSYSTEM_M %s
! RUN: %flang -### -c --target=aarch64-none-none -fveclib=SLEEF %s 2>&1 | FileCheck -check-prefix CHECK-SLEEF %s
@@ -23,7 +24,7 @@
! RUN: not %flang --target=x86-none-none -c -fveclib=SLEEF %s 2>&1 | FileCheck -check-prefix CHECK-ERROR %s
! RUN: not %flang --target=x86-none-none -c -fveclib=ArmPL %s 2>&1 | FileCheck -check-prefix CHECK-ERROR %s
-! RUN: not %flang --target=aarch64-none-none -c -fveclib=libmvec %s 2>&1 | FileCheck -check-prefix CHECK-ERROR %s
+! RUN: not %flang --target=riscv64-none-none -c -fveclib=libmvec %s 2>&1 | FileCheck -check-prefix CHECK-ERROR %s
! RUN: not %flang --target=aarch64-none-none -c -fveclib=SVML %s 2>&1 | FileCheck -check-prefix CHECK-ERROR %s
! RUN: not %flang --target=aarch64-none-none -c -fveclib=AMDLIBM %s 2>&1 | FileCheck -check-prefix CHECK-ERROR %s
! CHECK-ERROR: unsupported option {{.*}} for target
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You may also want to change Options.td
. Currently, the note about needing GLIBC 2.40 is only displayed for Clang as it's under HelpTextForVariants<[ClangOption, CC1Option]
:
llvm-project/clang/include/clang/Driver/Options.td
Lines 3491 to 3494 in cb80651
HelpTextForVariants<[ClangOption, CC1Option], | |
"Use the given vector functions library.\n" | |
" Note: -fveclib={ArmPL,SLEEF,libmvec} implies -fno-math-errno.\n" | |
" Note: -fveclib=libmvec on AArch64 requires GLIBC 2.40 or newer.">, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with MacDue's comments. Thank you for contributing this!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! LGTM!
@@ -3487,7 +3487,8 @@ def fno_experimental_isel : Flag<["-"], "fno-experimental-isel">, Group<f_clang_ | |||
Alias<fno_global_isel>; | |||
def fveclib : Joined<["-"], "fveclib=">, Group<f_Group>, | |||
Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>, | |||
HelpText<"Use the given vector functions library">, | |||
HelpText<"Use the given vector functions library.\n" | |||
" Note: -fveclib=libmvec on AArch64 requires GLIBC 2.40 or newer.">, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the constraint on glibc
>=2.40 true for clang
as well? What happens if the user attempts to build with an older glibc
? Will they see a configure-time error or will the build fail?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ach. Please ignore the question about the constraint on glibc. The second question about failure modes with older glibc still holds though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The toolchain user will see a link time failure when trying to resolve a call to a vector math routine. Note: the exact requirement depends on the function in question, but version 2.40 is what was used when deciding which math functions to add mappings for.
-fveclib=libmvec
for AArch64 (NEON and SVE) in Clang was supported by #143696. This patch does the same for Flang.Vector functions defined in
libmvec
are used for the following Fortran operator and functions currently.**
)real(kind=4)
andreal(kind=8)
(including their coresponding specific intrinsic functions)sin
forcomplex(kind=8)
)As with Clang/AArch64, glibc 2.40 or higher is required to use all these functions.