Author: Joshua Batista Date: 2023-07-31T10:59:13-07:00 New Revision: 57f879cdd4c63189c569bdc1ce4e87e7342eea46
URL: https://github.com/llvm/llvm-project/commit/57f879cdd4c63189c569bdc1ce4e87e7342eea46 DIFF: https://github.com/llvm/llvm-project/commit/57f879cdd4c63189c569bdc1ce4e87e7342eea46.diff LOG: clang: Add elementwise bitreverse builtin Add codegen for llvm bitreverse elementwise builtin The bitreverse elementwise builtin is necessary for HLSL codegen. Tests were added to make sure that the expected errors are encountered when these functions are given inputs of incompatible types, or too many inputs. The new builtin is restricted to integer types only. Reviewed By: arsenm Differential Revision: https://reviews.llvm.org/D156357 Added: Modified: clang/docs/LanguageExtensions.rst clang/docs/ReleaseNotes.rst clang/include/clang/Basic/Builtins.def clang/lib/CodeGen/CGBuiltin.cpp clang/lib/Sema/SemaChecking.cpp clang/test/CodeGen/builtins-elementwise-math.c clang/test/Sema/builtins-elementwise-math.c clang/test/SemaCXX/builtins-elementwise-math.cpp Removed: ################################################################################ diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst index 1830480b1285d7..fbe240dd79b848 100644 --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -631,7 +631,7 @@ Unless specified otherwise operation(±0) = ±0 and operation(±infinity) = ±in =========================================== ================================================================ ========================================= T __builtin_elementwise_abs(T x) return the absolute value of a number x; the absolute value of signed integer and floating point types the most negative integer remains the most negative integer - T __builtin_elementwise_fma(T x, T y, T z) fused multiply add, (x * y) + z. floating point types + T __builtin_elementwise_fma(T x, T y, T z) fused multiply add, (x * y) + z. floating point types T __builtin_elementwise_ceil(T x) return the smallest integral value greater than or equal to x floating point types 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 @@ -640,6 +640,7 @@ Unless specified otherwise operation(±0) = ±0 and operation(±infinity) = ±in T __builtin_elementwise_log2(T x) return the base 2 logarithm of x floating point types T __builtin_elementwise_log10(T x) return the base 10 logarithm of x floating point types T __builtin_elementwise_pow(T x, T y) return x raised to the power of y floating point types + T __builtin_elementwise_bitreverse(T x) return the integer represented after reversing the bits of x integer types T __builtin_elementwise_exp(T x) returns the base-e exponential, e^x, of the specified value floating point types T __builtin_elementwise_exp2(T x) returns the base-2 exponential, 2^x, of the specified value floating point types T __builtin_elementwise_roundeven(T x) round x to the nearest integer value in floating point format, floating point types diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index d369af7944ebeb..55189cbd659087 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -182,6 +182,14 @@ DWARF Support in Clang Floating Point Support in Clang ------------------------------- +- Add ``__builtin_elementwise_log`` builtin for floating point types only. +- Add ``__builtin_elementwise_log10`` builtin for floating point types only. +- Add ``__builtin_elementwise_log2`` builtin for floating point types only. +- Add ``__builtin_elementwise_exp`` builtin for floating point types only. +- Add ``__builtin_elementwise_exp2`` builtin for floating point types only. +- Add ``__builtin_set_flt_rounds`` builtin for X86, x86_64, Arm and AArch64 only. +- Add ``__builtin_elementwise_pow`` builtin for floating point types only. +- Add ``__builtin_elementwise_bitreverse`` builtin for integer types only. AST Matchers ------------ diff --git a/clang/include/clang/Basic/Builtins.def b/clang/include/clang/Basic/Builtins.def index 6dad8b512bd2df..843cc7f334f564 100644 --- a/clang/include/clang/Basic/Builtins.def +++ b/clang/include/clang/Basic/Builtins.def @@ -677,6 +677,7 @@ BUILTIN(__builtin_call_with_static_chain, "v.", "nt") BUILTIN(__builtin_nondeterministic_value, "v.", "nt") BUILTIN(__builtin_elementwise_abs, "v.", "nct") +BUILTIN(__builtin_elementwise_bitreverse, "v.", "nct") BUILTIN(__builtin_elementwise_max, "v.", "nct") BUILTIN(__builtin_elementwise_min, "v.", "nct") BUILTIN(__builtin_elementwise_ceil, "v.", "nct") diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index fc8ee06fbb0624..1f1323e2f92045 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -3237,6 +3237,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__builtin_elementwise_pow: { return RValue::get(emitBinaryBuiltin(*this, E, llvm::Intrinsic::pow)); } + case Builtin::BI__builtin_elementwise_bitreverse: + return RValue::get(emitUnaryBuiltin(*this, E, llvm::Intrinsic::bitreverse, + "elt.bitreverse")); 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 index f8e48728da6647..502c583a48d6df 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -2700,6 +2700,26 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, if (SemaBuiltinElementwiseMath(TheCall)) return ExprError(); break; + + case Builtin::BI__builtin_elementwise_bitreverse: { + if (PrepareBuiltinElementwiseMathOneArgCall(TheCall)) + return ExprError(); + + const Expr *Arg = TheCall->getArg(0); + QualType ArgTy = Arg->getType(); + QualType EltTy = ArgTy; + + if (auto *VecTy = EltTy->getAs<VectorType>()) + EltTy = VecTy->getElementType(); + + if (!EltTy->isIntegerType()) { + Diag(Arg->getBeginLoc(), diag::err_builtin_invalid_arg_type) + << 1 << /* integer ty */ 6 << ArgTy; + return ExprError(); + } + break; + } + case Builtin::BI__builtin_elementwise_copysign: { if (checkArgCount(*this, TheCall, 2)) return ExprError(); diff --git a/clang/test/CodeGen/builtins-elementwise-math.c b/clang/test/CodeGen/builtins-elementwise-math.c index 1087986c434774..b50fcd5e6780cd 100644 --- a/clang/test/CodeGen/builtins-elementwise-math.c +++ b/clang/test/CodeGen/builtins-elementwise-math.c @@ -323,6 +323,42 @@ void test_builtin_elementwise_min(float f1, float f2, double d1, double d2, int_as_one = __builtin_elementwise_min(int_as_one, b); } +void test_builtin_elementwise_bitreverse(si8 vi1, si8 vi2, + long long int i1, long long int i2, short si, + _BitInt(31) bi1, _BitInt(31) bi2) { + + + // CHECK: [[I1:%.+]] = load i64, ptr %i1.addr, align 8 + // CHECK-NEXT: call i64 @llvm.bitreverse.i64(i64 [[I1]]) + i2 = __builtin_elementwise_bitreverse(i1); + + // CHECK: [[VI1:%.+]] = load <8 x i16>, ptr %vi1.addr, align 16 + // CHECK-NEXT: call <8 x i16> @llvm.bitreverse.v8i16(<8 x i16> [[VI1]]) + vi2 = __builtin_elementwise_bitreverse(vi1); + + // CHECK: [[CVI2:%.+]] = load <8 x i16>, ptr %cvi2, align 16 + // CHECK-NEXT: call <8 x i16> @llvm.bitreverse.v8i16(<8 x i16> [[CVI2]]) + const si8 cvi2 = vi2; + vi2 = __builtin_elementwise_bitreverse(cvi2); + + // CHECK: [[BI1:%.+]] = load i31, ptr %bi1.addr, align 4 + // CHECK-NEXT: call i31 @llvm.bitreverse.i31(i31 [[BI1]]) + bi2 = __builtin_elementwise_bitreverse(bi1); + + // CHECK: [[IA1:%.+]] = load i32, ptr addrspace(1) @int_as_one, align 4 + // CHECK-NEXT: call i32 @llvm.bitreverse.i32(i32 [[IA1]]) + b = __builtin_elementwise_bitreverse(int_as_one); + + // CHECK: call i32 @llvm.bitreverse.i32(i32 -10) + b = __builtin_elementwise_bitreverse(-10); + + // CHECK: [[SI:%.+]] = load i16, ptr %si.addr, align 2 + // CHECK-NEXT: [[SI_EXT:%.+]] = sext i16 [[SI]] to i32 + // CHECK-NEXT: [[RES:%.+]] = call i32 @llvm.bitreverse.i32(i32 [[SI_EXT]]) + // CHECK-NEXT: = trunc i32 [[RES]] to i16 + si = __builtin_elementwise_bitreverse(si); +} + void test_builtin_elementwise_ceil(float f1, float f2, double d1, double d2, float4 vf1, float4 vf2) { // CHECK-LABEL: define void @test_builtin_elementwise_ceil( diff --git a/clang/test/Sema/builtins-elementwise-math.c b/clang/test/Sema/builtins-elementwise-math.c index 5aad056c4de409..a735748c7cba6e 100644 --- a/clang/test/Sema/builtins-elementwise-math.c +++ b/clang/test/Sema/builtins-elementwise-math.c @@ -269,6 +269,27 @@ void test_builtin_elementwise_min(int i, short s, double d, float4 v, int3 iv, u // expected-error@-1 {{1st argument must be a vector, integer or floating point type (was '_Complex float')}} } +void test_builtin_elementwise_bitreverse(int i, float f, double d, float4 v, int3 iv, unsigned u, unsigned4 uv) { + + struct Foo s = __builtin_elementwise_ceil(f); + // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'float'}} + + i = __builtin_elementwise_bitreverse(); + // expected-error@-1 {{too few arguments to function call, expected 1, have 0}} + + i = __builtin_elementwise_bitreverse(f); + // expected-error@-1 {{1st argument must be a vector of integers (was 'float')}} + + i = __builtin_elementwise_bitreverse(f, f); + // expected-error@-1 {{too many arguments to function call, expected 1, have 2}} + + u = __builtin_elementwise_bitreverse(d); + // expected-error@-1 {{1st argument must be a vector of integers (was 'double')}} + + v = __builtin_elementwise_bitreverse(v); + // expected-error@-1 {{1st argument must be a vector of integers (was 'float4' (vector of 4 'float' values))}} +} + void test_builtin_elementwise_ceil(int i, float f, double d, float4 v, int3 iv, unsigned u, unsigned4 uv) { struct Foo s = __builtin_elementwise_ceil(f); diff --git a/clang/test/SemaCXX/builtins-elementwise-math.cpp b/clang/test/SemaCXX/builtins-elementwise-math.cpp index 492497aa33658a..f5ad1688eb09c4 100644 --- a/clang/test/SemaCXX/builtins-elementwise-math.cpp +++ b/clang/test/SemaCXX/builtins-elementwise-math.cpp @@ -206,3 +206,10 @@ void test_builtin_elementwise_pow() { static_assert(!is_const<decltype(__builtin_elementwise_pow(b, a))>::value); static_assert(!is_const<decltype(__builtin_elementwise_pow(a, a))>::value); } + +void test_builtin_elementwise_bitreverse() { + const int a = 2; + int b = 1; + static_assert(!is_const<decltype(__builtin_elementwise_bitreverse(a))>::value); + static_assert(!is_const<decltype(__builtin_elementwise_bitreverse(b))>::value); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits