Skip to content

[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

Merged
merged 2 commits into from
Jul 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -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.">,
Copy link
Contributor

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?

Copy link
Contributor

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.

Copy link
Collaborator

@paulwalker-arm paulwalker-arm Jul 1, 2025

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.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, a user will see a link-time error message if older glibc is used. This is same as Clang.

$ flang -O2 -fveclib=libmvec test.f90
/usr/bin/ld: /tmp/test-d377a8.o: in function `_QQmain':
FIRModule:(.text+0xd4): undefined reference to `_ZGVnN4vv_powf'
flang-21: error: linker command failed with exit code 1 (use -v to see invocation)

Please see https://github.com/bminor/glibc/blob/96abd59bf2a11ddd4e7ccaac840ec13c0b62d3ba/sysdeps/aarch64/fpu/Versions for math function v.s. required glibc version. Currently, math functions introduced in glibc > 2.40 are not used in -fveclib=libmvec.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thank you for the clarification

HelpTextForVariants<[ClangOption, CC1Option],
"Use the given vector functions library.\n"
" Note: -fveclib={ArmPL,SLEEF,libmvec} implies -fno-math-errno.\n"
Expand Down
9 changes: 8 additions & 1 deletion clang/lib/Driver/ToolChains/Flang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions flang/docs/ReleaseNotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ 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) (requires GLIBC 2.40 or newer)

## Windows Support

Expand Down
4 changes: 4 additions & 0 deletions flang/test/Driver/fveclib-codegen.f90
Original file line number Diff line number Diff line change
@@ -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

Expand All @@ -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)
Expand Down
3 changes: 2 additions & 1 deletion flang/test/Driver/fveclib.f90
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
Expand Down