Skip to content

[clang] Lower non-builtin sincos[f|l] calls to llvm.sincos.* when -fno-math-errno is set #121763

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 5 commits into from
Feb 19, 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
5 changes: 5 additions & 0 deletions clang/lib/CodeGen/CGBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3377,11 +3377,16 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
return RValue::get(emitUnaryMaybeConstrainedFPBuiltin(
*this, E, Intrinsic::sinh, Intrinsic::experimental_constrained_sinh));

case Builtin::BIsincos:
case Builtin::BIsincosf:
case Builtin::BIsincosl:
case Builtin::BI__builtin_sincos:
case Builtin::BI__builtin_sincosf:
case Builtin::BI__builtin_sincosf16:
case Builtin::BI__builtin_sincosl:
case Builtin::BI__builtin_sincosf128:
if (Builder.getIsFPConstrained())
break; // TODO: Emit constrained sincos intrinsic once one exists.
emitSincosBuiltin(*this, E, Intrinsic::sincos);
return RValue::get(nullptr);

Expand Down
46 changes: 46 additions & 0 deletions clang/test/CodeGen/AArch64/sincos.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
// 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

void sincos(double, double*, double*);
void sincosf(float, float*, float*);
void sincosl(long double, long double*, long double*);

// NO-MATH-ERRNO-LABEL: @sincos_f32
// NO-MATH-ERRNO: [[SINCOS:%.*]] = tail call { float, float } @llvm.sincos.f32(float {{.*}})
// NO-MATH-ERRNO-NEXT: [[SIN:%.*]] = extractvalue { float, float } [[SINCOS]], 0
Expand All @@ -12,6 +16,20 @@
// MATH-ERRNO: call void @sincosf(
//
void sincos_f32(float x, float* fp0, float* fp1) {
sincosf(x, fp0, fp1);
}

// NO-MATH-ERRNO-LABEL: @sincos_builtin_f32
// NO-MATH-ERRNO: [[SINCOS:%.*]] = tail call { float, float } @llvm.sincos.f32(float {{.*}})
// NO-MATH-ERRNO-NEXT: [[SIN:%.*]] = extractvalue { float, float } [[SINCOS]], 0
// NO-MATH-ERRNO-NEXT: [[COS:%.*]] = extractvalue { float, float } [[SINCOS]], 1
// NO-MATH-ERRNO-NEXT: store float [[SIN]], ptr {{.*}}, align 4, !alias.scope [[SINCOS_ALIAS_SCOPE:![0-9]+]]
// NO-MATH-ERRNO-NEXT: store float [[COS]], ptr {{.*}}, align 4, !noalias [[SINCOS_ALIAS_SCOPE]]
//
// MATH-ERRNO-LABEL: @sincos_builtin_f32
// MATH-ERRNO: call void @sincosf(
//
void sincos_builtin_f32(float x, float* fp0, float* fp1) {
__builtin_sincosf(x, fp0, fp1);
}

Expand All @@ -26,6 +44,20 @@ void sincos_f32(float x, float* fp0, float* fp1) {
// MATH-ERRNO: call void @sincos(
//
void sincos_f64(double x, double* dp0, double* dp1) {
sincos(x, dp0, dp1);
}

// NO-MATH-ERRNO-LABEL: @sincos_builtin_f64
// NO-MATH-ERRNO: [[SINCOS:%.*]] = tail call { double, double } @llvm.sincos.f64(double {{.*}})
// NO-MATH-ERRNO-NEXT: [[SIN:%.*]] = extractvalue { double, double } [[SINCOS]], 0
// NO-MATH-ERRNO-NEXT: [[COS:%.*]] = extractvalue { double, double } [[SINCOS]], 1
// NO-MATH-ERRNO-NEXT: store double [[SIN]], ptr {{.*}}, align 8, !alias.scope [[SINCOS_ALIAS_SCOPE:![0-9]+]]
// NO-MATH-ERRNO-NEXT: store double [[COS]], ptr {{.*}}, align 8, !noalias [[SINCOS_ALIAS_SCOPE]]
//
// MATH-ERRNO-LABEL: @sincos_builtin_f64
// MATH-ERRNO: call void @sincos(
//
void sincos_builtin_f64(double x, double* dp0, double* dp1) {
__builtin_sincos(x, dp0, dp1);
}

Expand All @@ -40,5 +72,19 @@ void sincos_f64(double x, double* dp0, double* dp1) {
// MATH-ERRNO: call void @sincosl(
//
void sincos_f128(long double x, long double* ldp0, long double* ldp1) {
sincosl(x, ldp0, ldp1);
}

// NO-MATH-ERRNO-LABEL: @sincos_builtin_f128
// NO-MATH-ERRNO: [[SINCOS:%.*]] = tail call { fp128, fp128 } @llvm.sincos.f128(fp128 {{.*}})
// NO-MATH-ERRNO-NEXT: [[SIN:%.*]] = extractvalue { fp128, fp128 } [[SINCOS]], 0
// NO-MATH-ERRNO-NEXT: [[COS:%.*]] = extractvalue { fp128, fp128 } [[SINCOS]], 1
// NO-MATH-ERRNO-NEXT: store fp128 [[SIN]], ptr {{.*}}, align 16, !alias.scope [[SINCOS_ALIAS_SCOPE:![0-9]+]]
// NO-MATH-ERRNO-NEXT: store fp128 [[COS]], ptr {{.*}}, align 16, !noalias [[SINCOS_ALIAS_SCOPE]]
//
// MATH-ERRNO-LABEL: @sincos_builtin_f128
// MATH-ERRNO: call void @sincosl(
//
void sincos_builtin_f128(long double x, long double* ldp0, long double* ldp1) {
__builtin_sincosl(x, ldp0, ldp1);
}
11 changes: 11 additions & 0 deletions clang/test/CodeGen/math-libcalls.c
Original file line number Diff line number Diff line change
Expand Up @@ -660,6 +660,17 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) {
// HAS_MAYTRAP: declare float @llvm.experimental.constrained.sinh.f32(
// HAS_MAYTRAP: declare x86_fp80 @llvm.experimental.constrained.sinh.f80(

sincos(f, d, d); sincosf(f, fp, fp); sincosl(f, l, l);

// NO__ERRNO: declare { double, double } @llvm.sincos.f64(double) [[READNONE_INTRINSIC]]
// NO__ERRNO: declare { float, float } @llvm.sincos.f32(float) [[READNONE_INTRINSIC]]
// NO__ERRNO: declare { x86_fp80, x86_fp80 } @llvm.sincos.f80(x86_fp80) [[READNONE_INTRINSIC]]
// HAS_ERRNO: declare void @sincos(double noundef, ptr noundef, ptr noundef) [[NOT_READNONE]]
// HAS_ERRNO: declare void @sincosf(float noundef, ptr noundef, ptr noundef) [[NOT_READNONE]]
// HAS_ERRNO: declare void @sincosl(x86_fp80 noundef, ptr noundef, ptr noundef) [[NOT_READNONE]]
// HAS_MAYTRAP: declare void @sincos(double noundef, ptr noundef, ptr noundef) [[NOT_READNONE]]
// HAS_MAYTRAP: declare void @sincosf(float noundef, ptr noundef, ptr noundef) [[NOT_READNONE]]
// HAS_MAYTRAP: declare void @sincosl(x86_fp80 noundef, ptr noundef, ptr noundef) [[NOT_READNONE]]

sqrt(f); sqrtf(f); sqrtl(f);

Expand Down