[llvm] [CodeGen] Lower vector llvm.sincos to AMDLIBM vector calls (PR #194580)
Kito Cheng via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 28 23:26:39 PDT 2026
https://github.com/kito-cheng updated https://github.com/llvm/llvm-project/pull/194580
>From d2acbb523b8bd64ba3f2ade44ec6cc053e7363ac Mon Sep 17 00:00:00 2001
From: Kito Cheng <kito.cheng at sifive.com>
Date: Tue, 28 Apr 2026 13:18:26 +0800
Subject: [PATCH] [CodeGen] Lower vector llvm.sincos to AMDLIBM vector calls
- Adds amd_vrd2_sincos to RuntimeLibcalls.td.
- Adds v8f32, v16f32, v4f64, and v8f64 cases to getSINCOS().
- Enables the AMDLIBM sincos in RuntimeLibcallsInfo.
---
llvm/include/llvm/IR/RuntimeLibcalls.td | 1 +
llvm/lib/CodeGen/TargetLoweringBase.cpp | 8 +
llvm/lib/IR/RuntimeLibcalls.cpp | 7 +
llvm/test/CodeGen/X86/veclib-llvm.sincos.ll | 175 ++++++++++++++------
4 files changed, 137 insertions(+), 54 deletions(-)
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td b/llvm/include/llvm/IR/RuntimeLibcalls.td
index 28967d81f63fb..a09825dfa43dc 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.td
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.td
@@ -4431,6 +4431,7 @@ defset list<RuntimeLibcallImpl> AMDLIBM_VECFUNCS = {
def amd_vrd2_log2 : RuntimeLibcallImpl<LOG2_V2F64>;
def amd_vrd2_pow : RuntimeLibcallImpl<POW_V2F64>;
def amd_vrd2_sin : RuntimeLibcallImpl<SIN_V2F64>;
+ def amd_vrd2_sincos : RuntimeLibcallImpl<SINCOS_V2F64>;
def amd_vrd2_tan : RuntimeLibcallImpl<TAN_V2F64>;
def amd_vrd4_atan : RuntimeLibcallImpl<ATAN_V4F64>;
def amd_vrd4_cos : RuntimeLibcallImpl<COS_V4F64>;
diff --git a/llvm/lib/CodeGen/TargetLoweringBase.cpp b/llvm/lib/CodeGen/TargetLoweringBase.cpp
index ad858dc0c3af6..28826c08cbdec 100644
--- a/llvm/lib/CodeGen/TargetLoweringBase.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringBase.cpp
@@ -586,8 +586,16 @@ RTLIB::Libcall RTLIB::getSINCOS(EVT RetVT) {
switch (RetVT.getSimpleVT().SimpleTy) {
case MVT::v4f32:
return RTLIB::SINCOS_V4F32;
+ case MVT::v8f32:
+ return RTLIB::SINCOS_V8F32;
+ case MVT::v16f32:
+ return RTLIB::SINCOS_V16F32;
case MVT::v2f64:
return RTLIB::SINCOS_V2F64;
+ case MVT::v4f64:
+ return RTLIB::SINCOS_V4F64;
+ case MVT::v8f64:
+ return RTLIB::SINCOS_V8F64;
case MVT::nxv4f32:
return RTLIB::SINCOS_NXV4F32;
case MVT::nxv2f64:
diff --git a/llvm/lib/IR/RuntimeLibcalls.cpp b/llvm/lib/IR/RuntimeLibcalls.cpp
index 96aef02342612..d72277fa2b179 100644
--- a/llvm/lib/IR/RuntimeLibcalls.cpp
+++ b/llvm/lib/IR/RuntimeLibcalls.cpp
@@ -89,6 +89,13 @@ RuntimeLibcallsInfo::RuntimeLibcallsInfo(const Triple &TT,
RTLIB::impl_armpl_vcbrtq_f32, RTLIB::impl_armpl_vcbrtq_f64})
setLibcallImplCallingConv(Impl, CallingConv::AArch64_VectorCall);
break;
+ case VectorLibrary::AMDLIBM:
+ for (RTLIB::LibcallImpl Impl :
+ {RTLIB::impl_amd_vrd2_sincos, RTLIB::impl_amd_vrd4_sincos,
+ RTLIB::impl_amd_vrd8_sincos, RTLIB::impl_amd_vrs4_sincosf,
+ RTLIB::impl_amd_vrs8_sincosf, RTLIB::impl_amd_vrs16_sincosf})
+ setAvailable(Impl);
+ break;
default:
break;
}
diff --git a/llvm/test/CodeGen/X86/veclib-llvm.sincos.ll b/llvm/test/CodeGen/X86/veclib-llvm.sincos.ll
index 11bc122cb80c8..0075e85865667 100644
--- a/llvm/test/CodeGen/X86/veclib-llvm.sincos.ll
+++ b/llvm/test/CodeGen/X86/veclib-llvm.sincos.ll
@@ -9,11 +9,14 @@
; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mcpu=x86-64-v4 -vector-library=LIBMVEC < %s | FileCheck %s --check-prefixes=CHECK,GLIBC,GLIBC-AVX512
define void @test_sincos_v4f32(<4 x float> %x, ptr noalias %out_sin, ptr noalias %out_cos) {
-; CHECK-LABEL: test_sincos_v4f32:
-; CHECK: callq sincosf at PLT
-; CHECK: callq sincosf at PLT
-; CHECK: callq sincosf at PLT
-; CHECK: callq sincosf at PLT
+; AMD-LABEL: test_sincos_v4f32:
+; AMD: callq amd_vrs4_sincosf at PLT
+;
+; GLIBC-LABEL: test_sincos_v4f32:
+; GLIBC: callq sincosf at PLT
+; GLIBC: callq sincosf at PLT
+; GLIBC: callq sincosf at PLT
+; GLIBC: callq sincosf at PLT
%result = call { <4 x float>, <4 x float> } @llvm.sincos.v4f32(<4 x float> %x)
%result.0 = extractvalue { <4 x float>, <4 x float> } %result, 0
%result.1 = extractvalue { <4 x float>, <4 x float> } %result, 1
@@ -23,15 +26,29 @@ define void @test_sincos_v4f32(<4 x float> %x, ptr noalias %out_sin, ptr noalias
}
define void @test_sincos_v8f32(<8 x float> %x, ptr noalias %out_sin, ptr noalias %out_cos) {
-; CHECK-LABEL: test_sincos_v8f32:
-; CHECK: callq sincosf at PLT
-; CHECK: callq sincosf at PLT
-; CHECK: callq sincosf at PLT
-; CHECK: callq sincosf at PLT
-; CHECK: callq sincosf at PLT
-; CHECK: callq sincosf at PLT
-; CHECK: callq sincosf at PLT
-; CHECK: callq sincosf at PLT
+; AMD-SSE-LABEL: test_sincos_v8f32:
+; AMD-SSE: callq amd_vrs4_sincosf at PLT
+; AMD-SSE: callq amd_vrs4_sincosf at PLT
+;
+; AMD-AVX-LABEL: test_sincos_v8f32:
+; AMD-AVX: callq amd_vrs4_sincosf at PLT
+; AMD-AVX: callq amd_vrs4_sincosf at PLT
+;
+; AMD-AVX2-LABEL: test_sincos_v8f32:
+; AMD-AVX2: callq amd_vrs8_sincosf at PLT
+;
+; AMD-AVX512-LABEL: test_sincos_v8f32:
+; AMD-AVX512: callq amd_vrs8_sincosf at PLT
+;
+; GLIBC-LABEL: test_sincos_v8f32:
+; GLIBC: callq sincosf at PLT
+; GLIBC: callq sincosf at PLT
+; GLIBC: callq sincosf at PLT
+; GLIBC: callq sincosf at PLT
+; GLIBC: callq sincosf at PLT
+; GLIBC: callq sincosf at PLT
+; GLIBC: callq sincosf at PLT
+; GLIBC: callq sincosf at PLT
%result = call { <8 x float>, <8 x float> } @llvm.sincos.v8f32(<8 x float> %x)
%result.0 = extractvalue { <8 x float>, <8 x float> } %result, 0
%result.1 = extractvalue { <8 x float>, <8 x float> } %result, 1
@@ -41,23 +58,42 @@ define void @test_sincos_v8f32(<8 x float> %x, ptr noalias %out_sin, ptr noalias
}
define void @test_sincos_v16f32(<16 x float> %x, ptr noalias %out_sin, ptr noalias %out_cos) {
-; CHECK-LABEL: test_sincos_v16f32:
-; CHECK: callq sincosf at PLT
-; CHECK: callq sincosf at PLT
-; CHECK: callq sincosf at PLT
-; CHECK: callq sincosf at PLT
-; CHECK: callq sincosf at PLT
-; CHECK: callq sincosf at PLT
-; CHECK: callq sincosf at PLT
-; CHECK: callq sincosf at PLT
-; CHECK: callq sincosf at PLT
-; CHECK: callq sincosf at PLT
-; CHECK: callq sincosf at PLT
-; CHECK: callq sincosf at PLT
-; CHECK: callq sincosf at PLT
-; CHECK: callq sincosf at PLT
-; CHECK: callq sincosf at PLT
-; CHECK: callq sincosf at PLT
+; AMD-SSE-LABEL: test_sincos_v16f32:
+; AMD-SSE: callq amd_vrs4_sincosf at PLT
+; AMD-SSE: callq amd_vrs4_sincosf at PLT
+; AMD-SSE: callq amd_vrs4_sincosf at PLT
+; AMD-SSE: callq amd_vrs4_sincosf at PLT
+;
+; AMD-AVX-LABEL: test_sincos_v16f32:
+; AMD-AVX: callq amd_vrs4_sincosf at PLT
+; AMD-AVX: callq amd_vrs4_sincosf at PLT
+; AMD-AVX: callq amd_vrs4_sincosf at PLT
+; AMD-AVX: callq amd_vrs4_sincosf at PLT
+;
+; AMD-AVX2-LABEL: test_sincos_v16f32:
+; AMD-AVX2: callq amd_vrs8_sincosf at PLT
+; AMD-AVX2: callq amd_vrs8_sincosf at PLT
+;
+; AMD-AVX512-LABEL: test_sincos_v16f32:
+; AMD-AVX512: callq amd_vrs16_sincosf at PLT
+;
+; GLIBC-LABEL: test_sincos_v16f32:
+; GLIBC: callq sincosf at PLT
+; GLIBC: callq sincosf at PLT
+; GLIBC: callq sincosf at PLT
+; GLIBC: callq sincosf at PLT
+; GLIBC: callq sincosf at PLT
+; GLIBC: callq sincosf at PLT
+; GLIBC: callq sincosf at PLT
+; GLIBC: callq sincosf at PLT
+; GLIBC: callq sincosf at PLT
+; GLIBC: callq sincosf at PLT
+; GLIBC: callq sincosf at PLT
+; GLIBC: callq sincosf at PLT
+; GLIBC: callq sincosf at PLT
+; GLIBC: callq sincosf at PLT
+; GLIBC: callq sincosf at PLT
+; GLIBC: callq sincosf at PLT
%result = call { <16 x float>, <16 x float> } @llvm.sincos.v16f32(<16 x float> %x)
%result.0 = extractvalue { <16 x float>, <16 x float> } %result, 0
%result.1 = extractvalue { <16 x float>, <16 x float> } %result, 1
@@ -67,9 +103,12 @@ define void @test_sincos_v16f32(<16 x float> %x, ptr noalias %out_sin, ptr noali
}
define void @test_sincos_v2f64(<2 x double> %x, ptr noalias %out_sin, ptr noalias %out_cos) {
-; CHECK-LABEL: test_sincos_v2f64:
-; CHECK: callq sincos at PLT
-; CHECK: callq sincos at PLT
+; AMD-LABEL: test_sincos_v2f64:
+; AMD: callq amd_vrd2_sincos at PLT
+;
+; GLIBC-LABEL: test_sincos_v2f64:
+; GLIBC: callq sincos at PLT
+; GLIBC: callq sincos at PLT
%result = call { <2 x double>, <2 x double> } @llvm.sincos.v2f64(<2 x double> %x)
%result.0 = extractvalue { <2 x double>, <2 x double> } %result, 0
%result.1 = extractvalue { <2 x double>, <2 x double> } %result, 1
@@ -79,11 +118,25 @@ define void @test_sincos_v2f64(<2 x double> %x, ptr noalias %out_sin, ptr noalia
}
define void @test_sincos_v4f64(<4 x double> %x, ptr noalias %out_sin, ptr noalias %out_cos) {
-; CHECK-LABEL: test_sincos_v4f64:
-; CHECK: callq sincos at PLT
-; CHECK: callq sincos at PLT
-; CHECK: callq sincos at PLT
-; CHECK: callq sincos at PLT
+; AMD-SSE-LABEL: test_sincos_v4f64:
+; AMD-SSE: callq amd_vrd2_sincos at PLT
+; AMD-SSE: callq amd_vrd2_sincos at PLT
+;
+; AMD-AVX-LABEL: test_sincos_v4f64:
+; AMD-AVX: callq amd_vrd2_sincos at PLT
+; AMD-AVX: callq amd_vrd2_sincos at PLT
+;
+; AMD-AVX2-LABEL: test_sincos_v4f64:
+; AMD-AVX2: callq amd_vrd4_sincos at PLT
+;
+; AMD-AVX512-LABEL: test_sincos_v4f64:
+; AMD-AVX512: callq amd_vrd4_sincos at PLT
+;
+; GLIBC-LABEL: test_sincos_v4f64:
+; GLIBC: callq sincos at PLT
+; GLIBC: callq sincos at PLT
+; GLIBC: callq sincos at PLT
+; GLIBC: callq sincos at PLT
%result = call { <4 x double>, <4 x double> } @llvm.sincos.v4f64(<4 x double> %x)
%result.0 = extractvalue { <4 x double>, <4 x double> } %result, 0
%result.1 = extractvalue { <4 x double>, <4 x double> } %result, 1
@@ -93,15 +146,34 @@ define void @test_sincos_v4f64(<4 x double> %x, ptr noalias %out_sin, ptr noalia
}
define void @test_sincos_v8f64(<8 x double> %x, ptr noalias %out_sin, ptr noalias %out_cos) {
-; CHECK-LABEL: test_sincos_v8f64:
-; CHECK: callq sincos at PLT
-; CHECK: callq sincos at PLT
-; CHECK: callq sincos at PLT
-; CHECK: callq sincos at PLT
-; CHECK: callq sincos at PLT
-; CHECK: callq sincos at PLT
-; CHECK: callq sincos at PLT
-; CHECK: callq sincos at PLT
+; AMD-SSE-LABEL: test_sincos_v8f64:
+; AMD-SSE: callq amd_vrd2_sincos at PLT
+; AMD-SSE: callq amd_vrd2_sincos at PLT
+; AMD-SSE: callq amd_vrd2_sincos at PLT
+; AMD-SSE: callq amd_vrd2_sincos at PLT
+;
+; AMD-AVX-LABEL: test_sincos_v8f64:
+; AMD-AVX: callq amd_vrd2_sincos at PLT
+; AMD-AVX: callq amd_vrd2_sincos at PLT
+; AMD-AVX: callq amd_vrd2_sincos at PLT
+; AMD-AVX: callq amd_vrd2_sincos at PLT
+;
+; AMD-AVX2-LABEL: test_sincos_v8f64:
+; AMD-AVX2: callq amd_vrd4_sincos at PLT
+; AMD-AVX2: callq amd_vrd4_sincos at PLT
+;
+; AMD-AVX512-LABEL: test_sincos_v8f64:
+; AMD-AVX512: callq amd_vrd8_sincos at PLT
+;
+; GLIBC-LABEL: test_sincos_v8f64:
+; GLIBC: callq sincos at PLT
+; GLIBC: callq sincos at PLT
+; GLIBC: callq sincos at PLT
+; GLIBC: callq sincos at PLT
+; GLIBC: callq sincos at PLT
+; GLIBC: callq sincos at PLT
+; GLIBC: callq sincos at PLT
+; GLIBC: callq sincos at PLT
%result = call { <8 x double>, <8 x double> } @llvm.sincos.v8f64(<8 x double> %x)
%result.0 = extractvalue { <8 x double>, <8 x double> } %result, 0
%result.1 = extractvalue { <8 x double>, <8 x double> } %result, 1
@@ -110,12 +182,7 @@ define void @test_sincos_v8f64(<8 x double> %x, ptr noalias %out_sin, ptr noalia
ret void
}
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
-; AMD: {{.*}}
-; AMD-AVX: {{.*}}
-; AMD-AVX2: {{.*}}
-; AMD-AVX512: {{.*}}
-; AMD-SSE: {{.*}}
-; GLIBC: {{.*}}
+; CHECK: {{.*}}
; GLIBC-AVX: {{.*}}
; GLIBC-AVX2: {{.*}}
; GLIBC-AVX512: {{.*}}
More information about the llvm-commits
mailing list