Skip to content

[clang][driver] Fix -fveclib=ArmPL issue: with -nostdlib do not link against libm #133578

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
Mar 31, 2025

Conversation

pawosm-arm
Copy link
Contributor

Although combining -fveclib=ArmPL with -nostdlib is a rare situation, it should still be supported correctly and should effect in avoidance of linking against libm.

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' flang:driver flang Flang issues not falling into any other category labels Mar 29, 2025
@llvmbot
Copy link
Member

llvmbot commented Mar 29, 2025

@llvm/pr-subscribers-clang-driver

@llvm/pr-subscribers-clang

Author: Paul Osmialowski (pawosm-arm)

Changes

Although combining -fveclib=ArmPL with -nostdlib is a rare situation, it should still be supported correctly and should effect in avoidance of linking against libm.


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

3 Files Affected:

  • (modified) clang/lib/Driver/ToolChains/CommonArgs.cpp (+5-3)
  • (modified) clang/test/Driver/fveclib.c (+6)
  • (modified) flang/test/Driver/fveclib.f90 (+6)
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 41cfa3d2e4f8c..5aac20e1cdf44 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -515,7 +515,7 @@ void tools::AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs,
       //
       // 1. On Linux, link only when actually needed.
       //
-      // 2. Prefer libm functions over libamath.
+      // 2. Prefer libm functions over libamath (when no -nostdlib in use).
       //
       // 3. Link against libm to resolve libamath dependencies.
       //
@@ -523,9 +523,11 @@ void tools::AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs,
         CmdArgs.push_back(Args.MakeArgString("--push-state"));
         CmdArgs.push_back(Args.MakeArgString("--as-needed"));
       }
-      CmdArgs.push_back(Args.MakeArgString("-lm"));
+      if (!Args.hasArg(options::OPT_nostdlib))
+        CmdArgs.push_back(Args.MakeArgString("-lm"));
       CmdArgs.push_back(Args.MakeArgString("-lamath"));
-      CmdArgs.push_back(Args.MakeArgString("-lm"));
+      if (!Args.hasArg(options::OPT_nostdlib))
+        CmdArgs.push_back(Args.MakeArgString("-lm"));
       if (Triple.isOSLinux())
         CmdArgs.push_back(Args.MakeArgString("--pop-state"));
       addArchSpecificRPath(TC, Args, CmdArgs);
diff --git a/clang/test/Driver/fveclib.c b/clang/test/Driver/fveclib.c
index 7d0985c4dd4f4..62361f4679cc6 100644
--- a/clang/test/Driver/fveclib.c
+++ b/clang/test/Driver/fveclib.c
@@ -116,11 +116,17 @@
 /// Verify that vectorized routines library is being linked in.
 // RUN: %clang -### --target=aarch64-pc-windows-msvc -fveclib=ArmPL %s 2>&1 | FileCheck --check-prefix=CHECK-LINKING-ARMPL-MSVC %s
 // RUN: %clang -### --target=aarch64-linux-gnu -fveclib=ArmPL %s 2>&1 | FileCheck --check-prefix=CHECK-LINKING-ARMPL-LINUX %s
+// RUN: %clang -### --target=aarch64-linux-gnu -fveclib=ArmPL %s -nostdlib 2>&1 | FileCheck --check-prefix=CHECK-LINKING-ARMPL-NOSTDLIB-LINUX %s
 // RUN: %clang -### --target=aarch64-linux-gnu -fveclib=ArmPL %s -lamath 2>&1 | FileCheck --check-prefix=CHECK-LINKING-AMATH-BEFORE-ARMPL-LINUX %s
 // RUN: %clang -### --target=arm64-apple-darwin -fveclib=ArmPL %s 2>&1 | FileCheck --check-prefix=CHECK-LINKING-ARMPL-DARWIN %s
+// RUN: %clang -### --target=arm64-apple-darwin -fveclib=ArmPL -nostdlib %s 2>&1 | FileCheck --check-prefix=CHECK-LINKING-ARMPL-NOSTDLIB-DARWIN %s
 // RUN: %clang -### --target=arm64-apple-darwin -fveclib=ArmPL %s -lamath 2>&1 | FileCheck --check-prefix=CHECK-LINKING-AMATH-BEFORE-ARMPL-DARWIN %s
 // CHECK-LINKING-ARMPL-LINUX: "--push-state" "--as-needed" "-lm" "-lamath" "-lm" "--pop-state"
+// CHECK-LINKING-ARMPL-NOSTDLIB-LINUX: "--push-state" "--as-needed" "-lamath" "--pop-state"
+// CHECK-LINKING-ARMPL-NOSTDLIB-LINUX-NO: "-lm"
 // CHECK-LINKING-ARMPL-DARWIN: "-lm" "-lamath" "-lm"
+// CHECK-LINKING-ARMPL-NOSTDLIB-DARWIN: "-lamath"
+// CHECK-LINKING-ARMPL-NOSTDLIB-DARWIN-NO: "-lm"
 // CHECK-LINKING-ARMPL-MSVC: "--dependent-lib=amath"
 // CHECK-LINKING-AMATH-BEFORE-ARMPL-LINUX: "-lamath" {{.*}}"--push-state" "--as-needed" "-lm" "-lamath" "-lm" "--pop-state"
 // CHECK-LINKING-AMATH-BEFORE-ARMPL-DARWIN: "-lamath" {{.*}}"-lm" "-lamath" "-lm"
diff --git a/flang/test/Driver/fveclib.f90 b/flang/test/Driver/fveclib.f90
index 490ce974724a6..2539e07270a85 100644
--- a/flang/test/Driver/fveclib.f90
+++ b/flang/test/Driver/fveclib.f90
@@ -33,11 +33,17 @@
 
 ! RUN: %flang -### --target=aarch64-pc-windows-msvc -fveclib=ArmPL %s 2>&1 | FileCheck --check-prefix=CHECK-LINKING-ARMPL-MSVC %s
 ! RUN: %flang -### --target=aarch64-linux-gnu -fveclib=ArmPL %s 2>&1 | FileCheck --check-prefix=CHECK-LINKING-ARMPL-LINUX %s
+! RUN: %flang -### --target=aarch64-linux-gnu -fveclib=ArmPL -nostdlib %s 2>&1 | FileCheck --check-prefix=CHECK-LINKING-ARMPL-NOSTDLIB-LINUX %s
 ! RUN: %flang -### --target=aarch64-linux-gnu -fveclib=ArmPL %s -lamath 2>&1 | FileCheck --check-prefix=CHECK-LINKING-AMATH-BEFORE-ARMPL-LINUX %s
 ! RUN: %flang -### --target=arm64-apple-darwin -fveclib=ArmPL %s 2>&1 | FileCheck --check-prefix=CHECK-LINKING-ARMPL-DARWIN %s
+! RUN: %flang -### --target=arm64-apple-darwin -fveclib=ArmPL -nostdlib %s 2>&1 | FileCheck --check-prefix=CHECK-LINKING-ARMPL-NOSTDLIB-DARWIN %s
 ! RUN: %flang -### --target=arm64-apple-darwin -fveclib=ArmPL %s -lamath 2>&1 | FileCheck --check-prefix=CHECK-LINKING-AMATH-BEFORE-ARMPL-DARWIN %s
 ! CHECK-LINKING-ARMPL-LINUX: "--push-state" "--as-needed" "-lm" "-lamath" "-lm" "--pop-state"
+! CHECK-LINKING-ARMPL-NOSTDLIB-LINUX: "--push-state" "--as-needed" "-lamath" "--pop-state"
+! CHECK-LINKING-ARMPL-NOSTDLIB-LINUX-NO: "-lm"
 ! CHECK-LINKING-ARMPL-DARWIN: "-lm" "-lamath" "-lm"
+! CHECK-LINKING-ARMPL-NOSTDLIB-DARWIN: "-lamath"
+! CHECK-LINKING-ARMPL-NOSTDLIB-DARWIN-NO: "-lm"
 ! CHECK-LINKING-ARMPL-MSVC: "--dependent-lib=amath"
 ! CHECK-LINKING-AMATH-BEFORE-ARMPL-LINUX: "-lamath" {{.*}}"--push-state" "--as-needed" "-lm" "-lamath" "-lm" "--pop-state"
 ! CHECK-LINKING-AMATH-BEFORE-ARMPL-DARWIN: "-lamath" {{.*}}"-lm" "-lamath" "-lm"

