-
Notifications
You must be signed in to change notification settings - Fork 11.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[clang][HLSL] Add sign intrinsic part 4 #108396
Conversation
@llvm/pr-subscribers-backend-x86 @llvm/pr-subscribers-clang Author: Tim Gymnich (tgymnich) Changes
Related PRs
Full diff: https://github.com/llvm/llvm-project/pull/108396.diff 4 Files Affected:
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
|
// 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); } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add a new line.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
- add handling for unsigned integers to hlsl_elementwise_sign
@tgymnich I think its time for you to ask for commit access. Follow these steps: https://llvm.org/docs/DeveloperPolicy.html#obtaining-commit-access |
Will do that. I just rebased the PR, so feel free to merge this for me in the meanwhile. |
Build failure was on |
- Add handling for unsigned integers to hlsl_elementwise_sign - Use `select` instead of adding dx and spirv intrinsics for unsigned integers as [discussed previously ](llvm#101988 (comment)) fixes llvm#70078 ### Related PRs - llvm#101987 - llvm#101988 - llvm#101989 cc @farzonl @pow2clk @bob80905 @bogner @llvm-beanz
// 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); } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The function names are missing a 'u'
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix test names changing `int` to `uint`. #108396 (comment) @bob80905
Fix test names changing `int` to `uint`. llvm#108396 (comment) @bob80905
Fix test names changing `int` to `uint`. llvm#108396 (comment) @bob80905
select
instead of adding dx and spirv intrinsics for unsigned integers as discussed previouslyfixes #70078
Related PRs
cc @farzonl @pow2clk @bob80905 @bogner @llvm-beanz