Skip to content

[clang] Add __builtin_sincospi that lowers to llvm.sincospi.* #127065

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
Feb 21, 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
6 changes: 6 additions & 0 deletions clang/include/clang/Basic/Builtins.td
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,12 @@ def TruncF16F128 : Builtin, F16F128MathTemplate {
let Prototype = "T(T)";
}

def Sincospi : Builtin, FPMathTemplate {
let Spellings = ["__builtin_sincospi"];
let Attributes = [FunctionWithBuiltinPrefix, NoThrow];
let Prototype = "void(T, T*, T*)";
}

// Access to floating point environment.
def BuiltinFltRounds : Builtin {
let Spellings = ["__builtin_flt_rounds"];
Expand Down
8 changes: 8 additions & 0 deletions clang/lib/CodeGen/CGBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3377,6 +3377,14 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
return RValue::get(emitUnaryMaybeConstrainedFPBuiltin(
*this, E, Intrinsic::sinh, Intrinsic::experimental_constrained_sinh));

case Builtin::BI__builtin_sincospi:
case Builtin::BI__builtin_sincospif:
case Builtin::BI__builtin_sincospil:
if (Builder.getIsFPConstrained())
break; // TODO: Emit constrained sincospi intrinsic once one exists.
emitSincosBuiltin(*this, E, Intrinsic::sincospi);
return RValue::get(nullptr);

case Builtin::BIsincos:
case Builtin::BIsincosf:
case Builtin::BIsincosl:
Expand Down
61 changes: 61 additions & 0 deletions clang/test/CodeGen/AArch64/sincos.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// RUN: %clang_cc1 -triple=aarch64-gnu-linux -emit-llvm -O1 %s -o - | FileCheck --check-prefix=NO-MATH-ERRNO %s
// RUN: %clang_cc1 -triple=aarch64-gnu-linux -emit-llvm -fmath-errno %s -o - | FileCheck --check-prefix=MATH-ERRNO %s
// RUN: %clang_cc1 -triple=aarch64-gnu-linux -emit-llvm -ffp-exception-behavior=strict %s -o - | FileCheck --check-prefix=STRICT-FP %s

void sincos(double, double*, double*);
void sincosf(float, float*, float*);
Expand All @@ -15,6 +16,9 @@ void sincosl(long double, long double*, long double*);
// MATH-ERRNO-LABEL: @sincos_f32
// MATH-ERRNO: call void @sincosf(
//
// STRICT-FP-LABEL: @sincos_f32
// STRICT-FP: call void @sincosf(
//
void sincos_f32(float x, float* fp0, float* fp1) {
sincosf(x, fp0, fp1);
}
Expand Down Expand Up @@ -43,6 +47,9 @@ void sincos_builtin_f32(float x, float* fp0, float* fp1) {
// MATH-ERRNO-LABEL: @sincos_f64
// MATH-ERRNO: call void @sincos(
//
// STRICT-FP-LABEL: @sincos_f64
// STRICT-FP: call void @sincos(
//
void sincos_f64(double x, double* dp0, double* dp1) {
sincos(x, dp0, dp1);
}
Expand Down Expand Up @@ -71,6 +78,9 @@ void sincos_builtin_f64(double x, double* dp0, double* dp1) {
// MATH-ERRNO-LABEL: @sincos_f128
// MATH-ERRNO: call void @sincosl(
//
// STRICT-FP-LABEL: @sincos_f128
// STRICT-FP: call void @sincosl(
//
void sincos_f128(long double x, long double* ldp0, long double* ldp1) {
sincosl(x, ldp0, ldp1);
}
Expand All @@ -88,3 +98,54 @@ void sincos_f128(long double x, long double* ldp0, long double* ldp1) {
void sincos_builtin_f128(long double x, long double* ldp0, long double* ldp1) {
__builtin_sincosl(x, ldp0, ldp1);
}

// NO-MATH-ERRNO-LABEL: @sincospi_f32
// NO-MATH-ERRNO: [[SINCOSPI:%.*]] = tail call { float, float } @llvm.sincospi.f32(float {{.*}})
// NO-MATH-ERRNO-NEXT: [[SINPI:%.*]] = extractvalue { float, float } [[SINCOSPI]], 0
// NO-MATH-ERRNO-NEXT: [[COSPI:%.*]] = extractvalue { float, float } [[SINCOSPI]], 1
// NO-MATH-ERRNO-NEXT: store float [[SINPI]], ptr {{.*}}, align 4, !alias.scope [[SINCOSPI_ALIAS_SCOPE:![0-9]+]]
// NO-MATH-ERRNO-NEXT: store float [[COSPI]], ptr {{.*}}, align 4, !noalias [[SINCOSPI_ALIAS_SCOPE]]
//
// MATH-ERRNO-LABEL: @sincospi_f32
// MATH-ERRNO: call void @sincospif(
//
// STRICT-FP-LABEL: @sincospi_f32
// STRICT-FP: call void @sincospif(
//
void sincospi_f32(float x, float* fp0, float* fp1) {
__builtin_sincospif(x, fp0, fp1);
}

// NO-MATH-ERRNO-LABEL: @sincospi_f64
// NO-MATH-ERRNO: [[SINCOSPI:%.*]] = tail call { double, double } @llvm.sincospi.f64(double {{.*}})
// NO-MATH-ERRNO-NEXT: [[SINPI:%.*]] = extractvalue { double, double } [[SINCOSPI]], 0
// NO-MATH-ERRNO-NEXT: [[COSPI:%.*]] = extractvalue { double, double } [[SINCOSPI]], 1
// NO-MATH-ERRNO-NEXT: store double [[SINPI]], ptr {{.*}}, align 8, !alias.scope [[SINCOSPI_ALIAS_SCOPE:![0-9]+]]
// NO-MATH-ERRNO-NEXT: store double [[COSPI]], ptr {{.*}}, align 8, !noalias [[SINCOSPI_ALIAS_SCOPE]]
//
// MATH-ERRNO-LABEL: @sincospi_f64
// MATH-ERRNO: call void @sincospi(
//
// STRICT-FP-LABEL: @sincospi_f64
// STRICT-FP: call void @sincospi(
//
void sincospi_f64(double x, double* dp0, double* dp1) {
__builtin_sincospi(x, dp0, dp1);
}

// NO-MATH-ERRNO-LABEL: @sincospi_f128
// NO-MATH-ERRNO: [[SINCOSPI:%.*]] = tail call { fp128, fp128 } @llvm.sincospi.f128(fp128 {{.*}})
// NO-MATH-ERRNO-NEXT: [[SINPI:%.*]] = extractvalue { fp128, fp128 } [[SINCOSPI]], 0
// NO-MATH-ERRNO-NEXT: [[COSPI:%.*]] = extractvalue { fp128, fp128 } [[SINCOSPI]], 1
// NO-MATH-ERRNO-NEXT: store fp128 [[SINPI]], ptr {{.*}}, align 16, !alias.scope [[SINCOSPI_ALIAS_SCOPE:![0-9]+]]
// NO-MATH-ERRNO-NEXT: store fp128 [[COSPI]], ptr {{.*}}, align 16, !noalias [[SINCOSPI_ALIAS_SCOPE]]
//
// MATH-ERRNO-LABEL: @sincospi_f128
// MATH-ERRNO: call void @sincospil(
//
// STRICT-FP-LABEL: @sincospi_f128
// STRICT-FP: call void @sincospil(
//
void sincospi_f128(long double x, long double* ldp0, long double* ldp1) {
__builtin_sincospil(x, ldp0, ldp1);
}
27 changes: 27 additions & 0 deletions clang/test/CodeGen/X86/math-builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,25 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) {
// NO__ERRNO-NEXT: store fp128 [[SINCOS_F128_1]], ptr %{{.+}}, align 16


// NO__ERRNO: [[SINCOSPI_F64:%.+]] = call { double, double } @llvm.sincospi.f64(double %{{.+}})
// NO__ERRNO-NEXT: [[SINCOSPI_F64_0:%.+]] = extractvalue { double, double } [[SINCOSPI_F64]], 0
// NO__ERRNO-NEXT: [[SINCOSPI_F64_1:%.+]] = extractvalue { double, double } [[SINCOSPI_F64]], 1
// NO__ERRNO-NEXT: store double [[SINCOSPI_F64_0]], ptr %{{.+}}, align 8
// NO__ERRNO-NEXT: store double [[SINCOSPI_F64_1]], ptr %{{.+}}, align 8

// NO__ERRNO: [[SINCOSPI_F32:%.+]] = call { float, float } @llvm.sincospi.f32(float %{{.+}})
// NO__ERRNO-NEXT: [[SINCOSPI_F32_0:%.+]] = extractvalue { float, float } [[SINCOSPI_F32]], 0
// NO__ERRNO-NEXT: [[SINCOSPI_F32_1:%.+]] = extractvalue { float, float } [[SINCOSPI_F32]], 1
// NO__ERRNO-NEXT: store float [[SINCOSPI_F32_0]], ptr %{{.+}}, align 4
// NO__ERRNO-NEXT: store float [[SINCOSPI_F32_1]], ptr %{{.+}}, align 4

// NO__ERRNO: [[SINCOSPI_F80:%.+]] = call { x86_fp80, x86_fp80 } @llvm.sincospi.f80(x86_fp80 %{{.+}})
// NO__ERRNO-NEXT: [[SINCOSPI_F80_0:%.+]] = extractvalue { x86_fp80, x86_fp80 } [[SINCOSPI_F80]], 0
// NO__ERRNO-NEXT: [[SINCOSPI_F80_1:%.+]] = extractvalue { x86_fp80, x86_fp80 } [[SINCOSPI_F80]], 1
// NO__ERRNO-NEXT: store x86_fp80 [[SINCOSPI_F80_0]], ptr %{{.+}}, align 16
// NO__ERRNO-NEXT: store x86_fp80 [[SINCOSPI_F80_1]], ptr %{{.+}}, align 16


// HAS_ERRNO: declare double @fmod(double noundef, double noundef) [[NOT_READNONE:#[0-9]+]]
// HAS_ERRNO: declare float @fmodf(float noundef, float noundef) [[NOT_READNONE]]
// HAS_ERRNO: declare x86_fp80 @fmodl(x86_fp80 noundef, x86_fp80 noundef) [[NOT_READNONE]]
Expand Down Expand Up @@ -700,6 +719,14 @@ __builtin_sincos(f,d,d); __builtin_sincosf(f,fp,fp); __builtin_sincosl(f,l,l); _
// HAS_ERRNO: declare void @sincosl(x86_fp80 noundef, ptr noundef, ptr noundef) [[NOT_READNONE]]
// HAS_ERRNO: declare void @sincosf128(fp128 noundef, ptr noundef, ptr noundef) [[NOT_READNONE]]

__builtin_sincospi(f,d,d); __builtin_sincospif(f,fp,fp); __builtin_sincospil(f,l,l);
// NO__ERRNO: declare { double, double } @llvm.sincospi.f64(double) [[READNONE_INTRINSIC]]
// NO__ERRNO: declare { float, float } @llvm.sincospi.f32(float) [[READNONE_INTRINSIC]]
// NO__ERRNO: declare { x86_fp80, x86_fp80 } @llvm.sincospi.f80(x86_fp80) [[READNONE_INTRINSIC]]
// HAS_ERRNO: declare void @sincospi(double noundef, ptr noundef, ptr noundef) [[NOT_READNONE]]
// HAS_ERRNO: declare void @sincospif(float noundef, ptr noundef, ptr noundef) [[NOT_READNONE]]
// HAS_ERRNO: declare void @sincospil(x86_fp80 noundef, ptr noundef, ptr noundef) [[NOT_READNONE]]

__builtin_sqrt(f); __builtin_sqrtf(f); __builtin_sqrtl(f); __builtin_sqrtf128(f);

// NO__ERRNO: declare double @llvm.sqrt.f64(double) [[READNONE_INTRINSIC]]
Expand Down