@llvmbot
Copy link
Member

llvmbot commented Mar 29, 2025

@llvm/pr-subscribers-flang-driver

Author: Paul Osmialowski (pawosm-arm)

Changes

Although combining -fveclib=ArmPL with -nostdlib is a rare situation, it should still be supported correctly and should effect in avoidance of linking against libm.


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

3 Files Affected:

  • (modified) clang/lib/Driver/ToolChains/CommonArgs.cpp (+5-3)
  • (modified) clang/test/Driver/fveclib.c (+6)
  • (modified) flang/test/Driver/fveclib.f90 (+6)
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 41cfa3d2e4f8c..5aac20e1cdf44 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -515,7 +515,7 @@ void tools::AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs,
       //
       // 1. On Linux, link only when actually needed.
       //
-      // 2. Prefer libm functions over libamath.
+      // 2. Prefer libm functions over libamath (when no -nostdlib in use).
       //
       // 3. Link against libm to resolve libamath dependencies.
       //
@@ -523,9 +523,11 @@ void tools::AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs,
         CmdArgs.push_back(Args.MakeArgString("--push-state"));
         CmdArgs.push_back(Args.MakeArgString("--as-needed"));
       }
-      CmdArgs.push_back(Args.MakeArgString("-lm"));
+      if (!Args.hasArg(options::OPT_nostdlib))
+        CmdArgs.push_back(Args.MakeArgString("-lm"));
       CmdArgs.push_back(Args.MakeArgString("-lamath"));
-      CmdArgs.push_back(Args.MakeArgString("-lm"));
+      if (!Args.hasArg(options::OPT_nostdlib))
+        CmdArgs.push_back(Args.MakeArgString("-lm"));
       if (Triple.isOSLinux())
         CmdArgs.push_back(Args.MakeArgString("--pop-state"));
       addArchSpecificRPath(TC, Args, CmdArgs);
diff --git a/clang/test/Driver/fveclib.c b/clang/test/Driver/fveclib.c
index 7d0985c4dd4f4..62361f4679cc6 100644
--- a/clang/test/Driver/fveclib.c
+++ b/clang/test/Driver/fveclib.c
@@ -116,11 +116,17 @@
 /// Verify that vectorized routines library is being linked in.
 // RUN: %clang -### --target=aarch64-pc-windows-msvc -fveclib=ArmPL %s 2>&1 | FileCheck --check-prefix=CHECK-LINKING-ARMPL-MSVC %s
 // RUN: %clang -### --target=aarch64-linux-gnu -fveclib=ArmPL %s 2>&1 | FileCheck --check-prefix=CHECK-LINKING-ARMPL-LINUX %s
+// RUN: %clang -### --target=aarch64-linux-gnu -fveclib=ArmPL %s -nostdlib 2>&1 | FileCheck --check-prefix=CHECK-LINKING-ARMPL-NOSTDLIB-LINUX %s
 // RUN: %clang -### --target=aarch64-linux-gnu -fveclib=ArmPL %s -lamath 2>&1 | FileCheck --check-prefix=CHECK-LINKING-AMATH-BEFORE-ARMPL-LINUX %s
 // RUN: %clang -### --target=arm64-apple-darwin -fveclib=ArmPL %s 2>&1 | FileCheck --check-prefix=CHECK-LINKING-ARMPL-DARWIN %s
+// RUN: %clang -### --target=arm64-apple-darwin -fveclib=ArmPL -nostdlib %s 2>&1 | FileCheck --check-prefix=CHECK-LINKING-ARMPL-NOSTDLIB-DARWIN %s
 // RUN: %clang -### --target=arm64-apple-darwin -fveclib=ArmPL %s -lamath 2>&1 | FileCheck --check-prefix=CHECK-LINKING-AMATH-BEFORE-ARMPL-DARWIN %s
 // CHECK-LINKING-ARMPL-LINUX: "--push-state" "--as-needed" "-lm" "-lamath" "-lm" "--pop-state"
