https://github.com/tgymnich updated https://github.com/llvm/llvm-project/pull/101989
>From 4516f38d4cba70f2368dc68c72e0024f3f3e0732 Mon Sep 17 00:00:00 2001 From: Tim Gymnich <tgymn...@icloud.com> Date: Fri, 2 Aug 2024 21:40:24 +0200 Subject: [PATCH 1/5] [clang][HLSL] Add sign intrinsic part 3 --- clang/include/clang/Basic/Builtins.td | 6 ++ clang/lib/CodeGen/CGBuiltin.cpp | 17 ++++++ clang/lib/CodeGen/CGHLSLRuntime.h | 1 + clang/lib/Headers/hlsl/hlsl_intrinsics.h | 71 ++++++++++++++++++++++++ clang/lib/Sema/SemaHLSL.cpp | 17 ++++++ 5 files changed, 112 insertions(+) diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index ac33672a32b336..c22b277efde90b 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -4751,6 +4751,12 @@ def HLSLSaturate : LangBuiltin<"HLSL_LANG"> { let Prototype = "void(...)"; } +def HLSLSign : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_elementwise_sign"]; + let Attributes = [NoThrow, Const]; + let Prototype = "int(...)"; +} + // Builtins for XRay. def XRayCustomEvent : Builtin { let Spellings = ["__xray_customevent"]; diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 4204c8ff276ab1..b0a0c41118da4a 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -18700,6 +18700,23 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: { llvm::FunctionType::get(IntTy, {}, false), "__hlsl_wave_get_lane_index", {}, false, true)); } + case Builtin::BI__builtin_hlsl_elementwise_sign: { + Value *Op0 = EmitScalarExpr(E->getArg(0)); + llvm::Type *Xty = Op0->getType(); + llvm::Type *retType = llvm::Type::getInt32Ty(this->getLLVMContext()); + if (Xty->isVectorTy()) { + auto *XVecTy = E->getArg(0)->getType()->getAs<VectorType>(); + retType = llvm::VectorType::get( + retType, ElementCount::getFixed(XVecTy->getNumElements())); + } + if (!E->getArg(0)->getType()->hasFloatingRepresentation() && + !E->getArg(0)->getType()->hasSignedIntegerRepresentation()) + llvm_unreachable("sign operand must have a float or int representation"); + + return Builder.CreateIntrinsic( + retType, CGM.getHLSLRuntime().getSignIntrinsic(), + ArrayRef<Value *>{Op0}, nullptr, "hlsl.sign"); + } } return nullptr; } diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h b/clang/lib/CodeGen/CGHLSLRuntime.h index 55a4b97c160cd6..dc1013d1134d6a 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.h +++ b/clang/lib/CodeGen/CGHLSLRuntime.h @@ -80,6 +80,7 @@ class CGHLSLRuntime { GENERATE_HLSL_INTRINSIC_FUNCTION(Normalize, normalize) GENERATE_HLSL_INTRINSIC_FUNCTION(Rsqrt, rsqrt) GENERATE_HLSL_INTRINSIC_FUNCTION(Saturate, saturate) + GENERATE_HLSL_INTRINSIC_FUNCTION(Sign, sign) GENERATE_HLSL_INTRINSIC_FUNCTION(ThreadId, thread_id) GENERATE_HLSL_INTRINSIC_FUNCTION(FDot, fdot) GENERATE_HLSL_INTRINSIC_FUNCTION(SDot, sdot) diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h index 6d38b668fe770e..1c172094f2d02c 100644 --- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h +++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h @@ -1796,5 +1796,76 @@ _HLSL_AVAILABILITY(shadermodel, 6.0) _HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_get_lane_index) __attribute__((convergent)) uint WaveGetLaneIndex(); +//===----------------------------------------------------------------------===// +// sign builtins +//===----------------------------------------------------------------------===// + +/// \fn T sign(T Val) +/// \brief Returns -1 if \a Val is less than zero; 0 if \a Val equals zero; and +/// 1 if \a Val is greater than zero. \param Val The input value. + +#ifdef __HLSL_ENABLE_16_BIT +_HLSL_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) +int16_t sign(int16_t); +_HLSL_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) +int16_t2 sign(int16_t2); +_HLSL_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) +int16_t3 sign(int16_t3); +_HLSL_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) +int16_t4 sign(int16_t4); +#endif + +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) +half sign(half); +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) +half2 sign(half2); +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) +half3 sign(half3); +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) +half4 sign(half4); + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) +int sign(int); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) +int2 sign(int2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) +int3 sign(int3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) +int4 sign(int4); + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) +float sign(float); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) +float2 sign(float2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) +float3 sign(float3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) +float4 sign(float4); + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) +int64_t sign(int64_t); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) +int64_t2 sign(int64_t2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) +int64_t3 sign(int64_t3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) +int64_t4 sign(int64_t4); + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) +double sign(double); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) +double2 sign(double2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) +double3 sign(double3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) +double4 sign(double4); } // namespace hlsl #endif //_HLSL_HLSL_INTRINSICS_H_ diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index 714e8f5cfa9926..563ee37304131d 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -12,6 +12,7 @@ #include "clang/AST/Decl.h" #include "clang/AST/Expr.h" #include "clang/AST/RecursiveASTVisitor.h" +#include "clang/Basic/Builtins.h" #include "clang/Basic/DiagnosticSema.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/TargetInfo.h" @@ -1364,6 +1365,14 @@ bool CheckNoDoubleVectors(Sema *S, CallExpr *TheCall) { return CheckArgsTypesAreCorrect(S, TheCall, S->Context.FloatTy, checkDoubleVector); } +bool CheckFloatingOrSignedIntRepresentation(Sema *S, CallExpr *TheCall) { + auto checkAllSignedTypes = [](clang::QualType PassedType) -> bool { + return !PassedType->hasSignedIntegerRepresentation() && + !PassedType->hasFloatingRepresentation(); + }; + return CheckArgsTypesAreCorrect(S, TheCall, S->Context.IntTy, + checkAllSignedTypes); +} bool CheckUnsignedIntRepresentation(Sema *S, CallExpr *TheCall) { auto checkAllUnsignedTypes = [](clang::QualType PassedType) -> bool { @@ -1490,6 +1499,14 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { TheCall->setType(ArgTyA); break; } + case Builtin::BI__builtin_hlsl_elementwise_sign: { + if (CheckFloatingOrSignedIntRepresentation(&SemaRef, TheCall)) + return true; + if (SemaRef.PrepareBuiltinElementwiseMathOneArgCall(TheCall)) + return true; + SetElementTypeAsReturnType(&SemaRef, TheCall, getASTContext().IntTy); + break; + } // Note these are llvm builtins that we want to catch invalid intrinsic // generation. Normal handling of these builitns will occur elsewhere. case Builtin::BI__builtin_elementwise_bitreverse: { >From 3041d0ad28c3b4058fe684b03d63e6010f6cb40b Mon Sep 17 00:00:00 2001 From: Tim Gymnich <tgymn...@icloud.com> Date: Fri, 2 Aug 2024 21:40:32 +0200 Subject: [PATCH 2/5] add tests --- clang/test/CodeGenHLSL/builtins/sign.hlsl | 209 ++++++++++++++++++ clang/test/SemaHLSL/BuiltIns/sign-errors.hlsl | 16 ++ 2 files changed, 225 insertions(+) create mode 100644 clang/test/CodeGenHLSL/builtins/sign.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/sign-errors.hlsl diff --git a/clang/test/CodeGenHLSL/builtins/sign.hlsl b/clang/test/CodeGenHLSL/builtins/sign.hlsl new file mode 100644 index 00000000000000..61596764231ec4 --- /dev/null +++ b/clang/test/CodeGenHLSL/builtins/sign.hlsl @@ -0,0 +1,209 @@ +// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ +// RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \ +// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \ +// RUN: --check-prefixes=CHECK,DXIL_CHECK,DXIL_NATIVE_HALF,NATIVE_HALF +// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ +// RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \ +// RUN: -o - | FileCheck %s --check-prefixes=CHECK,DXIL_CHECK,NO_HALF,DXIL_NO_HALF +// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ +// RUN: spirv-unknown-vulkan-compute %s -fnative-half-type \ +// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \ +// RUN: --check-prefixes=CHECK,SPIR_CHECK,NATIVE_HALF,SPIR_NATIVE_HALF +// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ +// RUN: spirv-unknown-vulkan-compute %s -emit-llvm -disable-llvm-passes \ +// RUN: -o - | FileCheck %s --check-prefixes=CHECK,SPIR_CHECK,NO_HALF,SPIR_NO_HALF + +// DXIL_NATIVE_HALF: define noundef i32 @ +// SPIR_NATIVE_HALF: define spir_func noundef i32 @ +// DXIL_NATIVE_HALF: %hlsl.sign = call i32 @llvm.dx.sign.f16( +// SPIR_NATIVE_HALF: %hlsl.sign = call i32 @llvm.spv.sign.f16( +// NATIVE_HALF: ret i32 %hlsl.sign +// DXIL_NO_HALF: define noundef i32 @ +// SPIR_NO_HALF: define spir_func noundef i32 @ +// DXIL_NO_HALF: %hlsl.sign = call i32 @llvm.dx.sign.f32( +// SPIR_NO_HALF: %hlsl.sign = call i32 @llvm.spv.sign.f32( +// NO_HALF: ret i32 %hlsl.sign +int test_sign_half(half p0) { return sign(p0); } + +// DXIL_NATIVE_HALF: define noundef <2 x i32> @ +// SPIR_NATIVE_HALF: define spir_func noundef <2 x i32> @ +// DXIL_NATIVE_HALF: %hlsl.sign = call <2 x i32> @llvm.dx.sign.v2f16( +// SPIR_NATIVE_HALF: %hlsl.sign = call <2 x i32> @llvm.spv.sign.v2f16( +// NATIVE_HALF: ret <2 x i32> %hlsl.sign +// DXIL_NO_HALF: define noundef <2 x i32> @ +// SPIR_NO_HALF: define spir_func noundef <2 x i32> @ +// DXIL_NO_HALF: %hlsl.sign = call <2 x i32> @llvm.dx.sign.v2f32( +// SPIR_NO_HALF: %hlsl.sign = call <2 x i32> @llvm.spv.sign.v2f32( +// NO_HALF: ret <2 x i32> %hlsl.sign +int2 test_sign_half2(half2 p0) { return sign(p0); } + +// DXIL_NATIVE_HALF: define noundef <3 x i32> @ +// SPIR_NATIVE_HALF: define spir_func noundef <3 x i32> @ +// DXIL_NATIVE_HALF: %hlsl.sign = call <3 x i32> @llvm.dx.sign.v3f16( +// SPIR_NATIVE_HALF: %hlsl.sign = call <3 x i32> @llvm.spv.sign.v3f16( +// NATIVE_HALF: ret <3 x i32> %hlsl.sign +// DXIL_NO_HALF: define noundef <3 x i32> @ +// SPIR_NO_HALF: define spir_func noundef <3 x i32> @ +// DXIL_NO_HALF: %hlsl.sign = call <3 x i32> @llvm.dx.sign.v3f32( +// SPIR_NO_HALF: %hlsl.sign = call <3 x i32> @llvm.spv.sign.v3f32( +// NO_HALF: ret <3 x i32> %hlsl.sign +int3 test_sign_half3(half3 p0) { return sign(p0); } + +// DXIL_NATIVE_HALF: define noundef <4 x i32> @ +// SPIR_NATIVE_HALF: define spir_func noundef <4 x i32> @ +// DXIL_NATIVE_HALF: %hlsl.sign = call <4 x i32> @llvm.dx.sign.v4f16( +// SPIR_NATIVE_HALF: %hlsl.sign = call <4 x i32> @llvm.spv.sign.v4f16( +// NATIVE_HALF: ret <4 x i32> %hlsl.sign +// DXIL_NO_HALF: define noundef <4 x i32> @ +// SPIR_NO_HALF: define spir_func noundef <4 x i32> @ +// DXIL_NO_HALF: %hlsl.sign = call <4 x i32> @llvm.dx.sign.v4f32( +// SPIR_NO_HALF: %hlsl.sign = call <4 x i32> @llvm.spv.sign.v4f32( +// NO_HALF: ret <4 x i32> %hlsl.sign +int4 test_sign_half4(half4 p0) { return sign(p0); } + + +// DXIL_CHECK: define noundef i32 @ +// SPIR_CHECK: define spir_func noundef i32 @ +// DXIL_CHECK: %hlsl.sign = call i32 @llvm.dx.sign.f32( +// SPIR_CHECK: %hlsl.sign = call i32 @llvm.spv.sign.f32( +// CHECK: ret i32 %hlsl.sign +int test_sign_float(float p0) { return sign(p0); } + +// DXIL_CHECK: define noundef <2 x i32> @ +// SPIR_CHECK: define spir_func noundef <2 x i32> @ +// DXIL_CHECK: %hlsl.sign = call <2 x i32> @llvm.dx.sign.v2f32( +// SPIR_CHECK: %hlsl.sign = call <2 x i32> @llvm.spv.sign.v2f32( +// CHECK: ret <2 x i32> %hlsl.sign +int2 test_sign_float2(float2 p0) { return sign(p0); } + +// DXIL_CHECK: define noundef <3 x i32> @ +// SPIR_CHECK: define spir_func noundef <3 x i32> @ +// DXIL_CHECK: %hlsl.sign = call <3 x i32> @llvm.dx.sign.v3f32( +// SPIR_CHECK: %hlsl.sign = call <3 x i32> @llvm.spv.sign.v3f32( +// CHECK: ret <3 x i32> %hlsl.sign +int3 test_sign_float3(float3 p0) { return sign(p0); } + +// DXIL_CHECK: define noundef <4 x i32> @ +// SPIR_CHECK: define spir_func noundef <4 x i32> @ +// DXIL_CHECK: %hlsl.sign = call <4 x i32> @llvm.dx.sign.v4f32( +// SPIR_CHECK: %hlsl.sign = call <4 x i32> @llvm.spv.sign.v4f32( +// CHECK: ret <4 x i32> %hlsl.sign +int4 test_sign_float4(float4 p0) { return sign(p0); } + + +// DXIL_CHECK: define noundef i32 @ +// SPIR_CHECK: define spir_func noundef i32 @ +// DXIL_CHECK: %hlsl.sign = call i32 @llvm.dx.sign.f64( +// SPIR_CHECK: %hlsl.sign = call i32 @llvm.spv.sign.f64( +// CHECK: ret i32 %hlsl.sign +int test_sign_double(double p0) { return sign(p0); } + +// DXIL_CHECK: define noundef <2 x i32> @ +// SPIR_CHECK: define spir_func noundef <2 x i32> @ +// DXIL_CHECK: %hlsl.sign = call <2 x i32> @llvm.dx.sign.v2f64( +// SPIR_CHECK: %hlsl.sign = call <2 x i32> @llvm.spv.sign.v2f64( +// CHECK: ret <2 x i32> %hlsl.sign +int2 test_sign_double2(double2 p0) { return sign(p0); } + +// DXIL_CHECK: define noundef <3 x i32> @ +// SPIR_CHECK: define spir_func noundef <3 x i32> @ +// DXIL_CHECK: %hlsl.sign = call <3 x i32> @llvm.dx.sign.v3f64( +// SPIR_CHECK: %hlsl.sign = call <3 x i32> @llvm.spv.sign.v3f64( +// CHECK: ret <3 x i32> %hlsl.sign +int3 test_sign_double3(double3 p0) { return sign(p0); } + +// DXIL_CHECK: define noundef <4 x i32> @ +// SPIR_CHECK: define spir_func noundef <4 x i32> @ +// DXIL_CHECK: %hlsl.sign = call <4 x i32> @llvm.dx.sign.v4f64( +// SPIR_CHECK: %hlsl.sign = call <4 x i32> @llvm.spv.sign.v4f64( +// CHECK: ret <4 x i32> %hlsl.sign +int4 test_sign_double4(double4 p0) { return sign(p0); } + + +#ifdef __HLSL_ENABLE_16_BIT +// DXIL_NATIVE_HALF: define noundef i32 @ +// SPIR_NATIVE_HALF: define spir_func noundef i32 @ +// DXIL_NATIVE_HALF: %hlsl.sign = call i32 @llvm.dx.sign.i16( +// SPIR_NATIVE_HALF: %hlsl.sign = call i32 @llvm.spv.sign.i16( +// NATIVE_HALF: ret i32 %hlsl.sign +int test_sign_int16_t(int16_t p0) { return sign(p0); } + +// DXIL_NATIVE_HALF: define noundef <2 x i32> @ +// SPIR_NATIVE_HALF: define spir_func noundef <2 x i32> @ +// DXIL_NATIVE_HALF: %hlsl.sign = call <2 x i32> @llvm.dx.sign.v2i16( +// SPIR_NATIVE_HALF: %hlsl.sign = call <2 x i32> @llvm.spv.sign.v2i16( +// NATIVE_HALF: ret <2 x i32> %hlsl.sign +int2 test_sign_int16_t2(int16_t2 p0) { return sign(p0); } + +// DXIL_NATIVE_HALF: define noundef <3 x i32> @ +// SPIR_NATIVE_HALF: define spir_func noundef <3 x i32> @ +// DXIL_NATIVE_HALF: %hlsl.sign = call <3 x i32> @llvm.dx.sign.v3i16( +// SPIR_NATIVE_HALF: %hlsl.sign = call <3 x i32> @llvm.spv.sign.v3i16( +// NATIVE_HALF: ret <3 x i32> %hlsl.sign +int3 test_sign_int16_t3(int16_t3 p0) { return sign(p0); } + +// DXIL_NATIVE_HALF: define noundef <4 x i32> @ +// SPIR_NATIVE_HALF: define spir_func noundef <4 x i32> @ +// DXIL_NATIVE_HALF: %hlsl.sign = call <4 x i32> @llvm.dx.sign.v4i16( +// SPIR_NATIVE_HALF: %hlsl.sign = call <4 x i32> @llvm.spv.sign.v4i16( +// NATIVE_HALF: ret <4 x i32> %hlsl.sign +int4 test_sign_int16_t4(int16_t4 p0) { return sign(p0); } +#endif // __HLSL_ENABLE_16_BIT + + +// DXIL_CHECK: define noundef i32 @ +// SPIR_CHECK: define spir_func noundef i32 @ +// DXIL_CHECK: %hlsl.sign = call i32 @llvm.dx.sign.i32( +// SPIR_CHECK: %hlsl.sign = call i32 @llvm.spv.sign.i32( +// CHECK: ret i32 %hlsl.sign +int test_sign_int(int p0) { return sign(p0); } + +// DXIL_CHECK: define noundef <2 x i32> @ +// SPIR_CHECK: define spir_func noundef <2 x i32> @ +// DXIL_CHECK: %hlsl.sign = call <2 x i32> @llvm.dx.sign.v2i32( +// SPIR_CHECK: %hlsl.sign = call <2 x i32> @llvm.spv.sign.v2i32( +// CHECK: ret <2 x i32> %hlsl.sign +int2 test_sign_int2(int2 p0) { return sign(p0); } + +// DXIL_CHECK: define noundef <3 x i32> @ +// SPIR_CHECK: define spir_func noundef <3 x i32> @ +// DXIL_CHECK: %hlsl.sign = call <3 x i32> @llvm.dx.sign.v3i32( +// SPIR_CHECK: %hlsl.sign = call <3 x i32> @llvm.spv.sign.v3i32( +// CHECK: ret <3 x i32> %hlsl.sign +int3 test_sign_int3(int3 p0) { return sign(p0); } + +// DXIL_CHECK: define noundef <4 x i32> @ +// SPIR_CHECK: define spir_func noundef <4 x i32> @ +// DXIL_CHECK: %hlsl.sign = call <4 x i32> @llvm.dx.sign.v4i32( +// SPIR_CHECK: %hlsl.sign = call <4 x i32> @llvm.spv.sign.v4i32( +// CHECK: ret <4 x i32> %hlsl.sign +int4 test_sign_int4(int4 p0) { return sign(p0); } + + +// DXIL_CHECK: define noundef i32 @ +// SPIR_CHECK: define spir_func noundef i32 @ +// DXIL_CHECK: %hlsl.sign = call i32 @llvm.dx.sign.i64( +// SPIR_CHECK: %hlsl.sign = call i32 @llvm.spv.sign.i64( +// CHECK: ret i32 %hlsl.sign +int test_sign_int64_t(int64_t p0) { return sign(p0); } + +// DXIL_CHECK: define noundef <2 x i32> @ +// SPIR_CHECK: define spir_func noundef <2 x i32> @ +// DXIL_CHECK: %hlsl.sign = call <2 x i32> @llvm.dx.sign.v2i64( +// SPIR_CHECK: %hlsl.sign = call <2 x i32> @llvm.spv.sign.v2i64( +// CHECK: ret <2 x i32> %hlsl.sign +int2 test_sign_int64_t2(int64_t2 p0) { return sign(p0); } + +// DXIL_CHECK: define noundef <3 x i32> @ +// SPIR_CHECK: define spir_func noundef <3 x i32> @ +// DXIL_CHECK: %hlsl.sign = call <3 x i32> @llvm.dx.sign.v3i64( +// SPIR_CHECK: %hlsl.sign = call <3 x i32> @llvm.spv.sign.v3i64( +// CHECK: ret <3 x i32> %hlsl.sign +int3 test_sign_int64_t3(int64_t3 p0) { return sign(p0); } + +// DXIL_CHECK: define noundef <4 x i32> @ +// SPIR_CHECK: define spir_func noundef <4 x i32> @ +// DXIL_CHECK: %hlsl.sign = call <4 x i32> @llvm.dx.sign.v4i64( +// SPIR_CHECK: %hlsl.sign = call <4 x i32> @llvm.spv.sign.v4i64( +// CHECK: ret <4 x i32> %hlsl.sign +int4 test_sign_int64_t4(int64_t4 p0) { return sign(p0); } diff --git a/clang/test/SemaHLSL/BuiltIns/sign-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/sign-errors.hlsl new file mode 100644 index 00000000000000..b67725fc77e52e --- /dev/null +++ b/clang/test/SemaHLSL/BuiltIns/sign-errors.hlsl @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm-only -disable-llvm-passes -verify -verify-ignore-unexpected + +bool test_too_few_arg() { + return __builtin_hlsl_elementwise_sign(); + // expected-error@-1 {{too few arguments to function call, expected 1, have 0}} +} + +bool2 test_too_many_arg(float2 p0) { + return __builtin_hlsl_elementwise_sign(p0, p0); + // expected-error@-1 {{too many arguments to function call, expected 1, have 2}} +} + +bool builtin_bool_to_float_type_promotion(bool p1) { + return __builtin_hlsl_elementwise_sign(p1); + // expected-error@-1 {passing 'bool' to parameter of incompatible type 'float'}} +} >From dafb7693463744898342308c9d5637b674b2da74 Mon Sep 17 00:00:00 2001 From: Tim Gymnich <tgymn...@icloud.com> Date: Sun, 11 Aug 2024 13:29:53 +0200 Subject: [PATCH 3/5] fix prototype --- clang/include/clang/Basic/Builtins.td | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index c22b277efde90b..47d37f9f07e23f 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -4754,7 +4754,7 @@ def HLSLSaturate : LangBuiltin<"HLSL_LANG"> { def HLSLSign : LangBuiltin<"HLSL_LANG"> { let Spellings = ["__builtin_hlsl_elementwise_sign"]; let Attributes = [NoThrow, Const]; - let Prototype = "int(...)"; + let Prototype = "void(...)"; } // Builtins for XRay. >From 0efd43ea767faeabcc09547d5a81b1ce297c9988 Mon Sep 17 00:00:00 2001 From: Tim Gymnich <tgymn...@icloud.com> Date: Sun, 11 Aug 2024 13:36:47 +0200 Subject: [PATCH 4/5] fix intrinsic return typers --- clang/lib/Headers/hlsl/hlsl_intrinsics.h | 40 ++++++++++++------------ 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h index 1c172094f2d02c..e2a40d7f0bb74d 100644 --- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h +++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h @@ -1807,30 +1807,30 @@ __attribute__((convergent)) uint WaveGetLaneIndex(); #ifdef __HLSL_ENABLE_16_BIT _HLSL_AVAILABILITY(shadermodel, 6.2) _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) -int16_t sign(int16_t); +int sign(int16_t); _HLSL_AVAILABILITY(shadermodel, 6.2) _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) -int16_t2 sign(int16_t2); +int2 sign(int16_t2); _HLSL_AVAILABILITY(shadermodel, 6.2) _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) -int16_t3 sign(int16_t3); +int3 sign(int16_t3); _HLSL_AVAILABILITY(shadermodel, 6.2) _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) -int16_t4 sign(int16_t4); +int4 sign(int16_t4); #endif _HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) -half sign(half); +int sign(half); _HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) -half2 sign(half2); +int2 sign(half2); _HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) -half3 sign(half3); +int3 sign(half3); _HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) -half4 sign(half4); +int4 sign(half4); _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) int sign(int); @@ -1842,30 +1842,30 @@ _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) int4 sign(int4); _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) -float sign(float); +int sign(float); _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) -float2 sign(float2); +int2 sign(float2); _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) -float3 sign(float3); +int3 sign(float3); _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) -float4 sign(float4); +int4 sign(float4); _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) -int64_t sign(int64_t); +int sign(int64_t); _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) -int64_t2 sign(int64_t2); +int2 sign(int64_t2); _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) -int64_t3 sign(int64_t3); +int3 sign(int64_t3); _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) -int64_t4 sign(int64_t4); +int4 sign(int64_t4); _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) -double sign(double); +int sign(double); _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) -double2 sign(double2); +int2 sign(double2); _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) -double3 sign(double3); +int3 sign(double3); _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) -double4 sign(double4); +int4 sign(double4); } // namespace hlsl #endif //_HLSL_HLSL_INTRINSICS_H_ >From 78fd3c27d6d74518f8921679947927e9a3b762ac Mon Sep 17 00:00:00 2001 From: Tim Gymnich <tgymn...@icloud.com> Date: Thu, 15 Aug 2024 14:45:49 +0200 Subject: [PATCH 5/5] replace llvm_unreachable with assertion --- clang/lib/CodeGen/CGBuiltin.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index b0a0c41118da4a..479c1f57218cbf 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -18709,9 +18709,9 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: { retType = llvm::VectorType::get( retType, ElementCount::getFixed(XVecTy->getNumElements())); } - if (!E->getArg(0)->getType()->hasFloatingRepresentation() && - !E->getArg(0)->getType()->hasSignedIntegerRepresentation()) - llvm_unreachable("sign operand must have a float or int representation"); + assert((E->getArg(0)->getType()->hasFloatingRepresentation() || + E->getArg(0)->getType()->hasSignedIntegerRepresentation()) && + "sign operand must have a float or int representation"); return Builder.CreateIntrinsic( retType, CGM.getHLSLRuntime().getSignIntrinsic(), _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits