Skip to content

[clang][HLSL] Add sign intrinsic part 4 #108396

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

Merged
merged 1 commit into from
Oct 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions clang/lib/CodeGen/CGBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18876,18 +18876,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");
Expand Down
31 changes: 31 additions & 0 deletions clang/lib/Headers/hlsl/hlsl_intrinsics.h
Original file line number Diff line number Diff line change
Expand Up @@ -2088,6 +2088,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)
Expand All @@ -2112,6 +2125,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)
Expand All @@ -2130,6 +2152,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)
Expand Down
6 changes: 3 additions & 3 deletions clang/lib/Sema/SemaHLSL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1708,9 +1708,9 @@ static bool CheckNoDoubleVectors(Sema *S, CallExpr *TheCall) {
return CheckArgsTypesAreCorrect(S, TheCall, S->Context.FloatTy,
checkDoubleVector);
}
static bool CheckFloatingOrSignedIntRepresentation(Sema *S, CallExpr *TheCall) {
static 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,
Expand Down Expand Up @@ -1966,7 +1966,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;
Expand Down
63 changes: 63 additions & 0 deletions clang/test/CodeGenHLSL/builtins/sign.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand All @@ -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
Expand All @@ -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); }
Copy link
Contributor

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'

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


// 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); }
Loading