+// CHECK-LINKING-ARMPL-NOSTDLIB-LINUX: "--push-state" "--as-needed" "-lamath" "--pop-state"
+// CHECK-LINKING-ARMPL-NOSTDLIB-LINUX-NO: "-lm"
 // CHECK-LINKING-ARMPL-DARWIN: "-lm" "-lamath" "-lm"
+// CHECK-LINKING-ARMPL-NOSTDLIB-DARWIN: "-lamath"
+// CHECK-LINKING-ARMPL-NOSTDLIB-DARWIN-NO: "-lm"
 // CHECK-LINKING-ARMPL-MSVC: "--dependent-lib=amath"
 // CHECK-LINKING-AMATH-BEFORE-ARMPL-LINUX: "-lamath" {{.*}}"--push-state" "--as-needed" "-lm" "-lamath" "-lm" "--pop-state"
 // CHECK-LINKING-AMATH-BEFORE-ARMPL-DARWIN: "-lamath" {{.*}}"-lm" "-lamath" "-lm"
diff --git a/flang/test/Driver/fveclib.f90 b/flang/test/Driver/fveclib.f90
index 490ce974724a6..2539e07270a85 100644
--- a/flang/test/Driver/fveclib.f90
+++ b/flang/test/Driver/fveclib.f90
@@ -33,11 +33,17 @@
 
 ! RUN: %flang -### --target=aarch64-pc-windows-msvc -fveclib=ArmPL %s 2>&1 | FileCheck --check-prefix=CHECK-LINKING-ARMPL-MSVC %s
 ! RUN: %flang -### --target=aarch64-linux-gnu -fveclib=ArmPL %s 2>&1 | FileCheck --check-prefix=CHECK-LINKING-ARMPL-LINUX %s
+! RUN: %flang -### --target=aarch64-linux-gnu -fveclib=ArmPL -nostdlib %s 2>&1 | FileCheck --check-prefix=CHECK-LINKING-ARMPL-NOSTDLIB-LINUX %s
 ! RUN: %flang -### --target=aarch64-linux-gnu -fveclib=ArmPL %s -lamath 2>&1 | FileCheck --check-prefix=CHECK-LINKING-AMATH-BEFORE-ARMPL-LINUX %s
 ! RUN: %flang -### --target=arm64-apple-darwin -fveclib=ArmPL %s 2>&1 | FileCheck --check-prefix=CHECK-LINKING-ARMPL-DARWIN %s
+! RUN: %flang -### --target=arm64-apple-darwin -fveclib=ArmPL -nostdlib %s 2>&1 | FileCheck --check-prefix=CHECK-LINKING-ARMPL-NOSTDLIB-DARWIN %s
 ! RUN: %flang -### --target=arm64-apple-darwin -fveclib=ArmPL %s -lamath 2>&1 | FileCheck --check-prefix=CHECK-LINKING-AMATH-BEFORE-ARMPL-DARWIN %s
 ! CHECK-LINKING-ARMPL-LINUX: "--push-state" "--as-needed" "-lm" "-lamath" "-lm" "--pop-state"
+! CHECK-LINKING-ARMPL-NOSTDLIB-LINUX: "--push-state" "--as-needed" "-lamath" "--pop-state"
+! CHECK-LINKING-ARMPL-NOSTDLIB-LINUX-NO: "-lm"
 ! CHECK-LINKING-ARMPL-DARWIN: "-lm" "-lamath" "-lm"
+! CHECK-LINKING-ARMPL-NOSTDLIB-DARWIN: "-lamath"
+! CHECK-LINKING-ARMPL-NOSTDLIB-DARWIN-NO: "-lm"
 ! CHECK-LINKING-ARMPL-MSVC: "--dependent-lib=amath"
 ! CHECK-LINKING-AMATH-BEFORE-ARMPL-LINUX: "-lamath" {{.*}}"--push-state" "--as-needed" "-lm" "-lamath" "-lm" "--pop-state"
 ! CHECK-LINKING-AMATH-BEFORE-ARMPL-DARWIN: "-lamath" {{.*}}"-lm" "-lamath" "-lm"

@pawosm-arm
Copy link
Contributor Author

Seriously, this is something CI people signaled to me. Our CI builds everything with -fveclib=ArmPL and one of the packages failed on unexpected linker behavior when libm was artificially added by -fveclib=ArmPL despite the -nostdlib flag being used. My suggestion to use -fveclib=none for that particular package has been promptly rejected (quite correctly though).

@pawosm-arm pawosm-arm requested a review from jhuber6 March 31, 2025 18:15
//
// 3. Link against libm to resolve libamath dependencies.
//
if (Triple.isOSLinux()) {
CmdArgs.push_back(Args.MakeArgString("--push-state"));
CmdArgs.push_back(Args.MakeArgString("--as-needed"));
}
CmdArgs.push_back(Args.MakeArgString("-lm"));
if (!Args.hasArg(options::OPT_nostdlib))
CmdArgs.push_back(Args.MakeArgString("-lm"));
CmdArgs.push_back(Args.MakeArgString("-lamath"));
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this still passed? Normally nostdlib implies turning off all implicitly linked standard libraries.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There was a very long story behind this which has been discussed while this code has been introduced. In short: libamath replaces some of the libm functions, but at the same time, some of the libamath functions depend on libm. In this case, we don't want to outshadow libm (we only want to provide vector implementations on as-needed basis), and at the same time we want to produce a valid binary with no missing symbols (and that's wehre libm is needed) as long as no -nostdlib flag is given.

Copy link
Contributor

Choose a reason for hiding this comment

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

I guess -fvevlib can be seen as an explicit request for libraries, so I can see it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thank you.

//
// 3. Link against libm to resolve libamath dependencies.
//
if (Triple.isOSLinux()) {
CmdArgs.push_back(Args.MakeArgString("--push-state"));
CmdArgs.push_back(Args.MakeArgString("--as-needed"));
}
CmdArgs.push_back(Args.MakeArgString("-lm"));
if (!Args.hasArg(options::OPT_nostdlib))
CmdArgs.push_back(Args.MakeArgString("-lm"));
CmdArgs.push_back(Args.MakeArgString("-lamath"));
Copy link
Contributor

Choose a reason for hiding this comment

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

I guess -fvevlib can be seen as an explicit request for libraries, so I can see it.

// CHECK-LINKING-ARMPL-DARWIN: "-lm" "-lamath" "-lm"
// CHECK-LINKING-ARMPL-NOSTDLIB-DARWIN: "-lamath"
// CHECK-LINKING-ARMPL-NOSTDLIB-DARWIN-NO: "-lm"
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this work? I thought it was -NOT, but because they do the same thing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well it passes all of the tests so I can assume it does. And I've just found more files where -NO: and -NOT: is being used both in the same file, e.g. pragma-attribute-strict-subjects.c or warn-unsafe-buffer-usage-fixits-pointer-access.cpp. But generally, I should follow whatever convention I've encountered, so I'd change it to NOT:, as it has been used in this file arleady, and the FileCheck page says about NOT: but nothing about NO:.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Pushed a correction. It still passes here locally.

…against libm

Although combining -fveclib=ArmPL with -nostdlib is a rare situation,
it should still be supported correctly and should effect in avoidance
of linking against libm.
@pawosm-arm pawosm-arm force-pushed the veclib-nostdlib-no-libm branch from c033be3 to 77dfec4 Compare March 31, 2025 19:10
Copy link
Contributor

@jhuber6 jhuber6 left a comment

Choose a reason for hiding this comment

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

I guessing we pass -lm twice here to work around ld.bfd not handling static libraries in a pleasant way?

@pawosm-arm
Copy link
Contributor Author

I guessing we pass -lm twice here to work around ld.bfd not handling static libraries in a pleasant way?

This is all due to the way libamath incremetnally emerged into its present existence. And yes, static linking added another layer of problems here.

@pawosm-arm pawosm-arm merged commit cb7c223 into llvm:main Mar 31, 2025
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang Clang issues not falling into any other category flang:driver flang Flang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants