https://github.com/joaosaffran updated https://github.com/llvm/llvm-project/pull/107292
>From a88a4eda4ce2ad32ee2ec02549b25c9f08aa14e9 Mon Sep 17 00:00:00 2001 From: Joao Saffran <jdereze...@microsoft.com> Date: Tue, 3 Sep 2024 19:06:22 +0000 Subject: [PATCH 1/4] Adding `asuint` implementation to hlsl --- clang/include/clang/Basic/Builtins.td | 6 +++ clang/lib/CodeGen/CGBuiltin.cpp | 17 +++++++ clang/lib/Headers/hlsl/hlsl_intrinsics.h | 38 ++++++++++----- clang/lib/Sema/SemaHLSL.cpp | 19 ++++++++ clang/test/CodeGenHLSL/builtins/asuint.hlsl | 53 +++++++++++++++++++++ 5 files changed, 122 insertions(+), 11 deletions(-) create mode 100644 clang/test/CodeGenHLSL/builtins/asuint.hlsl diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index 92118418d9d459..83bca9b342ef15 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -4751,6 +4751,12 @@ def HLSLRcp : LangBuiltin<"HLSL_LANG"> { let Prototype = "void(...)"; } +def HLSLAsUint : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_elementwise_asuint"]; + let Attributes = [NoThrow, Const]; + let Prototype = "void(...)"; +} + def HLSLRSqrt : LangBuiltin<"HLSL_LANG"> { let Spellings = ["__builtin_hlsl_elementwise_rsqrt"]; let Attributes = [NoThrow, Const]; diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index da7a1a55da5313..4a6a60fcac8a14 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -27,9 +27,11 @@ #include "clang/AST/Decl.h" #include "clang/AST/OSLog.h" #include "clang/AST/OperationKinds.h" +#include "clang/Basic/Builtins.h" #include "clang/Basic/TargetBuiltins.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" +#include "clang/Basic/TokenKinds.h" #include "clang/CodeGen/CGFunctionInfo.h" #include "clang/Frontend/FrontendDiagnostic.h" #include "llvm/ADT/APFloat.h" @@ -39,6 +41,7 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/DataLayout.h" +#include "llvm/IR/DerivedTypes.h" #include "llvm/IR/InlineAsm.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/IntrinsicsAArch64.h" @@ -62,6 +65,7 @@ #include "llvm/Support/ConvertUTF.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/ScopedPrinter.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/TargetParser/AArch64TargetParser.h" #include "llvm/TargetParser/RISCVISAInfo.h" #include "llvm/TargetParser/X86TargetParser.h" @@ -18815,6 +18819,19 @@ 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_asuint: { + Value *Op = EmitScalarExpr(E->getArg(0)); + E->dump(); + llvm::Type *DestTy = llvm::Type::getInt32Ty(this->getLLVMContext()); + + if (Op -> getType()->isVectorTy()){ + auto VecTy = E->getArg(0)->getType()->getAs<VectorType>(); + DestTy = llvm::VectorType::get(DestTy, VecTy->getNumElements(), + VecTy->isSizelessVectorType()); + } + + return Builder.CreateBitCast(Op, DestTy); + } case Builtin::BI__builtin_hlsl_wave_is_first_lane: { Intrinsic::ID ID = CGM.getHLSLRuntime().getWaveIsFirstLaneIntrinsic(); return EmitRuntimeCall(Intrinsic::getDeclaration(&CGM.getModule(), ID)); diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h index 5c08a45a35377d..18426597569098 100644 --- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h +++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h @@ -367,17 +367,6 @@ bool any(double4); /// \brief Returns the arcsine of the input value, \a Val. /// \param Val The input value. -#ifdef __HLSL_ENABLE_16_BIT -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_asin) -half asin(half); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_asin) -half2 asin(half2); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_asin) -half3 asin(half3); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_asin) -half4 asin(half4); -#endif - _HLSL_BUILTIN_ALIAS(__builtin_elementwise_asin) float asin(float); _HLSL_BUILTIN_ALIAS(__builtin_elementwise_asin) @@ -387,6 +376,33 @@ float3 asin(float3); _HLSL_BUILTIN_ALIAS(__builtin_elementwise_asin) float4 asin(float4); +//===----------------------------------------------------------------------===// +// asin builtins +//===----------------------------------------------------------------------===// + +/// \fn uint asin(T Val) +/// \brief Reinterprest. +/// \param Val The input value. + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_asuint) +uint asuint(float); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_asuint) +uint2 asuint(float2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_asuint) +uint3 asuint(float3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_asuint) +uint4 asuint(float4); + + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_asuint) +uint asuint(double); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_asuint) +uint2 asuint(double2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_asuint) +uint3 asuint(double3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_asuint) +uint4 asuint(double4); + //===----------------------------------------------------------------------===// // atan builtins //===----------------------------------------------------------------------===// diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index 3b40769939f12f..5b325035b6b2f5 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -28,6 +28,8 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Type.h" #include "llvm/Support/Casting.h" #include "llvm/Support/DXILABI.h" #include "llvm/Support/ErrorHandling.h" @@ -1646,6 +1648,23 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { return true; break; } + case Builtin::BI__builtin_hlsl_elementwise_asuint: { + if (SemaRef.checkArgCount(TheCall, 1)) + return true; + + ExprResult A = TheCall->getArg(0); + QualType ArgTyA = A.get()->getType(); + + if(ArgTyA->isVectorType()){ + auto VecTy = TheCall->getArg(0)->getType()->getAs<VectorType>(); + auto ReturnType = this->getASTContext().getVectorType(TheCall->getCallReturnType(this->getASTContext()), VecTy->getNumElements(), + VectorKind::Generic); + + TheCall->setType(ReturnType); + } + + break; + } case Builtin::BI__builtin_elementwise_acos: case Builtin::BI__builtin_elementwise_asin: case Builtin::BI__builtin_elementwise_atan: diff --git a/clang/test/CodeGenHLSL/builtins/asuint.hlsl b/clang/test/CodeGenHLSL/builtins/asuint.hlsl new file mode 100644 index 00000000000000..33acb00ae11182 --- /dev/null +++ b/clang/test/CodeGenHLSL/builtins/asuint.hlsl @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.3-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -o - | FileCheck %s + +// // CHECK-LABEL: builtin_test_asuint_float +// // CHECK: bitcast float %0 to i32 +// // CHECK: ret <4 x i32> %dx.clamp +// export uint builtin_test_asuint_float(float p0) { +// return __builtin_hlsl_elementwise_asuint(p0); +// } + + +// // CHECK-LABEL: builtin_test_asuint_float +// // CHECK: bitcast float %0 to i32 +// // CHECK: ret <4 x i32> %dx.clamp +// export uint builtin_test_asuint_double(double p0) { +// return __builtin_hlsl_elementwise_asuint(p0); +// } + + +// // CHECK-LABEL: builtin_test_asuint_float +// // CHECK: bitcast float %0 to i32 +// // CHECK: ret <4 x i32> %dx.clamp +// export uint builtin_test_asuint_half(half p0) { +// return __builtin_hlsl_elementwise_asuint(p0); +// } + + +// // CHECK-LABEL: builtin_test_asuint_float +// // CHECK: bitcast float %0 to i32 +// // CHECK: ret <4 x i32> %dx.clamp +// export uint4 builtin_test_asuint_float_vector(float p0) { +// return __builtin_hlsl_elementwise_asuint(p0); +// } + + +// CHECK-LABEL: builtin_test_asuint_float +// CHECK: bitcast float %0 to i32 +// CHECK: ret <4 x i32> %dx.clamp +export uint4 builtin_test_asuint_floa4t(float p0) { + return asuint(p0); +} + +// export uint4 builtin_test_asuint4_uint(uint p0) { +// return __builtin_hlsl_elementwise_asuint(p0); +// } + + +// export uint4 builtin_test_asuint4_int(int p0) { +// return __builtin_hlsl_elementwise_asuint(p0); +// } + +// export uint builtin_test_asuint_float(float p0) { +// return __builtin_hlsl_elementwise_asuint(p0); +// } \ No newline at end of file >From 82fca9ea6716114e4f483fcead9039deaa27f592 Mon Sep 17 00:00:00 2001 From: Joao Saffran <jdereze...@microsoft.com> Date: Tue, 3 Sep 2024 19:06:22 +0000 Subject: [PATCH 2/4] Adding `asuint` implementation to hlsl --- clang/lib/CodeGen/CGBuiltin.cpp | 16 ++--- clang/lib/Headers/hlsl/hlsl_intrinsics.h | 27 ++++---- clang/lib/Sema/SemaHLSL.cpp | 43 +++++++++---- clang/test/CodeGenHLSL/builtins/asuint.hlsl | 63 ++++++------------- .../test/SemaHLSL/BuiltIns/asuint-errors.hlsl | 18 ++++++ 5 files changed, 86 insertions(+), 81 deletions(-) create mode 100644 clang/test/SemaHLSL/BuiltIns/asuint-errors.hlsl diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 4a6a60fcac8a14..afbcd96bc14b2f 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -27,11 +27,9 @@ #include "clang/AST/Decl.h" #include "clang/AST/OSLog.h" #include "clang/AST/OperationKinds.h" -#include "clang/Basic/Builtins.h" #include "clang/Basic/TargetBuiltins.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" -#include "clang/Basic/TokenKinds.h" #include "clang/CodeGen/CGFunctionInfo.h" #include "clang/Frontend/FrontendDiagnostic.h" #include "llvm/ADT/APFloat.h" @@ -41,7 +39,6 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/DataLayout.h" -#include "llvm/IR/DerivedTypes.h" #include "llvm/IR/InlineAsm.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/IntrinsicsAArch64.h" @@ -65,7 +62,6 @@ #include "llvm/Support/ConvertUTF.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/ScopedPrinter.h" -#include "llvm/Support/raw_ostream.h" #include "llvm/TargetParser/AArch64TargetParser.h" #include "llvm/TargetParser/RISCVISAInfo.h" #include "llvm/TargetParser/X86TargetParser.h" @@ -18820,14 +18816,14 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: { {}, false, true)); } case Builtin::BI__builtin_hlsl_elementwise_asuint: { - Value *Op = EmitScalarExpr(E->getArg(0)); - E->dump(); + Value *Op = EmitScalarExpr(E->getArg(0)->IgnoreImpCasts()); + llvm::Type *DestTy = llvm::Type::getInt32Ty(this->getLLVMContext()); - if (Op -> getType()->isVectorTy()){ - auto VecTy = E->getArg(0)->getType()->getAs<VectorType>(); - DestTy = llvm::VectorType::get(DestTy, VecTy->getNumElements(), - VecTy->isSizelessVectorType()); + if (Op->getType()->isVectorTy()) { + const VectorType *VecTy = E->getArg(0)->getType()->getAs<VectorType>(); + DestTy = llvm::VectorType::get( + DestTy, ElementCount::getFixed(VecTy->getNumElements())); } return Builder.CreateBitCast(Op, DestTy); diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h index 18426597569098..f40469937ddc38 100644 --- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h +++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h @@ -367,6 +367,17 @@ bool any(double4); /// \brief Returns the arcsine of the input value, \a Val. /// \param Val The input value. +#ifdef __HLSL_ENABLE_16_BIT +_HLSL_BUILTIN_ALIAS(__builtin_elementwise_asin) +half asin(half); +_HLSL_BUILTIN_ALIAS(__builtin_elementwise_asin) +half2 asin(half2); +_HLSL_BUILTIN_ALIAS(__builtin_elementwise_asin) +half3 asin(half3); +_HLSL_BUILTIN_ALIAS(__builtin_elementwise_asin) +half4 asin(half4); +#endif + _HLSL_BUILTIN_ALIAS(__builtin_elementwise_asin) float asin(float); _HLSL_BUILTIN_ALIAS(__builtin_elementwise_asin) @@ -377,11 +388,11 @@ _HLSL_BUILTIN_ALIAS(__builtin_elementwise_asin) float4 asin(float4); //===----------------------------------------------------------------------===// -// asin builtins +// asuint builtins //===----------------------------------------------------------------------===// -/// \fn uint asin(T Val) -/// \brief Reinterprest. +/// \fn uint asuint(T Val) +/// \brief Interprets the bit pattern of x as an unsigned integer. /// \param Val The input value. _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_asuint) @@ -393,16 +404,6 @@ uint3 asuint(float3); _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_asuint) uint4 asuint(float4); - -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_asuint) -uint asuint(double); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_asuint) -uint2 asuint(double2); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_asuint) -uint3 asuint(double3); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_asuint) -uint4 asuint(double4); - //===----------------------------------------------------------------------===// // atan builtins //===----------------------------------------------------------------------===// diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index 5b325035b6b2f5..123a724d444c33 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -9,7 +9,6 @@ //===----------------------------------------------------------------------===// #include "clang/Sema/SemaHLSL.h" -#include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclBase.h" #include "clang/AST/DeclCXX.h" @@ -28,8 +27,6 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" -#include "llvm/IR/DerivedTypes.h" -#include "llvm/IR/Type.h" #include "llvm/Support/Casting.h" #include "llvm/Support/DXILABI.h" #include "llvm/Support/ErrorHandling.h" @@ -1468,6 +1465,25 @@ bool CheckVectorElementCallArgs(Sema *S, CallExpr *TheCall) { return true; } +bool CheckArgTypeWithoutImplicits( + Sema *S, Expr *Arg, QualType ExpectedType, + llvm::function_ref<bool(clang::QualType PassedType)> Check) { + + QualType ArgTy = Arg->IgnoreImpCasts()->getType(); + + clang::QualType BaseType = + ArgTy->isVectorType() + ? ArgTy->getAs<clang::VectorType>()->getElementType() + : ArgTy; + + if (Check(BaseType)) { + S->Diag(Arg->getBeginLoc(), diag::err_typecheck_convert_incompatible) + << ArgTy << ExpectedType << 1 << 0 << 0; + return true; + } + return false; +} + bool CheckArgsTypesAreCorrect( Sema *S, CallExpr *TheCall, QualType ExpectedType, llvm::function_ref<bool(clang::QualType PassedType)> Check) { @@ -1494,6 +1510,14 @@ bool CheckAllArgsHaveFloatRepresentation(Sema *S, CallExpr *TheCall) { checkAllFloatTypes); } +bool CheckArgIsFloatOrIntWithoutImplicits(Sema *S, Expr *Arg) { + auto checkFloat = [](clang::QualType PassedType) -> bool { + return !PassedType->isFloat32Type() && !PassedType->isIntegerType(); + }; + + return CheckArgTypeWithoutImplicits(S, Arg, S->Context.FloatTy, checkFloat); +} + bool CheckFloatOrHalfRepresentations(Sema *S, CallExpr *TheCall) { auto checkFloatorHalf = [](clang::QualType PassedType) -> bool { clang::QualType BaseType = @@ -1652,16 +1676,9 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { if (SemaRef.checkArgCount(TheCall, 1)) return true; - ExprResult A = TheCall->getArg(0); - QualType ArgTyA = A.get()->getType(); - - if(ArgTyA->isVectorType()){ - auto VecTy = TheCall->getArg(0)->getType()->getAs<VectorType>(); - auto ReturnType = this->getASTContext().getVectorType(TheCall->getCallReturnType(this->getASTContext()), VecTy->getNumElements(), - VectorKind::Generic); - - TheCall->setType(ReturnType); - } + Expr *Arg = TheCall->getArg(0); + if (CheckArgIsFloatOrIntWithoutImplicits(&SemaRef, Arg)) + return true; break; } diff --git a/clang/test/CodeGenHLSL/builtins/asuint.hlsl b/clang/test/CodeGenHLSL/builtins/asuint.hlsl index 33acb00ae11182..2ae7d8219ac671 100644 --- a/clang/test/CodeGenHLSL/builtins/asuint.hlsl +++ b/clang/test/CodeGenHLSL/builtins/asuint.hlsl @@ -1,53 +1,26 @@ // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.3-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -o - | FileCheck %s -// // CHECK-LABEL: builtin_test_asuint_float -// // CHECK: bitcast float %0 to i32 -// // CHECK: ret <4 x i32> %dx.clamp -// export uint builtin_test_asuint_float(float p0) { -// return __builtin_hlsl_elementwise_asuint(p0); -// } - -// // CHECK-LABEL: builtin_test_asuint_float -// // CHECK: bitcast float %0 to i32 -// // CHECK: ret <4 x i32> %dx.clamp -// export uint builtin_test_asuint_double(double p0) { -// return __builtin_hlsl_elementwise_asuint(p0); -// } - - -// // CHECK-LABEL: builtin_test_asuint_float -// // CHECK: bitcast float %0 to i32 -// // CHECK: ret <4 x i32> %dx.clamp -// export uint builtin_test_asuint_half(half p0) { -// return __builtin_hlsl_elementwise_asuint(p0); -// } - - -// // CHECK-LABEL: builtin_test_asuint_float -// // CHECK: bitcast float %0 to i32 -// // CHECK: ret <4 x i32> %dx.clamp -// export uint4 builtin_test_asuint_float_vector(float p0) { -// return __builtin_hlsl_elementwise_asuint(p0); -// } - - -// CHECK-LABEL: builtin_test_asuint_float -// CHECK: bitcast float %0 to i32 -// CHECK: ret <4 x i32> %dx.clamp -export uint4 builtin_test_asuint_floa4t(float p0) { +// CHECK-LABEL: test_asuint4_uint +// CHECK: ret i32 %0 +export uint test_asuint4_uint(uint p0) { return asuint(p0); } -// export uint4 builtin_test_asuint4_uint(uint p0) { -// return __builtin_hlsl_elementwise_asuint(p0); -// } - +// CHECK-LABEL: test_asuint4_int +// CHECK: %splat.splatinsert = insertelement <4 x i32> poison, i32 %0, i64 0 +export uint4 test_asuint4_int(int p0) { + return asuint(p0); +} -// export uint4 builtin_test_asuint4_int(int p0) { -// return __builtin_hlsl_elementwise_asuint(p0); -// } +// CHECK-LABEL: test_asuint_float +// CHECK: %1 = bitcast float %0 to i32 +export uint test_asuint_float(float p0) { + return asuint(p0); +} -// export uint builtin_test_asuint_float(float p0) { -// return __builtin_hlsl_elementwise_asuint(p0); -// } \ No newline at end of file +// CHECK-LABEL: test_asuint_float +// CHECK: %1 = bitcast <4 x float> %0 to <4 x i32> +export uint4 test_asuint_float4(float4 p0) { + return asuint(p0); +} \ No newline at end of file diff --git a/clang/test/SemaHLSL/BuiltIns/asuint-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/asuint-errors.hlsl new file mode 100644 index 00000000000000..e9da975bff1b5e --- /dev/null +++ b/clang/test/SemaHLSL/BuiltIns/asuint-errors.hlsl @@ -0,0 +1,18 @@ +// 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 + + +export uint4 test_asuint_too_many_arg(float p0, float p1) { + return __builtin_hlsl_elementwise_asuint(p0, p1); + // expected-error@-1 {{too many arguments to function call, expected 1, have 2}} +} + + +export uint fn(double p1) { + return asuint(p1); + // expected-error@-1 {{passing 'double' to parameter of incompatible type 'float'}} +} + +export uint fn(half p1) { + return asuint(p1); + // expected-error@-1 {{passing 'half' to parameter of incompatible type 'float'}} +} >From d0619c7c9b5aa7a9c4137bf67af5a3647da75236 Mon Sep 17 00:00:00 2001 From: Joao Saffran <jdereze...@microsoft.com> Date: Fri, 6 Sep 2024 18:44:38 +0000 Subject: [PATCH 3/4] Adding `asuint` implementation to hlsl --- clang/include/clang/Basic/Builtins.td | 7 +++- clang/lib/CodeGen/CGBuiltin.cpp | 2 +- clang/lib/Headers/hlsl/hlsl_intrinsics.h | 18 +++++++++ clang/lib/Sema/SemaHLSL.cpp | 32 ++++----------- clang/test/CodeGenHLSL/builtins/asuint.hlsl | 43 ++++++++++++++------- 5 files changed, 61 insertions(+), 41 deletions(-) diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index 83bca9b342ef15..0e6c1c284da6cf 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -53,6 +53,9 @@ class MSInt32_64Template : Template<["msint32_t", "int64_t"], class FloatDoubleTemplate : Template<["float", "double"], ["f", ""]>; +class HLSLFloatAndIntTemplate : Template< + ["unsigned int", "int", "float"], + ["", "si", "f"]>; // FIXME: These assume that char -> i8, short -> i16, int -> i32, // long long -> i64. class SyncBuiltinsTemplate : @@ -4751,10 +4754,10 @@ def HLSLRcp : LangBuiltin<"HLSL_LANG"> { let Prototype = "void(...)"; } -def HLSLAsUint : LangBuiltin<"HLSL_LANG"> { +def HLSLAsUint : LangBuiltin<"HLSL_LANG">, HLSLFloatAndIntTemplate { let Spellings = ["__builtin_hlsl_elementwise_asuint"]; let Attributes = [NoThrow, Const]; - let Prototype = "void(...)"; + let Prototype = "unsigned int (T)"; } def HLSLRSqrt : LangBuiltin<"HLSL_LANG"> { diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index afbcd96bc14b2f..012623a3d7032f 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -18816,7 +18816,7 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: { {}, false, true)); } case Builtin::BI__builtin_hlsl_elementwise_asuint: { - Value *Op = EmitScalarExpr(E->getArg(0)->IgnoreImpCasts()); + Value *Op = EmitScalarExpr(E->getArg(0)); llvm::Type *DestTy = llvm::Type::getInt32Ty(this->getLLVMContext()); diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h index f40469937ddc38..178484f5852f51 100644 --- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h +++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h @@ -404,6 +404,24 @@ uint3 asuint(float3); _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_asuint) uint4 asuint(float4); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_asuint) +uint asuint(uint); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_asuint) +uint2 asuint(uint2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_asuint) +uint3 asuint(uint3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_asuint) +uint4 asuint(uint4); + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_asuint) +uint asuint(int); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_asuint) +uint2 asuint(int2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_asuint) +uint3 asuint(int3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_asuint) +uint4 asuint(int4); + //===----------------------------------------------------------------------===// // atan builtins //===----------------------------------------------------------------------===// diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index 123a724d444c33..10019067c803eb 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -1465,25 +1465,6 @@ bool CheckVectorElementCallArgs(Sema *S, CallExpr *TheCall) { return true; } -bool CheckArgTypeWithoutImplicits( - Sema *S, Expr *Arg, QualType ExpectedType, - llvm::function_ref<bool(clang::QualType PassedType)> Check) { - - QualType ArgTy = Arg->IgnoreImpCasts()->getType(); - - clang::QualType BaseType = - ArgTy->isVectorType() - ? ArgTy->getAs<clang::VectorType>()->getElementType() - : ArgTy; - - if (Check(BaseType)) { - S->Diag(Arg->getBeginLoc(), diag::err_typecheck_convert_incompatible) - << ArgTy << ExpectedType << 1 << 0 << 0; - return true; - } - return false; -} - bool CheckArgsTypesAreCorrect( Sema *S, CallExpr *TheCall, QualType ExpectedType, llvm::function_ref<bool(clang::QualType PassedType)> Check) { @@ -1510,12 +1491,16 @@ bool CheckAllArgsHaveFloatRepresentation(Sema *S, CallExpr *TheCall) { checkAllFloatTypes); } -bool CheckArgIsFloatOrIntWithoutImplicits(Sema *S, Expr *Arg) { +bool CheckNotFloatAndInt(Sema *S, CallExpr *TheCall) { auto checkFloat = [](clang::QualType PassedType) -> bool { - return !PassedType->isFloat32Type() && !PassedType->isIntegerType(); + clang::QualType BaseType = + PassedType->isVectorType() + ? PassedType->getAs<clang::VectorType>()->getElementType() + : PassedType; + return !(BaseType->isFloat32Type() || BaseType->isIntegerType()); }; - return CheckArgTypeWithoutImplicits(S, Arg, S->Context.FloatTy, checkFloat); + return CheckArgsTypesAreCorrect(S, TheCall, S->Context.FloatTy, checkFloat); } bool CheckFloatOrHalfRepresentations(Sema *S, CallExpr *TheCall) { @@ -1676,8 +1661,7 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { if (SemaRef.checkArgCount(TheCall, 1)) return true; - Expr *Arg = TheCall->getArg(0); - if (CheckArgIsFloatOrIntWithoutImplicits(&SemaRef, Arg)) + if (CheckNotFloatAndInt(&SemaRef, TheCall)) return true; break; diff --git a/clang/test/CodeGenHLSL/builtins/asuint.hlsl b/clang/test/CodeGenHLSL/builtins/asuint.hlsl index 2ae7d8219ac671..1edf07942d3a09 100644 --- a/clang/test/CodeGenHLSL/builtins/asuint.hlsl +++ b/clang/test/CodeGenHLSL/builtins/asuint.hlsl @@ -1,26 +1,41 @@ -// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.3-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -o - | FileCheck %s +// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.3-library %s -fnative-half-type -emit-llvm -O1 -o - | FileCheck %s +// CHECK: define {{.*}}test_uint{{.*}}(i32 {{.*}} [[VAL:%.*]]){{.*}} +// CHECK-NOT: bitcast +// CHECK: ret i32 [[VAL]] +export uint test_uint(uint p0) { + return asuint(p0); +} + +// CHECK: define {{.*}}test_int{{.*}}(i32 {{.*}} [[VAL:%.*]]){{.*}} +// CHECK-NOT: bitcast +// CHECK: ret i32 [[VAL]] +export uint test_int(int p0) { + return asuint(p0); +} -// CHECK-LABEL: test_asuint4_uint -// CHECK: ret i32 %0 -export uint test_asuint4_uint(uint p0) { +// CHECK: define {{.*}}test_float{{.*}}(float {{.*}} [[VAL:%.*]]){{.*}} +// CHECK: bitcast float [[VAL]] to i32 +export uint test_float(float p0) { return asuint(p0); } -// CHECK-LABEL: test_asuint4_int -// CHECK: %splat.splatinsert = insertelement <4 x i32> poison, i32 %0, i64 0 -export uint4 test_asuint4_int(int p0) { +// CHECK: define {{.*}}test_vector_uint{{.*}}(<4 x i32> {{.*}} [[VAL:%.*]]){{.*}} +// CHECK-NOT: bitcast +// CHECK: ret <4 x i32> [[VAL]] +export uint4 test_vector_uint(uint4 p0) { return asuint(p0); } -// CHECK-LABEL: test_asuint_float -// CHECK: %1 = bitcast float %0 to i32 -export uint test_asuint_float(float p0) { +// CHECK: define {{.*}}test_vector_int{{.*}}(<4 x i32> {{.*}} [[VAL:%.*]]){{.*}} +// CHECK-NOT: bitcast +// CHECK: ret <4 x i32> [[VAL]] +export uint4 test_vector_int(int4 p0) { return asuint(p0); } -// CHECK-LABEL: test_asuint_float -// CHECK: %1 = bitcast <4 x float> %0 to <4 x i32> -export uint4 test_asuint_float4(float4 p0) { +// CHECK: define {{.*}}test_vector_float{{.*}}(<4 x float> {{.*}} [[VAL:%.*]]){{.*}} +// CHECK: bitcast <4 x float> [[VAL]] to <4 x i32> +export uint4 test_vector_float(float4 p0) { return asuint(p0); -} \ No newline at end of file +} >From 0fc05f8f3fbf4dfa2d70a868ef0fedeec2d0146f Mon Sep 17 00:00:00 2001 From: Joao Saffran <jdereze...@microsoft.com> Date: Mon, 9 Sep 2024 18:35:20 +0000 Subject: [PATCH 4/4] changing asuint implementation to call __builtin_bit_cast --- clang/include/clang/Basic/Builtins.td | 8 +--- clang/lib/CodeGen/CGBuiltin.cpp | 13 ------ clang/lib/Headers/hlsl/hlsl_intrinsics.h | 42 +++++++------------ clang/lib/Sema/SemaHLSL.cpp | 38 ++++++++++------- .../test/SemaHLSL/BuiltIns/asuint-errors.hlsl | 18 ++++---- 5 files changed, 48 insertions(+), 71 deletions(-) diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index 0e6c1c284da6cf..e100c5a0e6214e 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -55,7 +55,7 @@ class FloatDoubleTemplate : Template<["float", "double"], class HLSLFloatAndIntTemplate : Template< ["unsigned int", "int", "float"], - ["", "si", "f"]>; + ["", "i", "f"]>; // FIXME: These assume that char -> i8, short -> i16, int -> i32, // long long -> i64. class SyncBuiltinsTemplate : @@ -4754,12 +4754,6 @@ def HLSLRcp : LangBuiltin<"HLSL_LANG"> { let Prototype = "void(...)"; } -def HLSLAsUint : LangBuiltin<"HLSL_LANG">, HLSLFloatAndIntTemplate { - let Spellings = ["__builtin_hlsl_elementwise_asuint"]; - let Attributes = [NoThrow, Const]; - let Prototype = "unsigned int (T)"; -} - def HLSLRSqrt : LangBuiltin<"HLSL_LANG"> { let Spellings = ["__builtin_hlsl_elementwise_rsqrt"]; let Attributes = [NoThrow, Const]; diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 012623a3d7032f..da7a1a55da5313 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -18815,19 +18815,6 @@ 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_asuint: { - Value *Op = EmitScalarExpr(E->getArg(0)); - - llvm::Type *DestTy = llvm::Type::getInt32Ty(this->getLLVMContext()); - - if (Op->getType()->isVectorTy()) { - const VectorType *VecTy = E->getArg(0)->getType()->getAs<VectorType>(); - DestTy = llvm::VectorType::get( - DestTy, ElementCount::getFixed(VecTy->getNumElements())); - } - - return Builder.CreateBitCast(Op, DestTy); - } case Builtin::BI__builtin_hlsl_wave_is_first_lane: { Intrinsic::ID ID = CGM.getHLSLRuntime().getWaveIsFirstLaneIntrinsic(); return EmitRuntimeCall(Intrinsic::getDeclaration(&CGM.getModule(), ID)); diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h index 178484f5852f51..8a1397cef7255b 100644 --- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h +++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h @@ -395,32 +395,22 @@ float4 asin(float4); /// \brief Interprets the bit pattern of x as an unsigned integer. /// \param Val The input value. -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_asuint) -uint asuint(float); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_asuint) -uint2 asuint(float2); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_asuint) -uint3 asuint(float3); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_asuint) -uint4 asuint(float4); - -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_asuint) -uint asuint(uint); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_asuint) -uint2 asuint(uint2); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_asuint) -uint3 asuint(uint3); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_asuint) -uint4 asuint(uint4); - -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_asuint) -uint asuint(int); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_asuint) -uint2 asuint(int2); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_asuint) -uint3 asuint(int3); -_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_asuint) -uint4 asuint(int4); + +__attribute__((__always_inline__, __nodebug__)) static inline uint asuint(float v) { return __builtin_bit_cast(uint, v); } +__attribute__((__always_inline__, __nodebug__)) static inline uint2 asuint(float2 v) { return __builtin_bit_cast(uint2, v); } +__attribute__((__always_inline__, __nodebug__)) static inline uint3 asuint(float3 v) { return __builtin_bit_cast(uint3, v); } +__attribute__((__always_inline__, __nodebug__)) static inline uint4 asuint(float4 v) { return __builtin_bit_cast(uint4, v); } + +__attribute__((__always_inline__, __nodebug__)) static inline uint asuint(uint v) { return __builtin_bit_cast(uint, v); } +__attribute__((__always_inline__, __nodebug__)) static inline uint2 asuint(uint2 v) { return __builtin_bit_cast(uint2, v); } +__attribute__((__always_inline__, __nodebug__)) static inline uint3 asuint(uint3 v) { return __builtin_bit_cast(uint3, v); } +__attribute__((__always_inline__, __nodebug__)) static inline uint4 asuint(uint4 v) { return __builtin_bit_cast(uint4, v); } + +__attribute__((__always_inline__, __nodebug__)) static inline uint asuint(int v) { return __builtin_bit_cast(uint, v); } +__attribute__((__always_inline__, __nodebug__)) static inline uint2 asuint(int2 v) { return __builtin_bit_cast(uint2, v); } +__attribute__((__always_inline__, __nodebug__)) static inline uint3 asuint(int3 v) { return __builtin_bit_cast(uint3, v); } +__attribute__((__always_inline__, __nodebug__)) static inline uint4 asuint(int4 v) { return __builtin_bit_cast(uint4, v); } + //===----------------------------------------------------------------------===// // atan builtins diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index 10019067c803eb..600a988ce33f09 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -1465,6 +1465,25 @@ bool CheckVectorElementCallArgs(Sema *S, CallExpr *TheCall) { return true; } +bool CheckArgTypeWithoutImplicits( + Sema *S, Expr *Arg, QualType ExpectedType, + llvm::function_ref<bool(clang::QualType PassedType)> Check) { + + QualType ArgTy = Arg->IgnoreImpCasts()->getType(); + + clang::QualType BaseType = + ArgTy->isVectorType() + ? ArgTy->getAs<clang::VectorType>()->getElementType() + : ArgTy; + + if (Check(BaseType)) { + S->Diag(Arg->getBeginLoc(), diag::err_typecheck_convert_incompatible) + << ArgTy << ExpectedType << 1 << 0 << 0; + return true; + } + return false; +} + bool CheckArgsTypesAreCorrect( Sema *S, CallExpr *TheCall, QualType ExpectedType, llvm::function_ref<bool(clang::QualType PassedType)> Check) { @@ -1491,16 +1510,12 @@ bool CheckAllArgsHaveFloatRepresentation(Sema *S, CallExpr *TheCall) { checkAllFloatTypes); } -bool CheckNotFloatAndInt(Sema *S, CallExpr *TheCall) { +bool CheckNotFloatAndIntWithoutImplicits(Sema *S, Expr *Arg) { auto checkFloat = [](clang::QualType PassedType) -> bool { - clang::QualType BaseType = - PassedType->isVectorType() - ? PassedType->getAs<clang::VectorType>()->getElementType() - : PassedType; - return !(BaseType->isFloat32Type() || BaseType->isIntegerType()); + return !(PassedType->isFloat32Type() || PassedType->isIntegerType()); }; - return CheckArgsTypesAreCorrect(S, TheCall, S->Context.FloatTy, checkFloat); + return CheckArgTypeWithoutImplicits(S, Arg, S->Context.FloatTy, checkFloat); } bool CheckFloatOrHalfRepresentations(Sema *S, CallExpr *TheCall) { @@ -1657,15 +1672,6 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { return true; break; } - case Builtin::BI__builtin_hlsl_elementwise_asuint: { - if (SemaRef.checkArgCount(TheCall, 1)) - return true; - - if (CheckNotFloatAndInt(&SemaRef, TheCall)) - return true; - - break; - } case Builtin::BI__builtin_elementwise_acos: case Builtin::BI__builtin_elementwise_asin: case Builtin::BI__builtin_elementwise_atan: diff --git a/clang/test/SemaHLSL/BuiltIns/asuint-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/asuint-errors.hlsl index e9da975bff1b5e..f03a0f96bc76d7 100644 --- a/clang/test/SemaHLSL/BuiltIns/asuint-errors.hlsl +++ b/clang/test/SemaHLSL/BuiltIns/asuint-errors.hlsl @@ -1,18 +1,18 @@ // 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 -export uint4 test_asuint_too_many_arg(float p0, float p1) { - return __builtin_hlsl_elementwise_asuint(p0, p1); - // expected-error@-1 {{too many arguments to function call, expected 1, have 2}} -} +// export uint4 test_asuint_too_many_arg(float p0, float p1) { +// return asuint(p0, p1); +// // expected-error@-1 {{no matching function for call to 'asuint'}} +// } -export uint fn(double p1) { - return asuint(p1); - // expected-error@-1 {{passing 'double' to parameter of incompatible type 'float'}} -} +// export uint fn(double p1) { +// return asuint(p1); +// // expected-error@-1 {{call to 'asuint' is ambiguous}} +// } export uint fn(half p1) { return asuint(p1); - // expected-error@-1 {{passing 'half' to parameter of incompatible type 'float'}} + // expected-error@-1 {{call to 'asuint' is ambiguous}} } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits