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 @@ -655,6 +655,7 @@ 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_nondet, "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 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -13529,6 +13529,8 @@ bool PrepareBuiltinElementwiseMathOneArgCall(CallExpr *TheCall); bool PrepareBuiltinReduceMathOneArgCall(CallExpr *TheCall); + bool SemaBuiltinNonDet(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 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -3060,6 +3060,12 @@ return RValue::get(V); } + case Builtin::BI__builtin_nondet: { + Value *Result = PoisonValue::get(ConvertType(E->getArg(0)->getType())); + 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 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -2580,6 +2580,12 @@ break; } + case Builtin::BI__builtin_nondet: { + if (SemaBuiltinNonDet(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: { @@ -17799,6 +17805,16 @@ return false; } +bool Sema::SemaBuiltinNonDet(CallExpr *TheCall) { + if (checkArgCount(*this, TheCall, 1)) + return true; + + ExprResult Arg = TheCall->getArg(0); + QualType TyArg = Arg.get()->getType(); + TheCall->setType(TyArg); + return false; +} + ExprResult Sema::SemaBuiltinMatrixTranspose(CallExpr *TheCall, ExprResult CallResult) { if (checkArgCount(*this, TheCall, 1)) diff --git a/clang/test/CodeGen/builtins-nondet.c b/clang/test/CodeGen/builtins-nondet.c new file mode 100644 --- /dev/null +++ b/clang/test/CodeGen/builtins-nondet.c @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s + +typedef float float4 __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_nondet(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_nondet(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_nondet(x); +} + +float4 clang_nondet_v( float4 x ) { +// CHECK-LABEL: entry +// CHECK: [[A:%.*]] = alloca <4 x float>, align 16 +// CHECK: store <4 x float> [[X:%.*]], ptr [[A]], align 16 +// CHECK: [[R:%.*]] = freeze <4 x float> poison +// CHECK: ret <4 x float> [[R]] + return __builtin_nondet(x); +} +