From edf80dce39b3c9f731423c1a1da4f99cbf768e7c Mon Sep 17 00:00:00 2001 From: Usha Gupta Date: Tue, 9 Dec 2025 11:36:53 +0000 Subject: [PATCH] [LTO][Veclib] Fix vector library handling with LTO (#170638) Commit #167996 moved VecLib into TargetOptions and ensured clang properly sets it. However, some LTO backend code paths were still creating _TargetLibraryInfoImpl_ without passing the VecLib parameter from `TargetMachine::Options`. This PR completes the fix by ensuring that: _LTOBackend.cpp, ThinLTOCodeGenerator.cpp, UpdateCompilerUsed.cpp_ all pass `TM->Options.VecLib` when constructing _TargetLibraryInfoImpl_. Without this fix, vector library information (e.g., -fveclib=ArmPL) would not be properly recognized during LTO optimization and code generation, potentially causing incorrect optimizations or linker errors when vector library functions are referenced. --- llvm/lib/LTO/LTOBackend.cpp | 4 +-- llvm/lib/LTO/ThinLTOCodeGenerator.cpp | 2 +- llvm/lib/LTO/UpdateCompilerUsed.cpp | 2 +- llvm/test/LTO/AArch64/frem-scalable-veclib.ll | 19 ++++++++++++++ llvm/test/LTO/AArch64/veclib-armpl-lto.ll | 24 +++++++++++++++++ llvm/test/LTO/AArch64/veclib-armpl-lto2.ll | 26 +++++++++++++++++++ 6 files changed, 73 insertions(+), 4 deletions(-) create mode 100644 llvm/test/LTO/AArch64/frem-scalable-veclib.ll create mode 100644 llvm/test/LTO/AArch64/veclib-armpl-lto.ll create mode 100644 llvm/test/LTO/AArch64/veclib-armpl-lto2.ll diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp index f9cde383ce32..49b412c9a299 100644 --- a/llvm/lib/LTO/LTOBackend.cpp +++ b/llvm/lib/LTO/LTOBackend.cpp @@ -279,7 +279,7 @@ static void runNewPMPasses(const Config &Conf, Module &Mod, TargetMachine *TM, RegisterPassPlugins(Conf.PassPlugins, PB); std::unique_ptr TLII( - new TargetLibraryInfoImpl(TM->getTargetTriple())); + new TargetLibraryInfoImpl(TM->getTargetTriple(), TM->Options.VecLib)); if (Conf.Freestanding) TLII->disableAllFunctions(); FAM.registerPass([&] { return TargetLibraryAnalysis(*TLII); }); @@ -445,7 +445,7 @@ static void codegen(const Config &Conf, TargetMachine *TM, // keep the pointer and may use it until their destruction. See #138194. { legacy::PassManager CodeGenPasses; - TargetLibraryInfoImpl TLII(Mod.getTargetTriple()); + TargetLibraryInfoImpl TLII(Mod.getTargetTriple(), TM->Options.VecLib); CodeGenPasses.add(new TargetLibraryInfoWrapperPass(TLII)); CodeGenPasses.add(new RuntimeLibraryInfoWrapper( Mod.getTargetTriple(), TM->Options.ExceptionModel, diff --git a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp index ff94c54ab3e6..ed26c931d062 100644 --- a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp +++ b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp @@ -249,7 +249,7 @@ static void optimizeModule(Module &TheModule, TargetMachine &TM, PassBuilder PB(&TM, PTO, PGOOpt, &PIC); std::unique_ptr TLII( - new TargetLibraryInfoImpl(TM.getTargetTriple())); + new TargetLibraryInfoImpl(TM.getTargetTriple(), TM.Options.VecLib)); if (Freestanding) TLII->disableAllFunctions(); FAM.registerPass([&] { return TargetLibraryAnalysis(*TLII); }); diff --git a/llvm/lib/LTO/UpdateCompilerUsed.cpp b/llvm/lib/LTO/UpdateCompilerUsed.cpp index 1889c2b762ff..f79a3744afad 100644 --- a/llvm/lib/LTO/UpdateCompilerUsed.cpp +++ b/llvm/lib/LTO/UpdateCompilerUsed.cpp @@ -57,7 +57,7 @@ private: // same names are added to llvm.compiler.used to prevent them from being // deleted by optimizations. void initializeLibCalls(const Module &TheModule) { - TargetLibraryInfoImpl TLII(TM.getTargetTriple()); + TargetLibraryInfoImpl TLII(TM.getTargetTriple(), TM.Options.VecLib); TargetLibraryInfo TLI(TLII); // TargetLibraryInfo has info on C runtime library calls on the current diff --git a/llvm/test/LTO/AArch64/frem-scalable-veclib.ll b/llvm/test/LTO/AArch64/frem-scalable-veclib.ll new file mode 100644 index 000000000000..6e9edfef67f2 --- /dev/null +++ b/llvm/test/LTO/AArch64/frem-scalable-veclib.ll @@ -0,0 +1,19 @@ +; RUN: opt -module-summary %s -o %t.bc +; RUN: llvm-lto2 run %t.bc -o %t.o -save-temps \ +; RUN: -r %t.bc,compute,px \ +; RUN: -mcpu=neoverse-v1 -O3 \ +; RUN: -vector-library=ArmPL +; RUN: llvm-nm %t.o.1 | FileCheck %s + +; This test verifies that the VecLib propagation in LTO prevents a crash +; when compiling scalable vector frem operations. + +; CHECK: compute + +target triple = "aarch64-unknown-linux-gnu" + +define @compute( %a, %b) { +entry: + %rem = frem %a, %b + ret %rem +} diff --git a/llvm/test/LTO/AArch64/veclib-armpl-lto.ll b/llvm/test/LTO/AArch64/veclib-armpl-lto.ll new file mode 100644 index 000000000000..713f8b381d8d --- /dev/null +++ b/llvm/test/LTO/AArch64/veclib-armpl-lto.ll @@ -0,0 +1,24 @@ +; RUN: llvm-as %s -o %t.bc +; RUN: llvm-lto -exported-symbol=compute -exported-symbol=armpl_vsinq_f64 -o %t.o %t.bc +; RUN: llvm-nm %t.o | FileCheck %s + +; This test ensures that ArmPL vector library functions are preserved through +; the old LTO API (llvm-lto). TargetLibraryInfoImpl in LTO backend passes +; receive the VecLib parameter from TargetMachine Options. + +; CHECK: armpl_vsinq_f64 +; CHECK: compute + +target triple = "aarch64-unknown-linux-gnu" + +@llvm.compiler.used = appending global [1 x ptr] [ptr @armpl_vsinq_f64], section "llvm.metadata" + +declare aarch64_vector_pcs <2 x double> @armpl_vsinq_f64(<2 x double>) + +define void @compute(ptr %out, ptr %in) { +entry: + %v = load <2 x double>, ptr %in, align 16 + %result = call aarch64_vector_pcs <2 x double> @armpl_vsinq_f64(<2 x double> %v) + store <2 x double> %result, ptr %out, align 16 + ret void +} diff --git a/llvm/test/LTO/AArch64/veclib-armpl-lto2.ll b/llvm/test/LTO/AArch64/veclib-armpl-lto2.ll new file mode 100644 index 000000000000..9873910a08cd --- /dev/null +++ b/llvm/test/LTO/AArch64/veclib-armpl-lto2.ll @@ -0,0 +1,26 @@ +; RUN: opt -module-summary %s -o %t.bc +; RUN: llvm-lto2 run -save-temps -o %t.o %t.bc \ +; RUN: -r=%t.bc,compute,px \ +; RUN: -r=%t.bc,armpl_vsinq_f64 +; RUN: llvm-dis %t.o.1.5.precodegen.bc -o - | FileCheck %s + +; This test ensures that ArmPL vector library functions are preserved through +; the new LTO API (llvm-lto2). TargetLibraryInfoImpl in LTO backend passes +; receive the VecLib parameter from TargetMachine Options. + +; CHECK: @llvm.compiler.used = appending global [1 x ptr] [ptr @armpl_vsinq_f64] +; CHECK: declare aarch64_vector_pcs <2 x double> @armpl_vsinq_f64(<2 x double>) + +target triple = "aarch64-unknown-linux-gnu" + +@llvm.compiler.used = appending global [1 x ptr] [ptr @armpl_vsinq_f64], section "llvm.metadata" + +declare aarch64_vector_pcs <2 x double> @armpl_vsinq_f64(<2 x double>) + +define void @compute(ptr %out, ptr %in) { +entry: + %v = load <2 x double>, ptr %in, align 16 + %result = call aarch64_vector_pcs <2 x double> @armpl_vsinq_f64(<2 x double> %v) + store <2 x double> %result, ptr %out, align 16 + ret void +}