Skip to content

Commit

Permalink
Emit constrained atan2 intrinsic for clang builtin
Browse files Browse the repository at this point in the history
This change is part of this proposal: https://discourse.llvm.org/t/rfc-all-the-math-intrinsics/78294

- `Builtins.td` - Add f16 support for libm atan2 builtin
- `CGBuiltin.cpp` - Emit constraint atan2 intrinsic for clang builtin

Part of Implement the atan2 HLSL Function llvm#70096.
  • Loading branch information
tex3d committed Oct 21, 2024
1 parent 8c975b3 commit a78cf25
Show file tree
Hide file tree
Showing 8 changed files with 49 additions and 29 deletions.
6 changes: 3 additions & 3 deletions clang/include/clang/Basic/Builtins.td
Original file line number Diff line number Diff line change
Expand Up @@ -227,10 +227,10 @@ def FminimumNumF16F128 : Builtin, F16F128MathTemplate {
let Prototype = "T(T, T)";
}

def Atan2F128 : Builtin {
let Spellings = ["__builtin_atan2f128"];
def Atan2F16F128 : Builtin, F16F128MathTemplate {
let Spellings = ["__builtin_atan2"];
let Attributes = [FunctionWithBuiltinPrefix, NoThrow, ConstIgnoringErrnoAndExceptions];
let Prototype = "__float128(__float128, __float128)";
let Prototype = "T(T, T)";
}

def CopysignF16 : Builtin {
Expand Down
11 changes: 11 additions & 0 deletions clang/lib/CodeGen/CGBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2724,6 +2724,17 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
return RValue::get(emitUnaryMaybeConstrainedFPBuiltin(
*this, E, Intrinsic::atan, Intrinsic::experimental_constrained_atan));

case Builtin::BIatan2:
case Builtin::BIatan2f:
case Builtin::BIatan2l:
case Builtin::BI__builtin_atan2:
case Builtin::BI__builtin_atan2f:
case Builtin::BI__builtin_atan2f16:
case Builtin::BI__builtin_atan2l:
case Builtin::BI__builtin_atan2f128:
return RValue::get(emitBinaryMaybeConstrainedFPBuiltin(
*this, E, Intrinsic::atan2, Intrinsic::experimental_constrained_atan2));

case Builtin::BIceil:
case Builtin::BIceilf:
case Builtin::BIceill:
Expand Down
14 changes: 7 additions & 7 deletions clang/test/CodeGen/X86/math-builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,18 +45,18 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) {

__builtin_atan2(f,f); __builtin_atan2f(f,f) ; __builtin_atan2l(f, f); __builtin_atan2f128(f,f);

// NO__ERRNO: declare double @atan2(double noundef, double noundef) [[READNONE:#[0-9]+]]
// NO__ERRNO: declare float @atan2f(float noundef, float noundef) [[READNONE]]
// NO__ERRNO: declare x86_fp80 @atan2l(x86_fp80 noundef, x86_fp80 noundef) [[READNONE]]
// NO__ERRNO: declare fp128 @atan2f128(fp128 noundef, fp128 noundef) [[READNONE]]
// NO__ERRNO: declare double @llvm.atan2.f64(double, double) [[READNONE_INTRINSIC:#[0-9]+]]
// NO__ERRNO: declare float @llvm.atan2.f32(float, float) [[READNONE_INTRINSIC]]
// NO__ERRNO: declare x86_fp80 @llvm.atan2.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]]
// NO__ERRNO: declare fp128 @llvm.atan2.f128(fp128, fp128) [[READNONE_INTRINSIC]]
// HAS_ERRNO: declare double @atan2(double noundef, double noundef) [[NOT_READNONE]]
// HAS_ERRNO: declare float @atan2f(float noundef, float noundef) [[NOT_READNONE]]
// HAS_ERRNO: declare x86_fp80 @atan2l(x86_fp80 noundef, x86_fp80 noundef) [[NOT_READNONE]]
// HAS_ERRNO: declare fp128 @atan2f128(fp128 noundef, fp128 noundef) [[NOT_READNONE]]

__builtin_copysign(f,f); __builtin_copysignf(f,f); __builtin_copysignl(f,f); __builtin_copysignf128(f,f);

// NO__ERRNO: declare double @llvm.copysign.f64(double, double) [[READNONE_INTRINSIC:#[0-9]+]]
// NO__ERRNO: declare double @llvm.copysign.f64(double, double) [[READNONE_INTRINSIC]]
// NO__ERRNO: declare float @llvm.copysign.f32(float, float) [[READNONE_INTRINSIC]]
// NO__ERRNO: declare x86_fp80 @llvm.copysign.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]]
// NO__ERRNO: declare fp128 @llvm.copysign.f128(fp128, fp128) [[READNONE_INTRINSIC]]
Expand Down Expand Up @@ -179,7 +179,7 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) {

__builtin_acosh(f); __builtin_acoshf(f); __builtin_acoshl(f); __builtin_acoshf128(f);

// NO__ERRNO: declare double @acosh(double noundef) [[READNONE]]
// NO__ERRNO: declare double @acosh(double noundef) [[READNONE:#[0-9]+]]
// NO__ERRNO: declare float @acoshf(float noundef) [[READNONE]]
// NO__ERRNO: declare x86_fp80 @acoshl(x86_fp80 noundef) [[READNONE]]
// NO__ERRNO: declare fp128 @acoshf128(fp128 noundef) [[READNONE]]
Expand Down Expand Up @@ -721,10 +721,10 @@ __builtin_trunc(f); __builtin_truncf(f); __builtin_truncl(f); __builtin
// HAS_ERRNO: declare fp128 @llvm.trunc.f128(fp128) [[READNONE_INTRINSIC]]
};

// NO__ERRNO: attributes [[READNONE]] = { {{.*}}memory(none){{.*}} }
// NO__ERRNO: attributes [[READNONE_INTRINSIC]] = { {{.*}}memory(none){{.*}} }
// NO__ERRNO: attributes [[NOT_READNONE]] = { nounwind {{.*}} }
// NO__ERRNO: attributes [[PURE]] = { {{.*}}memory(read){{.*}} }
// NO__ERRNO: attributes [[READNONE]] = { {{.*}}memory(none){{.*}} }

// HAS_ERRNO: attributes [[NOT_READNONE]] = { nounwind {{.*}} }
// HAS_ERRNO: attributes [[READNONE_INTRINSIC]] = { {{.*}}memory(none){{.*}} }
Expand Down
7 changes: 7 additions & 0 deletions clang/test/CodeGen/constrained-math-builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@ __builtin_atan(f); __builtin_atanf(f); __builtin_atanl(f); __builti
// CHECK: call x86_fp80 @llvm.experimental.constrained.atan.f80(x86_fp80 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict")
// CHECK: call fp128 @llvm.experimental.constrained.atan.f128(fp128 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict")

__builtin_atan2(f,f); __builtin_atan2f(f,f); __builtin_atan2l(f,f); __builtin_atan2f128(f,f);

// CHECK: call double @llvm.experimental.constrained.atan2.f64(double %{{.*}}, double %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict")
// CHECK: call float @llvm.experimental.constrained.atan2.f32(float %{{.*}}, float %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict")
// CHECK: call x86_fp80 @llvm.experimental.constrained.atan2.f80(x86_fp80 %{{.*}}, x86_fp80 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict")
// CHECK: call fp128 @llvm.experimental.constrained.atan2.f128(fp128 %{{.*}}, fp128 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict")

__builtin_ceil(f); __builtin_ceilf(f); __builtin_ceill(f); __builtin_ceilf128(f);

// CHECK: call double @llvm.experimental.constrained.ceil.f64(double %{{.*}}, metadata !"fpexcept.strict")
Expand Down
7 changes: 3 additions & 4 deletions clang/test/CodeGen/libcalls.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,9 @@ void test_builtins(double d, float f, long double ld) {
double atan2_ = atan2(d, 2);
long double atan2l_ = atan2l(ld, ld);
float atan2f_ = atan2f(f, f);
// CHECK-NO: declare double @atan2(double noundef, double noundef) [[NUW_RN:#[0-9]+]]
// CHECK-NO: declare x86_fp80 @atan2l(x86_fp80 noundef, x86_fp80 noundef) [[NUW_RN]]
// CHECK-NO: declare float @atan2f(float noundef, float noundef) [[NUW_RN]]
// CHECK-NO: declare double @llvm.atan2.f64(double, double) [[NUW_RNI]]
// CHECK-NO: declare x86_fp80 @llvm.atan2.f80(x86_fp80, x86_fp80) [[NUW_RNI]]
// CHECK-NO: declare float @llvm.atan2.f32(float, float) [[NUW_RNI]]
// CHECK-YES: declare double @atan2(double noundef, double noundef) [[NUW]]
// CHECK-YES: declare x86_fp80 @atan2l(x86_fp80 noundef, x86_fp80 noundef) [[NUW]]
// CHECK-YES: declare float @atan2f(float noundef, float noundef) [[NUW]]
Expand All @@ -124,5 +124,4 @@ void test_builtins(double d, float f, long double ld) {
}

// CHECK-YES: attributes [[NUW]] = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+x87" }
// CHECK-NO-DAG: attributes [[NUW_RN]] = { nounwind willreturn memory(none){{.*}} }
// CHECK-NO-DAG: attributes [[NUW_RNI]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
20 changes: 10 additions & 10 deletions clang/test/CodeGen/math-libcalls.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,19 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) {

atan2(f,f); atan2f(f,f) ; atan2l(f, f);

// NO__ERRNO: declare double @atan2(double noundef, double noundef) [[READNONE:#[0-9]+]]
// NO__ERRNO: declare float @atan2f(float noundef, float noundef) [[READNONE]]
// NO__ERRNO: declare x86_fp80 @atan2l(x86_fp80 noundef, x86_fp80 noundef) [[READNONE]]
// NO__ERRNO: declare double @llvm.atan2.f64(double, double) [[READNONE_INTRINSIC:#[0-9]+]]
// NO__ERRNO: declare float @llvm.atan2.f32(float, float) [[READNONE_INTRINSIC]]
// NO__ERRNO: declare x86_fp80 @llvm.atan2.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]]
// HAS_ERRNO: declare double @atan2(double noundef, double noundef) [[NOT_READNONE]]
// HAS_ERRNO: declare float @atan2f(float noundef, float noundef) [[NOT_READNONE]]
// HAS_ERRNO: declare x86_fp80 @atan2l(x86_fp80 noundef, x86_fp80 noundef) [[NOT_READNONE]]
// HAS_MAYTRAP: declare double @atan2(double noundef, double noundef) [[NOT_READNONE:#[0-9]+]]
// HAS_MAYTRAP: declare float @atan2f(float noundef, float noundef) [[NOT_READNONE]]
// HAS_MAYTRAP: declare x86_fp80 @atan2l(x86_fp80 noundef, x86_fp80 noundef) [[NOT_READNONE]]
// HAS_MAYTRAP: declare double @llvm.experimental.constrained.atan2.f64(
// HAS_MAYTRAP: declare float @llvm.experimental.constrained.atan2.f32(
// HAS_MAYTRAP: declare x86_fp80 @llvm.experimental.constrained.atan2.f80(

copysign(f,f); copysignf(f,f);copysignl(f,f);

// NO__ERRNO: declare double @llvm.copysign.f64(double, double) [[READNONE_INTRINSIC:#[0-9]+]]
// NO__ERRNO: declare double @llvm.copysign.f64(double, double) [[READNONE_INTRINSIC]]
// NO__ERRNO: declare float @llvm.copysign.f32(float, float) [[READNONE_INTRINSIC]]
// NO__ERRNO: declare x86_fp80 @llvm.copysign.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]]
// HAS_ERRNO: declare double @llvm.copysign.f64(double, double) [[READNONE_INTRINSIC:#[0-9]+]]
Expand Down Expand Up @@ -65,13 +65,13 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) {
// HAS_ERRNO: declare double @frexp(double noundef, ptr noundef) [[NOT_READNONE]]
// HAS_ERRNO: declare float @frexpf(float noundef, ptr noundef) [[NOT_READNONE]]
// HAS_ERRNO: declare x86_fp80 @frexpl(x86_fp80 noundef, ptr noundef) [[NOT_READNONE]]
// HAS_MAYTRAP: declare double @frexp(double noundef, ptr noundef) [[NOT_READNONE]]
// HAS_MAYTRAP: declare double @frexp(double noundef, ptr noundef) [[NOT_READNONE:#[0-9]+]]
// HAS_MAYTRAP: declare float @frexpf(float noundef, ptr noundef) [[NOT_READNONE]]
// HAS_MAYTRAP: declare x86_fp80 @frexpl(x86_fp80 noundef, ptr noundef) [[NOT_READNONE]]

ldexp(f,f); ldexpf(f,f); ldexpl(f,f);

// NO__ERRNO: declare double @ldexp(double noundef, i32 noundef) [[READNONE]]
// NO__ERRNO: declare double @ldexp(double noundef, i32 noundef) [[READNONE:#[0-9]+]]
// NO__ERRNO: declare float @ldexpf(float noundef, i32 noundef) [[READNONE]]
// NO__ERRNO: declare x86_fp80 @ldexpl(x86_fp80 noundef, i32 noundef) [[READNONE]]
// HAS_ERRNO: declare double @ldexp(double noundef, i32 noundef) [[NOT_READNONE]]
Expand Down Expand Up @@ -719,9 +719,9 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) {
// HAS_ERRNO: declare x86_fp80 @llvm.trunc.f80(x86_fp80) [[READNONE_INTRINSIC]]
};

// NO__ERRNO: attributes [[READNONE]] = { {{.*}}memory(none){{.*}} }
// NO__ERRNO: attributes [[READNONE_INTRINSIC]] = { {{.*}}memory(none){{.*}} }
// NO__ERRNO: attributes [[NOT_READNONE]] = { nounwind {{.*}} }
// NO__ERRNO: attributes [[READNONE]] = { {{.*}}memory(none){{.*}} }
// NO__ERRNO: attributes [[READONLY]] = { {{.*}}memory(read){{.*}} }

// HAS_ERRNO: attributes [[NOT_READNONE]] = { nounwind {{.*}} }
Expand Down
10 changes: 5 additions & 5 deletions clang/test/CodeGenCXX/builtin-calling-conv.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// RUN: %clang_cc1 -triple x86_64-linux-pc -DREDECL -emit-llvm %s -o - | FileCheck %s -check-prefix LINUX
// RUN: %clang_cc1 -triple spir-unknown-unknown -DREDECL -DSPIR -emit-llvm %s -o - | FileCheck %s -check-prefix SPIR
// RUN: %clang_cc1 -triple x86_64-linux-pc -emit-llvm %s -o - | FileCheck %s -check-prefix LINUX
// RUN: %clang_cc1 -triple spir-unknown-unknown -DSPIR -emit-llvm %s -o - | FileCheck %s -check-prefix SPIR
// RUN: %clang_cc1 -triple i386-windows-pc -fdefault-calling-conv=stdcall -emit-llvm %s -o - | FileCheck %s -check-prefix WIN32
// RUN: %clang_cc1 -triple x86_64-linux-pc -DREDECL -emit-llvm -fmath-errno %s -o - | FileCheck %s -check-prefix LINUX
// RUN: %clang_cc1 -triple spir-unknown-unknown -DREDECL -DSPIR -emit-llvm -fmath-errno %s -o - | FileCheck %s -check-prefix SPIR
// RUN: %clang_cc1 -triple x86_64-linux-pc -emit-llvm -fmath-errno %s -o - | FileCheck %s -check-prefix LINUX
// RUN: %clang_cc1 -triple spir-unknown-unknown -DSPIR -emit-llvm -fmath-errno %s -o - | FileCheck %s -check-prefix SPIR
// RUN: %clang_cc1 -triple i386-windows-pc -fdefault-calling-conv=stdcall -emit-llvm -fmath-errno %s -o - | FileCheck %s -check-prefix WIN32

#ifdef REDECL
namespace std {
Expand Down
3 changes: 3 additions & 0 deletions clang/test/CodeGenOpenCL/builtins-f16.cl
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ void test_half_builtins(half h0, half h1, half h2, int i0) {
// CHECK: call half @llvm.atan.f16(half %h0)
res = __builtin_atanf16(h0);

// CHECK: call half @llvm.atan2.f16(half %h0, half %h1)
res = __builtin_atan2f16(h0, h1);

// CHECK: call half @llvm.copysign.f16(half %h0, half %h1)
res = __builtin_copysignf16(h0, h1);

Expand Down

0 comments on commit a78cf25

Please sign in to comment.