Author: ManuelJBrito Date: 2023-02-03T09:47:46Z New Revision: 450a4612c39cc150879a0f0ffffe692adfc1d0d9
URL: https://github.com/llvm/llvm-project/commit/450a4612c39cc150879a0f0ffffe692adfc1d0d9 DIFF: https://github.com/llvm/llvm-project/commit/450a4612c39cc150879a0f0ffffe692adfc1d0d9.diff LOG: [Clang] Add builtin_nondeterministic_value Differential Revision: https://reviews.llvm.org/D142388 Added: clang/test/CodeGen/builtins-nondeterministic-value.c Modified: clang/docs/LanguageExtensions.rst clang/docs/ReleaseNotes.rst clang/include/clang/Basic/Builtins.def clang/include/clang/Sema/Sema.h clang/lib/CodeGen/CGBuiltin.cpp clang/lib/Sema/SemaChecking.cpp Removed: ################################################################################ diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst index 90e7943510608..9d5a4d78e8040 100644 --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -3081,6 +3081,32 @@ Query for this feature with ``__has_builtin(__builtin_debugtrap)``. Query for this feature with ``__has_builtin(__builtin_trap)``. +``__builtin_nondeterministic_value`` +------------------------------------ + +``__builtin_nondeterministic_value`` returns a valid nondeterministic value of the same type as the provided argument. + +**Syntax**: + +.. code-block:: c++ + + type __builtin_nondeterministic_value(type x) + +**Examples**: + +.. code-block:: c++ + + int x = __builtin_nondeterministic_value(x); + float y = __builtin_nondeterministic_value(y); + __m256i a = __builtin_nondeterministic_value(a); + +**Description** + +Each call to ``__builtin_nondeterministic_value`` returns a valid value of the type given by the argument. + +The types currently supported are: integer types, floating-point types, vector types. + +Query for this feature with ``__has_builtin(__builtin_nondeterministic_value)``. ``__builtin_sycl_unique_stable_name`` ------------------------------------- diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index c7b084ef8e29c..d2f1919f24a33 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -79,6 +79,8 @@ Non-comprehensive list of changes in this release - Clang now saves the address of ABI-indirect function parameters on the stack, improving the debug information available in programs compiled without optimizations. +- Clang now supports ``__builtin_nondeterministic_value`` that returns a + nondeterministic value of the same type as the provided argument. New Compiler Flags ------------------ diff --git a/clang/include/clang/Basic/Builtins.def b/clang/include/clang/Basic/Builtins.def index 07e0a2d7748c5..2d25a030fd682 100644 --- a/clang/include/clang/Basic/Builtins.def +++ b/clang/include/clang/Basic/Builtins.def @@ -655,6 +655,7 @@ BUILTIN(__builtin_alloca_uninitialized, "v*z", "Fn") BUILTIN(__builtin_alloca_with_align, "v*zIz", "Fn") BUILTIN(__builtin_alloca_with_align_uninitialized, "v*zIz", "Fn") BUILTIN(__builtin_call_with_static_chain, "v.", "nt") +BUILTIN(__builtin_nondeterministic_value, "v.", "nt") BUILTIN(__builtin_elementwise_abs, "v.", "nct") BUILTIN(__builtin_elementwise_max, "v.", "nct") diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 741c2503127af..67d55ab3d8c6d 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -13571,6 +13571,8 @@ class Sema final { bool PrepareBuiltinElementwiseMathOneArgCall(CallExpr *TheCall); bool PrepareBuiltinReduceMathOneArgCall(CallExpr *TheCall); + bool SemaBuiltinNonDeterministicValue(CallExpr *TheCall); + // Matrix builtin handling. ExprResult SemaBuiltinMatrixTranspose(CallExpr *TheCall, ExprResult CallResult); diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 8f733d7d14c6e..aefbc731f8738 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -3060,6 +3060,15 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, return RValue::get(V); } + case Builtin::BI__builtin_nondeterministic_value: { + llvm::Type *Ty = ConvertType(E->getArg(0)->getType()); + + Value *Result = PoisonValue::get(Ty); + Result = Builder.CreateFreeze(Result); + + return RValue::get(Result); + } + case Builtin::BI__builtin_elementwise_abs: { Value *Result; QualType QT = E->getArg(0)->getType(); diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index f1c4aabadef5f..efba0a8871c6c 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -2584,6 +2584,12 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, break; } + case Builtin::BI__builtin_nondeterministic_value: { + if (SemaBuiltinNonDeterministicValue(TheCall)) + return ExprError(); + break; + } + // __builtin_elementwise_abs restricts the element type to signed integers or // floating point types only. case Builtin::BI__builtin_elementwise_abs: { @@ -17858,6 +17864,21 @@ bool Sema::PrepareBuiltinReduceMathOneArgCall(CallExpr *TheCall) { return false; } +bool Sema::SemaBuiltinNonDeterministicValue(CallExpr *TheCall) { + if (checkArgCount(*this, TheCall, 1)) + return true; + + ExprResult Arg = TheCall->getArg(0); + QualType TyArg = Arg.get()->getType(); + + if (!TyArg->isBuiltinType() && !TyArg->isVectorType()) + return Diag(TheCall->getArg(0)->getBeginLoc(), diag::err_builtin_invalid_arg_type) + << 1 << /*vector, integer or floating point ty*/ 0 << TyArg; + + TheCall->setType(TyArg); + return false; +} + ExprResult Sema::SemaBuiltinMatrixTranspose(CallExpr *TheCall, ExprResult CallResult) { if (checkArgCount(*this, TheCall, 1)) diff --git a/clang/test/CodeGen/builtins-nondeterministic-value.c b/clang/test/CodeGen/builtins-nondeterministic-value.c new file mode 100644 index 0000000000000..8727644624ced --- /dev/null +++ b/clang/test/CodeGen/builtins-nondeterministic-value.c @@ -0,0 +1,60 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s + +typedef float float4 __attribute__((ext_vector_type(4))); +typedef _Bool bool4 __attribute__((ext_vector_type(4))); + +int clang_nondet_i( int x ) { +// CHECK-LABEL: entry +// CHECK: [[A:%.*]] = alloca i32, align 4 +// CHECK: store i32 [[X:%.*]], ptr [[A]], align 4 +// CHECK: [[R:%.*]] = freeze i32 poison +// CHECK: ret i32 [[R]] + return __builtin_nondeterministic_value(x); +} + +float clang_nondet_f( float x ) { +// CHECK-LABEL: entry +// CHECK: [[A:%.*]] = alloca float, align 4 +// CHECK: store float [[X:%.*]], ptr [[A]], align 4 +// CHECK: [[R:%.*]] = freeze float poison +// CHECK: ret float [[R]] + return __builtin_nondeterministic_value(x); +} + +double clang_nondet_d( double x ) { +// CHECK-LABEL: entry +// CHECK: [[A:%.*]] = alloca double, align 8 +// CHECK: store double [[X:%.*]], ptr [[A]], align 8 +// CHECK: [[R:%.*]] = freeze double poison +// CHECK: ret double [[R]] + return __builtin_nondeterministic_value(x); +} + +_Bool clang_nondet_b( _Bool x) { +// CHECK-LABEL: entry +// CHECK: [[A:%.*]] = alloca i8, align 1 +// CHECK: [[B:%.*]] = zext i1 %x to i8 +// CHECK: store i8 [[B]], ptr [[A]], align 1 +// CHECK: [[R:%.*]] = freeze i1 poison +// CHECK: ret i1 [[R]] + return __builtin_nondeterministic_value(x); +} + +void clang_nondet_fv( ) { +// CHECK-LABEL: entry +// CHECK: [[A:%.*]] = alloca <4 x float>, align 16 +// CHECK: [[R:%.*]] = freeze <4 x float> poison +// CHECK: store <4 x float> [[R]], ptr [[A]], align 16 +// CHECK: ret void + float4 x = __builtin_nondeterministic_value(x); +} + +void clang_nondet_bv( ) { +// CHECK: [[A:%.*]] = alloca i8, align 1 +// CHECK: [[V:%.*]] = freeze <4 x i1> poison +// CHECK: [[SV:%.*]] = shufflevector <4 x i1> [[V]], <4 x i1> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef> +// CHECK: [[BC:%.*]] = bitcast <8 x i1> [[SV]] to i8 +// CHECK: store i8 [[BC]], ptr [[A]], align 1 +// CHECK: ret void + bool4 x = __builtin_nondeterministic_value(x); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits