https://github.com/tgymnich created https://github.com/llvm/llvm-project/pull/108396
- add handling for unsigned integers to hlsl_elementwise_sign ### Related PRs - https://github.com/llvm/llvm-project/pull/101987 - https://github.com/llvm/llvm-project/pull/101988 - https://github.com/llvm/llvm-project/pull/101989 >From c6d87de9116ce5cb01e479ebfc35e354e98af19f Mon Sep 17 00:00:00 2001 From: Tim Gymnich <tgymn...@icloud.com> Date: Thu, 12 Sep 2024 15:57:20 +0200 Subject: [PATCH] [clang][HLSL] Add sign intrinsic part 4 - add handling for unsigned integers to hlsl_elementwise_sign --- clang/lib/CodeGen/CGBuiltin.cpp | 15 ++++-- clang/lib/Headers/hlsl/hlsl_intrinsics.h | 31 +++++++++++ clang/lib/Sema/SemaHLSL.cpp | 6 +-- clang/test/CodeGenHLSL/builtins/sign.hlsl | 63 +++++++++++++++++++++++ 4 files changed, 108 insertions(+), 7 deletions(-) diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 9950c06a0b9a6b..9ec966b95f8210 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -18871,18 +18871,25 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: { return EmitRuntimeCall(Intrinsic::getDeclaration(&CGM.getModule(), ID)); } case Builtin::BI__builtin_hlsl_elementwise_sign: { - Value *Op0 = EmitScalarExpr(E->getArg(0)); + auto *Arg0 = E->getArg(0); + Value *Op0 = EmitScalarExpr(Arg0); llvm::Type *Xty = Op0->getType(); llvm::Type *retType = llvm::Type::getInt32Ty(this->getLLVMContext()); if (Xty->isVectorTy()) { - auto *XVecTy = E->getArg(0)->getType()->getAs<VectorType>(); + auto *XVecTy = Arg0->getType()->getAs<VectorType>(); retType = llvm::VectorType::get( retType, ElementCount::getFixed(XVecTy->getNumElements())); } - assert((E->getArg(0)->getType()->hasFloatingRepresentation() || - E->getArg(0)->getType()->hasSignedIntegerRepresentation()) && + assert((Arg0->getType()->hasFloatingRepresentation() || + Arg0->getType()->hasIntegerRepresentation()) && "sign operand must have a float or int representation"); + if (Arg0->getType()->hasUnsignedIntegerRepresentation()) { + Value *Cmp = Builder.CreateICmpEQ(Op0, ConstantInt::get(Xty, 0)); + return Builder.CreateSelect(Cmp, ConstantInt::get(retType, 0), + ConstantInt::get(retType, 1), "hlsl.sign"); + } + return Builder.CreateIntrinsic( retType, CGM.getHLSLRuntime().getSignIntrinsic(), ArrayRef<Value *>{Op0}, nullptr, "hlsl.sign"); diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h index 7a1edd93984de7..f1758073600b0c 100644 --- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h +++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h @@ -1847,6 +1847,19 @@ int3 sign(int16_t3); _HLSL_AVAILABILITY(shadermodel, 6.2) _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) int4 sign(int16_t4); + +_HLSL_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) +int sign(uint16_t); +_HLSL_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) +int2 sign(uint16_t2); +_HLSL_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) +int3 sign(uint16_t3); +_HLSL_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) +int4 sign(uint16_t4); #endif _HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) @@ -1871,6 +1884,15 @@ int3 sign(int3); _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) int4 sign(int4); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) +int sign(uint); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) +int2 sign(uint2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) +int3 sign(uint3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) +int4 sign(uint4); + _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) int sign(float); _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) @@ -1889,6 +1911,15 @@ int3 sign(int64_t3); _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) int4 sign(int64_t4); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) +int sign(uint64_t); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) +int2 sign(uint64_t2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) +int3 sign(uint64_t3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) +int4 sign(uint64_t4); + _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) int sign(double); _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_sign) diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index 4e44813fe515ce..e0fdb180ad0358 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -1518,9 +1518,9 @@ bool CheckNoDoubleVectors(Sema *S, CallExpr *TheCall) { return CheckArgsTypesAreCorrect(S, TheCall, S->Context.FloatTy, checkDoubleVector); } -bool CheckFloatingOrSignedIntRepresentation(Sema *S, CallExpr *TheCall) { +bool CheckFloatingOrIntRepresentation(Sema *S, CallExpr *TheCall) { auto checkAllSignedTypes = [](clang::QualType PassedType) -> bool { - return !PassedType->hasSignedIntegerRepresentation() && + return !PassedType->hasIntegerRepresentation() && !PassedType->hasFloatingRepresentation(); }; return CheckArgsTypesAreCorrect(S, TheCall, S->Context.IntTy, @@ -1740,7 +1740,7 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { break; } case Builtin::BI__builtin_hlsl_elementwise_sign: { - if (CheckFloatingOrSignedIntRepresentation(&SemaRef, TheCall)) + if (CheckFloatingOrIntRepresentation(&SemaRef, TheCall)) return true; if (SemaRef.PrepareBuiltinElementwiseMathOneArgCall(TheCall)) return true; diff --git a/clang/test/CodeGenHLSL/builtins/sign.hlsl b/clang/test/CodeGenHLSL/builtins/sign.hlsl index 4bb239fb009e45..8027d47aed9ab2 100644 --- a/clang/test/CodeGenHLSL/builtins/sign.hlsl +++ b/clang/test/CodeGenHLSL/builtins/sign.hlsl @@ -112,6 +112,27 @@ int3 test_sign_int16_t3(int16_t3 p0) { return sign(p0); } // NATIVE_HALF: %hlsl.sign = call <4 x i32> @llvm.[[TARGET]].sign.v4i16( // NATIVE_HALF: ret <4 x i32> %hlsl.sign int4 test_sign_int16_t4(int16_t4 p0) { return sign(p0); } + + +// NATIVE_HALF: define [[FNATTRS]] i32 @ +// NATIVE_HALF: [[CMP:%.*]] = icmp eq i16 [[ARG:%.*]], 0 +// NATIVE_HALF: %hlsl.sign = select i1 [[CMP]], i32 0, i32 1 +int test_sign_uint16_t(uint16_t p0) { return sign(p0); } + +// NATIVE_HALF: define [[FNATTRS]] <2 x i32> @ +// NATIVE_HALF: [[CMP:%.*]] = icmp eq <2 x i16> [[ARG:%.*]], zeroinitializer +// NATIVE_HALF: %hlsl.sign = select <2 x i1> [[CMP]], <2 x i32> zeroinitializer, <2 x i32> <i32 1, i32 1> +int2 test_sign_uint16_t2(uint16_t2 p0) { return sign(p0); } + +// NATIVE_HALF: define [[FNATTRS]] <3 x i32> @ +// NATIVE_HALF: [[CMP:%.*]] = icmp eq <3 x i16> [[ARG:%.*]], zeroinitializer +// NATIVE_HALF: %hlsl.sign = select <3 x i1> [[CMP]], <3 x i32> zeroinitializer, <3 x i32> <i32 1, i32 1, i32 1> +int3 test_sign_uint16_t3(uint16_t3 p0) { return sign(p0); } + +// NATIVE_HALF: define [[FNATTRS]] <4 x i32> @ +// NATIVE_HALF: [[CMP:%.*]] = icmp eq <4 x i16> [[ARG:%.*]], zeroinitializer +// NATIVE_HALF: %hlsl.sign = select <4 x i1> [[CMP]], <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 1, i32 1, i32 1> +int4 test_sign_uint16_t4(uint16_t4 p0) { return sign(p0); } #endif // __HLSL_ENABLE_16_BIT @@ -136,6 +157,27 @@ int3 test_sign_int3(int3 p0) { return sign(p0); } int4 test_sign_int4(int4 p0) { return sign(p0); } +// CHECK: define [[FNATTRS]] i32 @ +// CHECK: [[CMP:%.*]] = icmp eq i32 [[ARG:%.*]], 0 +// CHECK: %hlsl.sign = select i1 [[CMP]], i32 0, i32 1 +int test_sign_uint(uint p0) { return sign(p0); } + +// CHECK: define [[FNATTRS]] <2 x i32> @ +// CHECK: [[CMP:%.*]] = icmp eq <2 x i32> [[ARG:%.*]], zeroinitializer +// CHECK: %hlsl.sign = select <2 x i1> [[CMP]], <2 x i32> zeroinitializer, <2 x i32> <i32 1, i32 1> +int2 test_sign_uint2(uint2 p0) { return sign(p0); } + +// CHECK: define [[FNATTRS]] <3 x i32> @ +// CHECK: [[CMP:%.*]] = icmp eq <3 x i32> [[ARG:%.*]], zeroinitializer +// CHECK: %hlsl.sign = select <3 x i1> [[CMP]], <3 x i32> zeroinitializer, <3 x i32> <i32 1, i32 1, i32 1> +int3 test_sign_uint3(uint3 p0) { return sign(p0); } + +// CHECK: define [[FNATTRS]] <4 x i32> @ +// CHECK: [[CMP:%.*]] = icmp eq <4 x i32> [[ARG:%.*]], zeroinitializer +// CHECK: %hlsl.sign = select <4 x i1> [[CMP]], <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 1, i32 1, i32 1> +int4 test_sign_uint4(uint4 p0) { return sign(p0); } + + // CHECK: define [[FNATTRS]] i32 @ // CHECK: %hlsl.sign = call i32 @llvm.[[TARGET]].sign.i64( // CHECK: ret i32 %hlsl.sign @@ -155,3 +197,24 @@ int3 test_sign_int64_t3(int64_t3 p0) { return sign(p0); } // CHECK: %hlsl.sign = call <4 x i32> @llvm.[[TARGET]].sign.v4i64( // CHECK: ret <4 x i32> %hlsl.sign int4 test_sign_int64_t4(int64_t4 p0) { return sign(p0); } + + +// CHECK: define [[FNATTRS]] i32 @ +// CHECK: [[CMP:%.*]] = icmp eq i64 [[ARG:%.*]], 0 +// CHECK: %hlsl.sign = select i1 [[CMP]], i32 0, i32 1 +int test_sign_int64_t(uint64_t p0) { return sign(p0); } + +// CHECK: define [[FNATTRS]] <2 x i32> @ +// CHECK: [[CMP:%.*]] = icmp eq <2 x i64> [[ARG:%.*]], zeroinitializer +// CHECK: %hlsl.sign = select <2 x i1> [[CMP]], <2 x i32> zeroinitializer, <2 x i32> <i32 1, i32 1> +int2 test_sign_int64_t2(uint64_t2 p0) { return sign(p0); } + +// CHECK: define [[FNATTRS]] <3 x i32> @ +// CHECK: [[CMP:%.*]] = icmp eq <3 x i64> [[ARG:%.*]], zeroinitializer +// CHECK: %hlsl.sign = select <3 x i1> [[CMP]], <3 x i32> zeroinitializer, <3 x i32> <i32 1, i32 1, i32 1> +int3 test_sign_int64_t3(uint64_t3 p0) { return sign(p0); } + +// CHECK: define [[FNATTRS]] <4 x i32> @ +// CHECK: [[CMP:%.*]] = icmp eq <4 x i64> [[ARG:%.*]], zeroinitializer +// CHECK: %hlsl.sign = select <4 x i1> [[CMP]], <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 1, i32 1, i32 1> +int4 test_sign_int64_t4(uint64_t4 p0) { return sign(p0); } \ No newline at end of file _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits