From 0cb6fb2384488b722bb75495f6257b6a8104decd Mon Sep 17 00:00:00 2001 From: Benjamin Maxwell Date: Mon, 14 Apr 2025 14:07:34 +0000 Subject: [PATCH] [LV] Workaround for sincos vectorization on aarch64-amazon-linux triple When the `aarch64-amazon-linux` triple is specified LLVM currently does not think it has a GNU environment, so looking up the "sincos" library function names via RTLIB::SINCOS_F32/64 fails, which prevents vectorizing sincos with vector libraries. The function names are needed only to find the corresponding vector mapping, so it does not matter if the scalar function exists. Given this, we can work around this issue by hardcoding names for SINCOS_F32/64 when we know we're using the name to find a vector mapping. --- llvm/include/llvm/CodeGen/BasicTTIImpl.h | 10 +++++++++- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 14 +++++++++++++- llvm/test/CodeGen/AArch64/veclib-llvm.sincos.ll | 3 +++ .../Transforms/LoopVectorize/AArch64/sincos.ll | 3 +++ 4 files changed, 28 insertions(+), 2 deletions(-) diff --git a/llvm/include/llvm/CodeGen/BasicTTIImpl.h b/llvm/include/llvm/CodeGen/BasicTTIImpl.h index 7711a9fd5d92..553e7ebc1fce 100644 --- a/llvm/include/llvm/CodeGen/BasicTTIImpl.h +++ b/llvm/include/llvm/CodeGen/BasicTTIImpl.h @@ -308,8 +308,16 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase { !isVectorizedStructTy(cast(RetTy))) return std::nullopt; + auto getLibcallName = [&] { + if (LC == RTLIB::SINCOS_F32) + return "sincosf"; + if (LC == RTLIB::SINCOS_F64) + return "sincos"; + return getTLI()->getLibcallName(LC); + }; + // Find associated libcall. - const char *LCName = getTLI()->getLibcallName(LC); + const char *LCName = getLibcallName(); if (!LCName) return std::nullopt; diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index b416c0efbbc4..717d45b4ea39 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -2554,7 +2554,19 @@ bool SelectionDAG::expandMultipleResultFPLibCall( EVT VT = Node->getValueType(0); unsigned NumResults = Node->getNumValues(); - const char *LCName = TLI->getLibcallName(LC); + /* Downstream change: #87 (sincos vectorization)*/ + auto getLibcallName = [&] { + if (VT.isVector()) { + if (LC == RTLIB::SINCOS_F32) + return "sincosf"; + if (LC == RTLIB::SINCOS_F64) + return "sincos"; + } + return TLI->getLibcallName(LC); + }; + /* End downstream change: #87 */ + + const char *LCName = getLibcallName(); if (!LC || !LCName) return false; diff --git a/llvm/test/CodeGen/AArch64/veclib-llvm.sincos.ll b/llvm/test/CodeGen/AArch64/veclib-llvm.sincos.ll index e18ac46165d2..7f40efa34271 100644 --- a/llvm/test/CodeGen/AArch64/veclib-llvm.sincos.ll +++ b/llvm/test/CodeGen/AArch64/veclib-llvm.sincos.ll @@ -1,6 +1,9 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --filter "(bl|ptrue)" --version 5 ; RUN: llc -mtriple=aarch64-gnu-linux -mattr=+neon,+sve -vector-library=sleefgnuabi < %s | FileCheck %s -check-prefix=SLEEF ; RUN: llc -mtriple=aarch64-gnu-linux -mattr=+neon,+sve -vector-library=ArmPL < %s | FileCheck %s -check-prefix=ARMPL +; Check we expand to a vector library call on aarch64-amazon-linux: +; RUN: llc -mtriple=aarch64-amazon-linux -mattr=+neon,+sve -vector-library=sleefgnuabi < %s | FileCheck %s -check-prefix=SLEEF +; RUN: llc -mtriple=aarch64-amazon-linux -mattr=+neon,+sve -vector-library=ArmPL < %s | FileCheck %s -check-prefix=ARMPL define void @test_sincos_v4f32(<4 x float> %x, ptr noalias %out_sin, ptr noalias %out_cos) { ; SLEEF-LABEL: test_sincos_v4f32: diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/sincos.ll b/llvm/test/Transforms/LoopVectorize/AArch64/sincos.ll index a7e949838f76..bcfa67eb7ab1 100644 --- a/llvm/test/Transforms/LoopVectorize/AArch64/sincos.ll +++ b/llvm/test/Transforms/LoopVectorize/AArch64/sincos.ll @@ -1,8 +1,11 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --filter "(:|sincos|extractvalue|store)" --version 5 ; RUN: opt -passes=loop-vectorize -mtriple=aarch64-gnu-linux -mcpu=neoverse-v1 -mattr=+sve < %s -S -o - -debug-only=loop-vectorize 2>%t.1 | FileCheck %s --check-prefix=CHECK ; RUN: opt -passes=loop-vectorize -mtriple=aarch64-gnu-linux -mcpu=neoverse-v1 -mattr=+sve -vector-library=ArmPL < %s -S -o - -debug-only=loop-vectorize 2>%t.2 | FileCheck %s --check-prefix=CHECK-ARMPL +; RUN: opt -passes=loop-vectorize -mtriple=aarch64-amazon-linux -mcpu=neoverse-v1 -mattr=+sve -vector-library=ArmPL < %s -S -o - -debug-only=loop-vectorize 2>%t.3 | FileCheck %s --check-prefix=CHECK-ARMPL ; RUN: FileCheck --input-file=%t.1 --check-prefix=CHECK-COST %s ; RUN: FileCheck --input-file=%t.2 --check-prefix=CHECK-COST-ARMPL %s +; Check we vectorize the functions with the vector-library on aarch64-amazon-linux: +; RUN: FileCheck --input-file=%t.3 --check-prefix=CHECK-COST-ARMPL %s ; REQUIRES: asserts ; CHECK-COST-LABEL: sincos_f32