https://github.com/djb updated https://github.com/llvm/llvm-project/pull/235542
>From c336ff6cb6c39340e760724cc5c4071caea951b5 Mon Sep 17 00:00:00 2001 From: David Browne <[email protected]> Date: Wed, 28 Oct 2026 23:01:32 +0100 Subject: [PATCH] add matrix support for sign Implement matrix support for sign and add matrix codegen and sema tests. Also fix a sema bug by rejecting boolean matrix and vector inputs to __builtin_hlsl_elementwise_sign, consistent with the builtin's rejection of scalar boolean inputs. Backend tests were not added as no modifications were made to either backend. --- clang/include/clang/Basic/HLSLIntrinsics.td | 1 - clang/lib/AST/Type.cpp | 2 + clang/lib/CodeGen/CGHLSLBuiltins.cpp | 8 +-- clang/lib/Sema/SemaHLSL.cpp | 12 ++-- clang/test/CodeGenHLSL/builtins/sign_mat.hlsl | 60 +++++++++++++++++++ clang/test/SemaHLSL/BuiltIns/sign-errors.hlsl | 9 ++- .../SemaHLSL/BuiltIns/sign_mat-errors.hlsl | 13 ++++ 7 files changed, 90 insertions(+), 15 deletions(-) create mode 100644 clang/test/CodeGenHLSL/builtins/sign_mat.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/sign_mat-errors.hlsl diff --git a/clang/include/clang/Basic/HLSLIntrinsics.td b/clang/include/clang/Basic/HLSLIntrinsics.td index fd59e3477b8c79..583917ca4030b5 100644 --- a/clang/include/clang/Basic/HLSLIntrinsics.td +++ b/clang/include/clang/Basic/HLSLIntrinsics.td @@ -1559,7 +1559,6 @@ def hlsl_sign : HLSLOneArgBuiltin<"sign", "__builtin_hlsl_elementwise_sign"> { let ReturnType = VaryingShape<IntTy>; let VaryingTypes = AllNumericTypes; let VaryingLongVector = 1; - let VaryingMatDims = []; } // Returns the sine of the input value, Val. diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 4c5f2f60a90005..8cbad334ebc467 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -2245,6 +2245,8 @@ bool Type::hasAutoForTrailingReturnType() const { bool Type::hasIntegerRepresentation() const { if (const auto *VT = dyn_cast<VectorType>(CanonicalType)) return VT->getElementType()->isIntegerType(); + if (const auto *MT = dyn_cast<MatrixType>(CanonicalType)) + return MT->getElementType()->isIntegerType(); if (CanonicalType->isSveVLSBuiltinType()) { const auto *VT = cast<BuiltinType>(CanonicalType); return VT->getKind() == BuiltinType::SveBool || diff --git a/clang/lib/CodeGen/CGHLSLBuiltins.cpp b/clang/lib/CodeGen/CGHLSLBuiltins.cpp index fc422918499ed2..2281e96889a770 100644 --- a/clang/lib/CodeGen/CGHLSLBuiltins.cpp +++ b/clang/lib/CodeGen/CGHLSLBuiltins.cpp @@ -1751,12 +1751,8 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, 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 = Arg0->getType()->castAs<VectorType>(); - retType = llvm::VectorType::get( - retType, ElementCount::getFixed(XVecTy->getNumElements())); - } + llvm::Type *retType = getAggregateType( + llvm::Type::getInt32Ty(this->getLLVMContext()), Arg0->getType()); assert((Arg0->getType()->hasFloatingRepresentation() || Arg0->getType()->hasIntegerRepresentation()) && "sign operand must have a float or int representation"); diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index f3fd1fb68c0727..e61d66833b7372 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -3796,11 +3796,11 @@ static bool CheckNoDoubleVectors(Sema *S, SourceLocation Loc, int ArgOrdinal, return false; } -static bool CheckFloatingOrIntRepresentation(Sema *S, SourceLocation Loc, - int ArgOrdinal, - clang::QualType PassedType) { - if (!PassedType->hasIntegerRepresentation() && - !PassedType->hasFloatingRepresentation()) +static bool CheckFloatingOrNonBoolIntRepresentation( + Sema *S, SourceLocation Loc, int ArgOrdinal, clang::QualType PassedType) { + if (getScalarComponentType(PassedType)->isBooleanType() || + (!PassedType->hasIntegerRepresentation() && + !PassedType->hasFloatingRepresentation())) return S->Diag(Loc, diag::err_builtin_invalid_arg_type) << ArgOrdinal << /* scalar or vector of */ 5 << /* integer */ 1 << /* fp */ 1 << PassedType; @@ -5146,7 +5146,7 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { if (SemaRef.PrepareBuiltinElementwiseMathOneArgCall(TheCall)) return true; if (CheckAllArgTypesAreCorrect(&SemaRef, TheCall, - CheckFloatingOrIntRepresentation)) + CheckFloatingOrNonBoolIntRepresentation)) return true; SetElementTypeAsReturnType(&SemaRef, TheCall, getASTContext().IntTy); break; diff --git a/clang/test/CodeGenHLSL/builtins/sign_mat.hlsl b/clang/test/CodeGenHLSL/builtins/sign_mat.hlsl new file mode 100644 index 00000000000000..018ef3dbd6d8ae --- /dev/null +++ b/clang/test/CodeGenHLSL/builtins/sign_mat.hlsl @@ -0,0 +1,60 @@ +// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ +// RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type -fnative-int16-type \ +// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \ +// RUN: --check-prefixes=CHECK,NATIVE_HALF \ +// RUN: -DTARGET=dx -DFNATTRS="hidden noundef" +// 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,NO_HALF \ +// RUN: -DTARGET=dx -DFNATTRS="hidden noundef" +// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ +// RUN: spirv-unknown-vulkan-library %s -fnative-half-type -fnative-int16-type \ +// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \ +// RUN: --check-prefixes=CHECK,NATIVE_HALF \ +// RUN: -DTARGET=spv -DFNATTRS="hidden spir_func noundef" +// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ +// RUN: spirv-unknown-vulkan-library %s -emit-llvm -disable-llvm-passes \ +// RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF \ +// RUN: -DTARGET=spv -DFNATTRS="hidden spir_func noundef" + +// CHECK-LABEL: test_sign_half2x3 +// NATIVE_HALF: call <6 x i32> @llvm.[[TARGET]].sign.v6f16(<6 x half> %{{.*}}) +// NO_HALF: call <6 x i32> @llvm.[[TARGET]].sign.v6f32(<6 x float> %{{.*}}) +int2x3 test_sign_half2x3(half2x3 p0) { return sign(p0); } + +// CHECK-LABEL: test_sign_half3x4 +// NATIVE_HALF: call <12 x i32> @llvm.[[TARGET]].sign.v12f16(<12 x half> %{{.*}}) +// NO_HALF: call <12 x i32> @llvm.[[TARGET]].sign.v12f32(<12 x float> %{{.*}}) +int3x4 test_sign_half3x4(half3x4 p0) { return sign(p0); } + +// CHECK-LABEL: test_sign_half4x4 +// NATIVE_HALF: call <16 x i32> @llvm.[[TARGET]].sign.v16f16(<16 x half> %{{.*}}) +// NO_HALF: call <16 x i32> @llvm.[[TARGET]].sign.v16f32(<16 x float> %{{.*}}) +int4x4 test_sign_half4x4(half4x4 p0) { return sign(p0); } + +// CHECK-LABEL: test_sign_int2x3 +// CHECK: call <6 x i32> @llvm.[[TARGET]].sign.v6i32(<6 x i32> %{{.*}}) +int2x3 test_sign_int2x3(int2x3 p0) { return sign(p0); } + +// CHECK-LABEL: test_sign_int3x4 +// CHECK: call <12 x i32> @llvm.[[TARGET]].sign.v12i32(<12 x i32> %{{.*}}) +int3x4 test_sign_int3x4(int3x4 p0) { return sign(p0); } + +// CHECK-LABEL: test_sign_int4x4 +// CHECK: call <16 x i32> @llvm.[[TARGET]].sign.v16i32(<16 x i32> %{{.*}}) +int4x4 test_sign_int4x4(int4x4 p0) { return sign(p0); } + +// CHECK-LABEL: test_sign_uint2x3 +// CHECK: [[CMP:%.*]] = icmp eq <6 x i32> %{{.*}}, zeroinitializer +// CHECK: %hlsl.sign = select <6 x i1> [[CMP]], <6 x i32> zeroinitializer, <6 x i32> splat (i32 1) +int2x3 test_sign_uint2x3(uint2x3 p0) { return sign(p0); } + +// CHECK-LABEL: test_sign_uint3x4 +// CHECK: [[CMP:%.*]] = icmp eq <12 x i32> %{{.*}}, zeroinitializer +// CHECK: %hlsl.sign = select <12 x i1> [[CMP]], <12 x i32> zeroinitializer, <12 x i32> splat (i32 1) +int3x4 test_sign_uint3x4(uint3x4 p0) { return sign(p0); } + +// CHECK-LABEL: test_sign_uint4x4 +// CHECK: [[CMP:%.*]] = icmp eq <16 x i32> %{{.*}}, zeroinitializer +// CHECK: %hlsl.sign = select <16 x i1> [[CMP]], <16 x i32> zeroinitializer, <16 x i32> splat (i32 1) +int4x4 test_sign_uint4x4(uint4x4 p0) { return sign(p0); } diff --git a/clang/test/SemaHLSL/BuiltIns/sign-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/sign-errors.hlsl index 68583d10d12876..31a6368e3f779a 100644 --- a/clang/test/SemaHLSL/BuiltIns/sign-errors.hlsl +++ b/clang/test/SemaHLSL/BuiltIns/sign-errors.hlsl @@ -10,7 +10,12 @@ bool2 test_too_many_arg(float2 p0) { // expected-error@-1 {{too many arguments to function call, expected 1, have 2}} } -bool builtin_bool_to_float_type_promotion(bool p1) { +bool builtin_sign_bool(bool p1) { return __builtin_hlsl_elementwise_sign(p1); - // expected-error@-1 {passing 'bool' to parameter of incompatible type 'float'}} + // expected-error@-1 {{1st argument must be a vector, integer or floating-point type (was 'bool')}} +} + +int2 builtin_sign_bool2(bool2 p0) { + return __builtin_hlsl_elementwise_sign(p0); + // expected-error@-1 {{1st argument must be a scalar or vector of integer or floating-point types (was 'bool2' (aka 'vector<bool, 2>'))}} } diff --git a/clang/test/SemaHLSL/BuiltIns/sign_mat-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/sign_mat-errors.hlsl new file mode 100644 index 00000000000000..5c0032b669069c --- /dev/null +++ b/clang/test/SemaHLSL/BuiltIns/sign_mat-errors.hlsl @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -fnative-int16-type -emit-llvm-only -disable-llvm-passes -verify + +int2x2 test_too_many_arg(float2x2 p0) { + return __builtin_hlsl_elementwise_sign(p0, p0); + // expected-error@-1 2 {{cannot pass object of non-trivial type 'float2x2' (aka 'matrix<float, 2, 2>') through variadic function; call will abort at runtime}} + // expected-error@-2 {{too many arguments to function call, expected 1, have 2}} +} + +int2x2 test_bool_matrix(bool2x2 p0) { + return __builtin_hlsl_elementwise_sign(p0); + // expected-error@-1 {{cannot pass object of non-trivial type 'bool2x2' (aka 'matrix<bool, 2, 2>') through variadic function; call will abort at runtime}} + // expected-error@-2 {{1st argument must be a scalar or vector of integer or floating-point types (was 'bool2x2' (aka 'matrix<bool, 2, 2>'))}} +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
