-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[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
Conversation
@llvm/pr-subscribers-clang @llvm/pr-subscribers-backend-x86 Author: Benjamin Maxwell (MacDue) ChangesThis (only) adds the Full diff: https://github.com/llvm/llvm-project/pull/127065.diff 4 Files Affected:
diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td
index 29939242596ba..8473db8559947 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -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"];
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 361e4c4bf2e2e..5d982edc7f63c 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -3377,6 +3377,12 @@ 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:
+ emitSincosBuiltin(*this, E, Intrinsic::sincospi);
+ return RValue::get(nullptr);
+
case Builtin::BI__builtin_sincos:
case Builtin::BI__builtin_sincosf:
case Builtin::BI__builtin_sincosf16:
diff --git a/clang/test/CodeGen/AArch64/sincos.c b/clang/test/CodeGen/AArch64/sincos.c
index b77d98ceab486..9f21eeb7e2303 100644
--- a/clang/test/CodeGen/AArch64/sincos.c
+++ b/clang/test/CodeGen/AArch64/sincos.c
@@ -42,3 +42,45 @@ void sincos_f64(double x, double* dp0, double* dp1) {
void sincos_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(
+//
+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(
+//
+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(
+//
+void sincospi_f128(long double x, long double* ldp0, long double* ldp1) {
+ __builtin_sincospil(x, ldp0, ldp1);
+}
diff --git a/clang/test/CodeGen/X86/math-builtins.c b/clang/test/CodeGen/X86/math-builtins.c
index d7bf7d57fba26..481d3c043683e 100644
--- a/clang/test/CodeGen/X86/math-builtins.c
+++ b/clang/test/CodeGen/X86/math-builtins.c
@@ -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]]
@@ -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]]
|
@llvm/pr-subscribers-clang-codegen Author: Benjamin Maxwell (MacDue) ChangesThis (only) adds the Full diff: https://github.com/llvm/llvm-project/pull/127065.diff 4 Files Affected:
diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td
index 29939242596ba..8473db8559947 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -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"];
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 361e4c4bf2e2e..5d982edc7f63c 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -3377,6 +3377,12 @@ 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:
+ emitSincosBuiltin(*this, E, Intrinsic::sincospi);
+ return RValue::get(nullptr);
+
case Builtin::BI__builtin_sincos:
case Builtin::BI__builtin_sincosf:
case Builtin::BI__builtin_sincosf16:
diff --git a/clang/test/CodeGen/AArch64/sincos.c b/clang/test/CodeGen/AArch64/sincos.c
index b77d98ceab486..9f21eeb7e2303 100644
--- a/clang/test/CodeGen/AArch64/sincos.c
+++ b/clang/test/CodeGen/AArch64/sincos.c
@@ -42,3 +42,45 @@ void sincos_f64(double x, double* dp0, double* dp1) {
void sincos_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(
+//
+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(
+//
+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(
+//
+void sincospi_f128(long double x, long double* ldp0, long double* ldp1) {
+ __builtin_sincospil(x, ldp0, ldp1);
+}
diff --git a/clang/test/CodeGen/X86/math-builtins.c b/clang/test/CodeGen/X86/math-builtins.c
index d7bf7d57fba26..481d3c043683e 100644
--- a/clang/test/CodeGen/X86/math-builtins.c
+++ b/clang/test/CodeGen/X86/math-builtins.c
@@ -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]]
@@ -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]]
|
How does this interact with strictfp? Do we need a constrained version of sincospi which raises appropriate exceptions? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs test with strictfp enabled
I've disabled the intrinsic lowering for both I think I might need to cherry-pick the |
This (only) adds the `__builtin` variant which lowers to the `llvm.sincospi.*` intrinsic when `-fno-math-errno` is set.
485e188
to
c7fae05
Compare
This (only) adds the
__builtin
variant which lowers to thellvm.sincospi.*
intrinsic when-fno-math-errno
is set.