diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -635,6 +635,7 @@ T __builtin_elementwise_sin(T x) return the sine of x interpreted as an angle in radians floating point types T __builtin_elementwise_cos(T x) return the cosine of x interpreted as an angle in radians floating point types T __builtin_elementwise_floor(T x) return the largest integral value less than or equal to x floating point types + T __builtin_elementwise_log(T x) return the natural logarithm of x floating point types T __builtin_elementwise_roundeven(T x) round x to the nearest integer value in floating point format, floating point types rounding halfway cases to even (that is, to the nearest value that is an even integer), regardless of the current rounding diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -845,6 +845,7 @@ unsafe floating-point optimizations use ``-funsafe-math-optimizations`` or ``-ffast-math`` instead. - Add ``__builtin_elementwise_sin`` and ``__builtin_elementwise_cos`` builtins for floating point types only. +- Add ``__builtin_elementwise_log``builtin for floating point types only. Internal API Changes -------------------- diff --git a/clang/include/clang/Basic/Builtins.def b/clang/include/clang/Basic/Builtins.def --- a/clang/include/clang/Basic/Builtins.def +++ b/clang/include/clang/Basic/Builtins.def @@ -662,6 +662,7 @@ BUILTIN(__builtin_elementwise_ceil, "v.", "nct") BUILTIN(__builtin_elementwise_cos, "v.", "nct") BUILTIN(__builtin_elementwise_floor, "v.", "nct") +BUILTIN(__builtin_elementwise_log, "v.", "nct") BUILTIN(__builtin_elementwise_roundeven, "v.", "nct") BUILTIN(__builtin_elementwise_sin, "v.", "nct") BUILTIN(__builtin_elementwise_trunc, "v.", "nct") diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -3076,6 +3076,9 @@ case Builtin::BI__builtin_elementwise_ceil: return RValue::get( emitUnaryBuiltin(*this, E, llvm::Intrinsic::ceil, "elt.ceil")); + case Builtin::BI__builtin_elementwise_log: + return RValue::get( + emitUnaryBuiltin(*this, E, llvm::Intrinsic::log, "elt.log")); case Builtin::BI__builtin_elementwise_cos: return RValue::get( emitUnaryBuiltin(*this, E, llvm::Intrinsic::cos, "elt.cos")); diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -2575,6 +2575,7 @@ case Builtin::BI__builtin_elementwise_ceil: case Builtin::BI__builtin_elementwise_cos: case Builtin::BI__builtin_elementwise_floor: + case Builtin::BI__builtin_elementwise_log: case Builtin::BI__builtin_elementwise_roundeven: case Builtin::BI__builtin_elementwise_sin: case Builtin::BI__builtin_elementwise_trunc: { diff --git a/clang/test/CodeGen/builtins-elementwise-math.c b/clang/test/CodeGen/builtins-elementwise-math.c --- a/clang/test/CodeGen/builtins-elementwise-math.c +++ b/clang/test/CodeGen/builtins-elementwise-math.c @@ -365,6 +365,22 @@ vf2 = __builtin_elementwise_floor(vf1); } +void test_builtin_elementwise_log(float f1, float f2, double d1, double d2, + float4 vf1, float4 vf2) { + // CHECK-LABEL: define void @test_builtin_elementwise_log( + // CHECK: [[F1:%.+]] = load float, ptr %f1.addr, align 4 + // CHECK-NEXT: call float @llvm.log.f32(float [[F1]]) + f2 = __builtin_elementwise_log(f1); + + // CHECK: [[D1:%.+]] = load double, ptr %d1.addr, align 8 + // CHECK-NEXT: call double @llvm.log.f64(double [[D1]]) + d2 = __builtin_elementwise_log(d1); + + // CHECK: [[VF1:%.+]] = load <4 x float>, ptr %vf1.addr, align 16 + // CHECK-NEXT: call <4 x float> @llvm.log.v4f32(<4 x float> [[VF1]]) + vf2 = __builtin_elementwise_log(vf1); +} + void test_builtin_elementwise_roundeven(float f1, float f2, double d1, double d2, float4 vf1, float4 vf2) { // CHECK-LABEL: define void @test_builtin_elementwise_roundeven( diff --git a/clang/test/Sema/aarch64-sve-vector-log-ops.c b/clang/test/Sema/aarch64-sve-vector-log-ops.c new file mode 100644 --- /dev/null +++ b/clang/test/Sema/aarch64-sve-vector-log-ops.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -triple aarch64 -target-feature +f -target-feature +d \ +// RUN: -target-feature +v -target-feature +zfh -target-feature +sve -target-feature +experimental-zvfh \ +// RUN: -disable-O0-optnone -o - -fsyntax-only %s -verify +// REQUIRES: aarch64-registered-target + +#include + +svfloat32_t test_log_vv_i8mf8(svfloat32_t v) { + + return __builtin_elementwise_log(v); + // expected-error@-1 {{1st argument must be a vector, integer or floating point type}} +} diff --git a/clang/test/Sema/builtins-elementwise-math.c b/clang/test/Sema/builtins-elementwise-math.c --- a/clang/test/Sema/builtins-elementwise-math.c +++ b/clang/test/Sema/builtins-elementwise-math.c @@ -322,6 +322,27 @@ // expected-error@-1 {{1st argument must be a floating point type (was 'unsigned4' (vector of 4 'unsigned int' values))}} } +void test_builtin_elementwise_log(int i, float f, double d, float4 v, int3 iv, unsigned u, unsigned4 uv) { + + struct Foo s = __builtin_elementwise_log(f); + // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'float'}} + + i = __builtin_elementwise_log(); + // expected-error@-1 {{too few arguments to function call, expected 1, have 0}} + + i = __builtin_elementwise_log(i); + // expected-error@-1 {{1st argument must be a floating point type (was 'int')}} + + i = __builtin_elementwise_log(f, f); + // expected-error@-1 {{too many arguments to function call, expected 1, have 2}} + + u = __builtin_elementwise_log(u); + // expected-error@-1 {{1st argument must be a floating point type (was 'unsigned int')}} + + uv = __builtin_elementwise_log(uv); + // expected-error@-1 {{1st argument must be a floating point type (was 'unsigned4' (vector of 4 'unsigned int' values))}} +} + void test_builtin_elementwise_roundeven(int i, float f, double d, float4 v, int3 iv, unsigned u, unsigned4 uv) { struct Foo s = __builtin_elementwise_roundeven(f); diff --git a/clang/test/Sema/riscv-sve-vector-log-ops.c b/clang/test/Sema/riscv-sve-vector-log-ops.c new file mode 100644 --- /dev/null +++ b/clang/test/Sema/riscv-sve-vector-log-ops.c @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -triple riscv64 -target-feature +f -target-feature +d \ +// RUN: -target-feature +v -target-feature +zfh -target-feature +experimental-zvfh \ +// RUN: -disable-O0-optnone -o - -fsyntax-only %s -verify +// REQUIRES: riscv-registered-target + +#include + + +vfloat32mf2_t test_sin_vv_i8mf8(vfloat32mf2_t v) { + + return __builtin_elementwise_sin(v); + // expected-error@-1 {{1st argument must be a vector, integer or floating point type}} +} diff --git a/clang/test/SemaCXX/builtins-elementwise-math.cpp b/clang/test/SemaCXX/builtins-elementwise-math.cpp --- a/clang/test/SemaCXX/builtins-elementwise-math.cpp +++ b/clang/test/SemaCXX/builtins-elementwise-math.cpp @@ -73,3 +73,10 @@ static_assert(!is_const::value); static_assert(!is_const::value); } + +void test_builtin_elementwise_log() { + const float a = 42.0; + float b = 42.3; + static_assert(!is_const::value); + static_assert(!is_const::value); +}