Skip to content

Commit 5a7ee43

Browse files
authored
[clang] Add __builtin_sincospi that lowers to llvm.sincospi.* (#127065)
This (only) adds the `__builtin` variant which lowers to the `llvm.sincospi.*` intrinsic when `-fno-math-errno` is set.
1 parent d12a4d4 commit 5a7ee43

File tree

4 files changed

+102
-0
lines changed

4 files changed

+102
-0
lines changed

clang/include/clang/Basic/Builtins.td

+6
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,12 @@ def TruncF16F128 : Builtin, F16F128MathTemplate {
521521
let Prototype = "T(T)";
522522
}
523523

524+
def Sincospi : Builtin, FPMathTemplate {
525+
let Spellings = ["__builtin_sincospi"];
526+
let Attributes = [FunctionWithBuiltinPrefix, NoThrow];
527+
let Prototype = "void(T, T*, T*)";
528+
}
529+
524530
// Access to floating point environment.
525531
def BuiltinFltRounds : Builtin {
526532
let Spellings = ["__builtin_flt_rounds"];

clang/lib/CodeGen/CGBuiltin.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -3377,6 +3377,14 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
33773377
return RValue::get(emitUnaryMaybeConstrainedFPBuiltin(
33783378
*this, E, Intrinsic::sinh, Intrinsic::experimental_constrained_sinh));
33793379

3380+
case Builtin::BI__builtin_sincospi:
3381+
case Builtin::BI__builtin_sincospif:
3382+
case Builtin::BI__builtin_sincospil:
3383+
if (Builder.getIsFPConstrained())
3384+
break; // TODO: Emit constrained sincospi intrinsic once one exists.
3385+
emitSincosBuiltin(*this, E, Intrinsic::sincospi);
3386+
return RValue::get(nullptr);
3387+
33803388
case Builtin::BIsincos:
33813389
case Builtin::BIsincosf:
33823390
case Builtin::BIsincosl:

clang/test/CodeGen/AArch64/sincos.c

+61
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// RUN: %clang_cc1 -triple=aarch64-gnu-linux -emit-llvm -O1 %s -o - | FileCheck --check-prefix=NO-MATH-ERRNO %s
22
// RUN: %clang_cc1 -triple=aarch64-gnu-linux -emit-llvm -fmath-errno %s -o - | FileCheck --check-prefix=MATH-ERRNO %s
3+
// RUN: %clang_cc1 -triple=aarch64-gnu-linux -emit-llvm -ffp-exception-behavior=strict %s -o - | FileCheck --check-prefix=STRICT-FP %s
34

45
void sincos(double, double*, double*);
56
void sincosf(float, float*, float*);
@@ -15,6 +16,9 @@ void sincosl(long double, long double*, long double*);
1516
// MATH-ERRNO-LABEL: @sincos_f32
1617
// MATH-ERRNO: call void @sincosf(
1718
//
19+
// STRICT-FP-LABEL: @sincos_f32
20+
// STRICT-FP: call void @sincosf(
21+
//
1822
void sincos_f32(float x, float* fp0, float* fp1) {
1923
sincosf(x, fp0, fp1);
2024
}
@@ -43,6 +47,9 @@ void sincos_builtin_f32(float x, float* fp0, float* fp1) {
4347
// MATH-ERRNO-LABEL: @sincos_f64
4448
// MATH-ERRNO: call void @sincos(
4549
//
50+
// STRICT-FP-LABEL: @sincos_f64
51+
// STRICT-FP: call void @sincos(
52+
//
4653
void sincos_f64(double x, double* dp0, double* dp1) {
4754
sincos(x, dp0, dp1);
4855
}
@@ -71,6 +78,9 @@ void sincos_builtin_f64(double x, double* dp0, double* dp1) {
7178
// MATH-ERRNO-LABEL: @sincos_f128
7279
// MATH-ERRNO: call void @sincosl(
7380
//
81+
// STRICT-FP-LABEL: @sincos_f128
82+
// STRICT-FP: call void @sincosl(
83+
//
7484
void sincos_f128(long double x, long double* ldp0, long double* ldp1) {
7585
sincosl(x, ldp0, ldp1);
7686
}
@@ -88,3 +98,54 @@ void sincos_f128(long double x, long double* ldp0, long double* ldp1) {
8898
void sincos_builtin_f128(long double x, long double* ldp0, long double* ldp1) {
8999
__builtin_sincosl(x, ldp0, ldp1);
90100
}
101+
102+
// NO-MATH-ERRNO-LABEL: @sincospi_f32
103+
// NO-MATH-ERRNO: [[SINCOSPI:%.*]] = tail call { float, float } @llvm.sincospi.f32(float {{.*}})
104+
// NO-MATH-ERRNO-NEXT: [[SINPI:%.*]] = extractvalue { float, float } [[SINCOSPI]], 0
105+
// NO-MATH-ERRNO-NEXT: [[COSPI:%.*]] = extractvalue { float, float } [[SINCOSPI]], 1
106+
// NO-MATH-ERRNO-NEXT: store float [[SINPI]], ptr {{.*}}, align 4, !alias.scope [[SINCOSPI_ALIAS_SCOPE:![0-9]+]]
107+
// NO-MATH-ERRNO-NEXT: store float [[COSPI]], ptr {{.*}}, align 4, !noalias [[SINCOSPI_ALIAS_SCOPE]]
108+
//
109+
// MATH-ERRNO-LABEL: @sincospi_f32
110+
// MATH-ERRNO: call void @sincospif(
111+
//
112+
// STRICT-FP-LABEL: @sincospi_f32
113+
// STRICT-FP: call void @sincospif(
114+
//
115+
void sincospi_f32(float x, float* fp0, float* fp1) {
116+
__builtin_sincospif(x, fp0, fp1);
117+
}
118+
119+
// NO-MATH-ERRNO-LABEL: @sincospi_f64
120+
// NO-MATH-ERRNO: [[SINCOSPI:%.*]] = tail call { double, double } @llvm.sincospi.f64(double {{.*}})
121+
// NO-MATH-ERRNO-NEXT: [[SINPI:%.*]] = extractvalue { double, double } [[SINCOSPI]], 0
122+
// NO-MATH-ERRNO-NEXT: [[COSPI:%.*]] = extractvalue { double, double } [[SINCOSPI]], 1
123+
// NO-MATH-ERRNO-NEXT: store double [[SINPI]], ptr {{.*}}, align 8, !alias.scope [[SINCOSPI_ALIAS_SCOPE:![0-9]+]]
124+
// NO-MATH-ERRNO-NEXT: store double [[COSPI]], ptr {{.*}}, align 8, !noalias [[SINCOSPI_ALIAS_SCOPE]]
125+
//
126+
// MATH-ERRNO-LABEL: @sincospi_f64
127+
// MATH-ERRNO: call void @sincospi(
128+
//
129+
// STRICT-FP-LABEL: @sincospi_f64
130+
// STRICT-FP: call void @sincospi(
131+
//
132+
void sincospi_f64(double x, double* dp0, double* dp1) {
133+
__builtin_sincospi(x, dp0, dp1);
134+
}
135+
136+
// NO-MATH-ERRNO-LABEL: @sincospi_f128
137+
// NO-MATH-ERRNO: [[SINCOSPI:%.*]] = tail call { fp128, fp128 } @llvm.sincospi.f128(fp128 {{.*}})
138+
// NO-MATH-ERRNO-NEXT: [[SINPI:%.*]] = extractvalue { fp128, fp128 } [[SINCOSPI]], 0
139+
// NO-MATH-ERRNO-NEXT: [[COSPI:%.*]] = extractvalue { fp128, fp128 } [[SINCOSPI]], 1
140+
// NO-MATH-ERRNO-NEXT: store fp128 [[SINPI]], ptr {{.*}}, align 16, !alias.scope [[SINCOSPI_ALIAS_SCOPE:![0-9]+]]
141+
// NO-MATH-ERRNO-NEXT: store fp128 [[COSPI]], ptr {{.*}}, align 16, !noalias [[SINCOSPI_ALIAS_SCOPE]]
142+
//
143+
// MATH-ERRNO-LABEL: @sincospi_f128
144+
// MATH-ERRNO: call void @sincospil(
145+
//
146+
// STRICT-FP-LABEL: @sincospi_f128
147+
// STRICT-FP: call void @sincospil(
148+
//
149+
void sincospi_f128(long double x, long double* ldp0, long double* ldp1) {
150+
__builtin_sincospil(x, ldp0, ldp1);
151+
}

clang/test/CodeGen/X86/math-builtins.c

+27
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,25 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) {
6363
// NO__ERRNO-NEXT: store fp128 [[SINCOS_F128_1]], ptr %{{.+}}, align 16
6464

6565

66+
// NO__ERRNO: [[SINCOSPI_F64:%.+]] = call { double, double } @llvm.sincospi.f64(double %{{.+}})
67+
// NO__ERRNO-NEXT: [[SINCOSPI_F64_0:%.+]] = extractvalue { double, double } [[SINCOSPI_F64]], 0
68+
// NO__ERRNO-NEXT: [[SINCOSPI_F64_1:%.+]] = extractvalue { double, double } [[SINCOSPI_F64]], 1
69+
// NO__ERRNO-NEXT: store double [[SINCOSPI_F64_0]], ptr %{{.+}}, align 8
70+
// NO__ERRNO-NEXT: store double [[SINCOSPI_F64_1]], ptr %{{.+}}, align 8
71+
72+
// NO__ERRNO: [[SINCOSPI_F32:%.+]] = call { float, float } @llvm.sincospi.f32(float %{{.+}})
73+
// NO__ERRNO-NEXT: [[SINCOSPI_F32_0:%.+]] = extractvalue { float, float } [[SINCOSPI_F32]], 0
74+
// NO__ERRNO-NEXT: [[SINCOSPI_F32_1:%.+]] = extractvalue { float, float } [[SINCOSPI_F32]], 1
75+
// NO__ERRNO-NEXT: store float [[SINCOSPI_F32_0]], ptr %{{.+}}, align 4
76+
// NO__ERRNO-NEXT: store float [[SINCOSPI_F32_1]], ptr %{{.+}}, align 4
77+
78+
// NO__ERRNO: [[SINCOSPI_F80:%.+]] = call { x86_fp80, x86_fp80 } @llvm.sincospi.f80(x86_fp80 %{{.+}})
79+
// NO__ERRNO-NEXT: [[SINCOSPI_F80_0:%.+]] = extractvalue { x86_fp80, x86_fp80 } [[SINCOSPI_F80]], 0
80+
// NO__ERRNO-NEXT: [[SINCOSPI_F80_1:%.+]] = extractvalue { x86_fp80, x86_fp80 } [[SINCOSPI_F80]], 1
81+
// NO__ERRNO-NEXT: store x86_fp80 [[SINCOSPI_F80_0]], ptr %{{.+}}, align 16
82+
// NO__ERRNO-NEXT: store x86_fp80 [[SINCOSPI_F80_1]], ptr %{{.+}}, align 16
83+
84+
6685
// HAS_ERRNO: declare double @fmod(double noundef, double noundef) [[NOT_READNONE:#[0-9]+]]
6786
// HAS_ERRNO: declare float @fmodf(float noundef, float noundef) [[NOT_READNONE]]
6887
// HAS_ERRNO: declare x86_fp80 @fmodl(x86_fp80 noundef, x86_fp80 noundef) [[NOT_READNONE]]
@@ -700,6 +719,14 @@ __builtin_sincos(f,d,d); __builtin_sincosf(f,fp,fp); __builtin_sincosl(f,l,l); _
700719
// HAS_ERRNO: declare void @sincosl(x86_fp80 noundef, ptr noundef, ptr noundef) [[NOT_READNONE]]
701720
// HAS_ERRNO: declare void @sincosf128(fp128 noundef, ptr noundef, ptr noundef) [[NOT_READNONE]]
702721

722+
__builtin_sincospi(f,d,d); __builtin_sincospif(f,fp,fp); __builtin_sincospil(f,l,l);
723+
// NO__ERRNO: declare { double, double } @llvm.sincospi.f64(double) [[READNONE_INTRINSIC]]
724+
// NO__ERRNO: declare { float, float } @llvm.sincospi.f32(float) [[READNONE_INTRINSIC]]
725+
// NO__ERRNO: declare { x86_fp80, x86_fp80 } @llvm.sincospi.f80(x86_fp80) [[READNONE_INTRINSIC]]
726+
// HAS_ERRNO: declare void @sincospi(double noundef, ptr noundef, ptr noundef) [[NOT_READNONE]]
727+
// HAS_ERRNO: declare void @sincospif(float noundef, ptr noundef, ptr noundef) [[NOT_READNONE]]
728+
// HAS_ERRNO: declare void @sincospil(x86_fp80 noundef, ptr noundef, ptr noundef) [[NOT_READNONE]]
729+
703730
__builtin_sqrt(f); __builtin_sqrtf(f); __builtin_sqrtl(f); __builtin_sqrtf128(f);
704731

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

0 commit comments

Comments
 (0)