Skip to content
Open
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
3 changes: 3 additions & 0 deletions clang/include/clang/AST/OperationKinds.def
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,9 @@ CAST_OPERATION(IntToOCLSampler)
// Truncate a vector type by dropping elements from the end (HLSL only).
CAST_OPERATION(HLSLVectorTruncation)

// Truncate a matrix type by dropping elements from the end (HLSL only).
CAST_OPERATION(HLSLMatrixTruncation)

// Non-decaying array RValue cast (HLSL only).
CAST_OPERATION(HLSLArrayRValue)

Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Sema/Overload.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,9 @@ class Sema;
/// HLSL vector truncation.
ICK_HLSL_Vector_Truncation,

/// HLSL Matrix truncation.
ICK_HLSL_Matrix_Truncation,

/// HLSL non-decaying array rvalue cast.
ICK_HLSL_Array_RValue,

Expand Down
1 change: 1 addition & 0 deletions clang/lib/AST/Expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1937,6 +1937,7 @@ bool CastExpr::CastConsistency() const {
case CK_FixedPointToBoolean:
case CK_HLSLArrayRValue:
case CK_HLSLVectorTruncation:
case CK_HLSLMatrixTruncation:
case CK_HLSLElementwiseCast:
case CK_HLSLAggregateSplatCast:
CheckNoBasePath:
Expand Down
13 changes: 13 additions & 0 deletions clang/lib/AST/ExprConstant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11773,6 +11773,10 @@ bool VectorExprEvaluator::VisitCastExpr(const CastExpr *E) {
Elements.push_back(Val.getVectorElt(I));
return Success(Elements, E);
}
case CK_HLSLMatrixTruncation: {
// TODO: See #168935. Add matrix truncation support to expr constant.
return Error(E);
}
case CK_HLSLAggregateSplatCast: {
APValue Val;
QualType ValTy;
Expand Down Expand Up @@ -18011,6 +18015,10 @@ bool IntExprEvaluator::VisitCastExpr(const CastExpr *E) {
return Error(E);
return Success(Val.getVectorElt(0), E);
}
case CK_HLSLMatrixTruncation: {
// TODO: See #168935. Add matrix truncation support to expr constant.
return Error(E);
}
case CK_HLSLElementwiseCast: {
SmallVector<APValue> SrcVals;
SmallVector<QualType> SrcTypes;
Expand Down Expand Up @@ -18604,6 +18612,10 @@ bool FloatExprEvaluator::VisitCastExpr(const CastExpr *E) {
return Error(E);
return Success(Val.getVectorElt(0), E);
}
case CK_HLSLMatrixTruncation: {
// TODO: See #168935. Add matrix truncation support to expr constant.
return Error(E);
}
case CK_HLSLElementwiseCast: {
SmallVector<APValue> SrcVals;
SmallVector<QualType> SrcTypes;
Expand Down Expand Up @@ -18761,6 +18773,7 @@ bool ComplexExprEvaluator::VisitCastExpr(const CastExpr *E) {
case CK_IntegralToFixedPoint:
case CK_MatrixCast:
case CK_HLSLVectorTruncation:
case CK_HLSLMatrixTruncation:
case CK_HLSLElementwiseCast:
case CK_HLSLAggregateSplatCast:
llvm_unreachable("invalid cast kind for complex value");
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/CIR/CodeGen/CIRGenExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ Address CIRGenFunction::emitPointerWithAlignment(const Expr *expr,
case CK_HLSLArrayRValue:
case CK_HLSLElementwiseCast:
case CK_HLSLVectorTruncation:
case CK_HLSLMatrixTruncation:
case CK_IntToOCLSampler:
case CK_IntegralCast:
case CK_IntegralComplexCast:
Expand Down Expand Up @@ -1279,6 +1280,7 @@ LValue CIRGenFunction::emitCastLValue(const CastExpr *e) {
case CK_IntegralToFixedPoint:
case CK_MatrixCast:
case CK_HLSLVectorTruncation:
case CK_HLSLMatrixTruncation:
case CK_HLSLArrayRValue:
case CK_HLSLElementwiseCast:
case CK_HLSLAggregateSplatCast:
Expand Down
1 change: 1 addition & 0 deletions clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,7 @@ mlir::Value ComplexExprEmitter::emitCast(CastKind ck, Expr *op,
case CK_IntegralToFixedPoint:
case CK_MatrixCast:
case CK_HLSLVectorTruncation:
case CK_HLSLMatrixTruncation:
case CK_HLSLArrayRValue:
case CK_HLSLElementwiseCast:
case CK_HLSLAggregateSplatCast:
Expand Down
1 change: 1 addition & 0 deletions clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1012,6 +1012,7 @@ class ConstExprEmitter
case CK_MatrixCast:
case CK_HLSLArrayRValue:
case CK_HLSLVectorTruncation:
case CK_HLSLMatrixTruncation:
case CK_HLSLElementwiseCast:
case CK_HLSLAggregateSplatCast:
return {};
Expand Down
1 change: 1 addition & 0 deletions clang/lib/CodeGen/CGExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5744,6 +5744,7 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {
case CK_IntegralToFixedPoint:
case CK_MatrixCast:
case CK_HLSLVectorTruncation:
case CK_HLSLMatrixTruncation:
case CK_HLSLArrayRValue:
case CK_HLSLElementwiseCast:
case CK_HLSLAggregateSplatCast:
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/CodeGen/CGExprAgg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1036,7 +1036,7 @@ void AggExprEmitter::VisitCastExpr(CastExpr *E) {
case CK_ZeroToOCLOpaqueType:
case CK_MatrixCast:
case CK_HLSLVectorTruncation:

case CK_HLSLMatrixTruncation:
case CK_IntToOCLSampler:
case CK_FloatingToFixedPoint:
case CK_FixedPointToFloating:
Expand Down Expand Up @@ -1550,6 +1550,7 @@ static bool castPreservesZero(const CastExpr *CE) {
case CK_NonAtomicToAtomic:
case CK_AtomicToNonAtomic:
case CK_HLSLVectorTruncation:
case CK_HLSLMatrixTruncation:
case CK_HLSLElementwiseCast:
case CK_HLSLAggregateSplatCast:
return true;
Expand Down
1 change: 1 addition & 0 deletions clang/lib/CodeGen/CGExprComplex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,7 @@ ComplexPairTy ComplexExprEmitter::EmitCast(CastKind CK, Expr *Op,
case CK_IntegralToFixedPoint:
case CK_MatrixCast:
case CK_HLSLVectorTruncation:
case CK_HLSLMatrixTruncation:
case CK_HLSLArrayRValue:
case CK_HLSLElementwiseCast:
case CK_HLSLAggregateSplatCast:
Expand Down
1 change: 1 addition & 0 deletions clang/lib/CodeGen/CGExprConstant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1333,6 +1333,7 @@ class ConstExprEmitter
case CK_ZeroToOCLOpaqueType:
case CK_MatrixCast:
case CK_HLSLVectorTruncation:
case CK_HLSLMatrixTruncation:
case CK_HLSLArrayRValue:
case CK_HLSLElementwiseCast:
case CK_HLSLAggregateSplatCast:
Expand Down
35 changes: 34 additions & 1 deletion clang/lib/CodeGen/CGExprScalar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2422,9 +2422,27 @@ static Value *EmitHLSLElementwiseCast(CodeGenFunction &CGF, LValue SrcVal,
}
return V;
}
if (auto *MatTy = DestTy->getAs<ConstantMatrixType>()) {
assert(LoadList.size() >= MatTy->getNumElementsFlattened() &&
"Flattened type on RHS must have the same number or more elements "
"than vector on LHS.");
llvm::Value *V =
CGF.Builder.CreateLoad(CGF.CreateIRTemp(DestTy, "flatcast.tmp"));
// write to V.
for (unsigned I = 0, E = MatTy->getNumElementsFlattened(); I < E; I++) {
RValue RVal = CGF.EmitLoadOfLValue(LoadList[I], Loc);
assert(RVal.isScalar() &&
"All flattened source values should be scalars.");
llvm::Value *Cast =
CGF.EmitScalarConversion(RVal.getScalarVal(), LoadList[I].getType(),
MatTy->getElementType(), Loc);
V = CGF.Builder.CreateInsertElement(V, Cast, I);
}
return V;
}
// if its a builtin just do an extract element or load.
assert(DestTy->isBuiltinType() &&
"Destination type must be a vector or builtin type.");
"Destination type must be a vector, matrix, or builtin type.");
RValue RVal = CGF.EmitLoadOfLValue(LoadList[0], Loc);
assert(RVal.isScalar() && "All flattened source values should be scalars.");
return CGF.EmitScalarConversion(RVal.getScalarVal(), LoadList[0].getType(),
Expand Down Expand Up @@ -2954,6 +2972,21 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
llvm::Value *Zero = llvm::Constant::getNullValue(CGF.SizeTy);
return Builder.CreateExtractElement(Vec, Zero, "cast.vtrunc");
}
case CK_HLSLMatrixTruncation: {
assert((DestTy->isMatrixType() || DestTy->isBuiltinType()) &&
"Destination type must be a matrix or builtin type.");
Value *Mat = Visit(E);
if (auto *MatTy = DestTy->getAs<ConstantMatrixType>()) {
SmallVector<int> Mask;
unsigned NumElts = MatTy->getNumElementsFlattened();
for (unsigned I = 0; I != NumElts; ++I)
Mask.push_back(I);

return Builder.CreateShuffleVector(Mat, Mask, "trunc");
}
llvm::Value *Zero = llvm::Constant::getNullValue(CGF.SizeTy);
return Builder.CreateExtractElement(Mat, Zero, "cast.mtrunc");
}
case CK_HLSLElementwiseCast: {
RValue RV = CGF.EmitAnyExpr(E);
SourceLocation Loc = CE->getExprLoc();
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Edit/RewriteObjCFoundationAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1085,6 +1085,7 @@ static bool rewriteToNumericBoxedExpression(const ObjCMessageExpr *Msg,
llvm_unreachable("OpenCL-specific cast in Objective-C?");

case CK_HLSLVectorTruncation:
case CK_HLSLMatrixTruncation:
case CK_HLSLElementwiseCast:
case CK_HLSLAggregateSplatCast:
llvm_unreachable("HLSL-specific cast in Objective-C?");
Expand Down
22 changes: 16 additions & 6 deletions clang/lib/Sema/SemaExprCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5197,19 +5197,18 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
case ICK_Incompatible_Pointer_Conversion:
case ICK_HLSL_Array_RValue:
case ICK_HLSL_Vector_Truncation:
case ICK_HLSL_Matrix_Truncation:
case ICK_HLSL_Vector_Splat:
llvm_unreachable("Improper second standard conversion");
}

if (SCS.Dimension != ICK_Identity) {
// If SCS.Element is not ICK_Identity the To and From types must be HLSL
// vectors or matrices.

// TODO: Support HLSL matrices.
assert((!From->getType()->isMatrixType() && !ToType->isMatrixType()) &&
"Dimension conversion for matrix types is not implemented yet.");
assert((ToType->isVectorType() || ToType->isBuiltinType()) &&
"Dimension conversion output must be vector or scalar type.");
assert(
(ToType->isVectorType() || ToType->isConstantMatrixType() ||
ToType->isBuiltinType()) &&
"Dimension conversion output must be vector, matrix, or scalar type.");
switch (SCS.Dimension) {
case ICK_HLSL_Vector_Splat: {
// Vector splat from any arithmetic type to a vector.
Expand All @@ -5235,6 +5234,17 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,

break;
}
case ICK_HLSL_Matrix_Truncation: {
auto *FromMat = From->getType()->castAs<ConstantMatrixType>();
QualType TruncTy = FromMat->getElementType();
if (auto *ToMat = ToType->getAs<ConstantMatrixType>())
TruncTy = Context.getConstantMatrixType(TruncTy, ToMat->getNumRows(),
ToMat->getNumColumns());
From = ImpCastExprToType(From, TruncTy, CK_HLSLMatrixTruncation,
From->getValueKind())
.get();
break;
}
case ICK_Identity:
default:
llvm_unreachable("Improper element standard conversion");
Expand Down
5 changes: 4 additions & 1 deletion clang/lib/Sema/SemaHLSL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3728,7 +3728,6 @@ bool SemaHLSL::CanPerformAggregateSplatCast(Expr *Src, QualType DestTy) {
}

// Can we perform an HLSL Elementwise cast?
// TODO: update this code when matrices are added; see issue #88060
bool SemaHLSL::CanPerformElementwiseCast(Expr *Src, QualType DestTy) {

// Don't handle casts where LHS and RHS are any combination of scalar/vector
Expand All @@ -3741,6 +3740,10 @@ bool SemaHLSL::CanPerformElementwiseCast(Expr *Src, QualType DestTy) {
(DestTy->isScalarType() || DestTy->isVectorType()))
return false;

if (SrcTy->isConstantMatrixType() &&
(DestTy->isScalarType() || DestTy->isConstantMatrixType()))
return false;

llvm::SmallVector<QualType> DestTypes;
BuildFlattenedTypeList(DestTy, DestTypes);
llvm::SmallVector<QualType> SrcTypes;
Expand Down
73 changes: 67 additions & 6 deletions clang/lib/Sema/SemaOverload.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ ImplicitConversionRank clang::GetConversionRank(ImplicitConversionKind Kind) {
ICR_C_Conversion_Extension,
ICR_Conversion,
ICR_HLSL_Dimension_Reduction,
ICR_HLSL_Dimension_Reduction,
Copy link
Collaborator

Choose a reason for hiding this comment

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

We should make sure the language spec is up to date with the conversion ranks (see: https://github.com/microsoft/hlsl-specs/blob/main/specs/language/overloading.tex#L296).

Copy link
Member Author

Choose a reason for hiding this comment

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

Working on a spec pr update.

ICR_Conversion,
ICR_HLSL_Scalar_Widening,
};
Expand Down Expand Up @@ -224,6 +225,7 @@ static const char *GetImplicitConversionName(ImplicitConversionKind Kind) {
"Incompatible pointer conversion",
"Fixed point conversion",
"HLSL vector truncation",
"HLSL matrix truncation",
"Non-decaying array conversion",
"HLSL vector splat",
};
Expand Down Expand Up @@ -2046,9 +2048,10 @@ static bool IsFloatingPointConversion(Sema &S, QualType FromType,
return true;
}

static bool IsVectorElementConversion(Sema &S, QualType FromType,
QualType ToType,
ImplicitConversionKind &ICK, Expr *From) {
static bool IsVectorOrMatrixElementConversion(Sema &S, QualType FromType,
QualType ToType,
ImplicitConversionKind &ICK,
Expr *From) {
if (S.Context.hasSameUnqualifiedType(FromType, ToType))
return true;

Expand Down Expand Up @@ -2088,6 +2091,57 @@ static bool IsVectorElementConversion(Sema &S, QualType FromType,
return false;
}

/// Determine whether the conversion from FromType to ToType is a valid
/// matrix conversion.
///
/// \param ICK Will be set to the matrix conversion kind, if this is a matrix
/// conversion.
static bool IsMatrixConversion(Sema &S, QualType FromType, QualType ToType,
ImplicitConversionKind &ICK,
ImplicitConversionKind &ElConv, Expr *From,
bool InOverloadResolution, bool CStyle) {
// The non HLSL Matrix conversion rules are not clear.
if (!S.getLangOpts().HLSL)
return false;

auto *ToMatrixType = ToType->getAs<ConstantMatrixType>();
auto *FromMatrixType = FromType->getAs<ConstantMatrixType>();

// If both arguments are vectors, handle possible vector truncation and
// element conversion.
if (ToMatrixType && FromMatrixType) {
unsigned FromCols = FromMatrixType->getNumColumns();
unsigned ToCols = ToMatrixType->getNumColumns();
if (FromCols < ToCols)
return false;

unsigned FromRows = FromMatrixType->getNumRows();
unsigned ToRows = ToMatrixType->getNumRows();
if (FromRows < ToRows)
return false;

if (FromRows == ToRows && FromCols == ToCols)
ElConv = ICK_Identity;
else
ElConv = ICK_HLSL_Matrix_Truncation;

QualType FromElTy = FromMatrixType->getElementType();
QualType ToElTy = ToMatrixType->getElementType();
if (S.Context.hasSameUnqualifiedType(FromElTy, ToElTy))
return true;
return IsVectorOrMatrixElementConversion(S, FromElTy, ToElTy, ICK, From);
}
if (FromMatrixType && !ToMatrixType) {
ElConv = ICK_HLSL_Matrix_Truncation;
QualType FromElTy = FromMatrixType->getElementType();
if (S.Context.hasSameUnqualifiedType(FromElTy, ToType))
return true;
return IsVectorOrMatrixElementConversion(S, FromElTy, ToType, ICK, From);
}

return false;
}

/// Determine whether the conversion from FromType to ToType is a valid
/// vector conversion.
///
Expand Down Expand Up @@ -2127,14 +2181,14 @@ static bool IsVectorConversion(Sema &S, QualType FromType, QualType ToType,
QualType ToElTy = ToExtType->getElementType();
if (S.Context.hasSameUnqualifiedType(FromElTy, ToElTy))
return true;
return IsVectorElementConversion(S, FromElTy, ToElTy, ICK, From);
return IsVectorOrMatrixElementConversion(S, FromElTy, ToElTy, ICK, From);
}
if (FromExtType && !ToExtType) {
ElConv = ICK_HLSL_Vector_Truncation;
QualType FromElTy = FromExtType->getElementType();
if (S.Context.hasSameUnqualifiedType(FromElTy, ToType))
return true;
return IsVectorElementConversion(S, FromElTy, ToType, ICK, From);
return IsVectorOrMatrixElementConversion(S, FromElTy, ToType, ICK, From);
}
// Fallthrough for the case where ToType is a vector and FromType is not.
}
Expand All @@ -2161,7 +2215,8 @@ static bool IsVectorConversion(Sema &S, QualType FromType, QualType ToType,
if (S.getLangOpts().HLSL) {
ElConv = ICK_HLSL_Vector_Splat;
QualType ToElTy = ToExtType->getElementType();
return IsVectorElementConversion(S, FromType, ToElTy, ICK, From);
return IsVectorOrMatrixElementConversion(S, FromType, ToElTy, ICK,
From);
}
ICK = ICK_Vector_Splat;
return true;
Expand Down Expand Up @@ -2460,6 +2515,11 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType,
SCS.Second = SecondICK;
SCS.Dimension = DimensionICK;
FromType = ToType.getUnqualifiedType();
} else if (IsMatrixConversion(S, FromType, ToType, SecondICK, DimensionICK,
From, InOverloadResolution, CStyle)) {
SCS.Second = SecondICK;
SCS.Dimension = DimensionICK;
FromType = ToType.getUnqualifiedType();
} else if (!S.getLangOpts().CPlusPlus &&
S.Context.typesAreCompatible(ToType, FromType)) {
// Compatible conversions (Clang extension for C function overloading)
Expand Down Expand Up @@ -6237,6 +6297,7 @@ static bool CheckConvertedConstantConversions(Sema &S,
case ICK_Incompatible_Pointer_Conversion:
case ICK_Fixed_Point_Conversion:
case ICK_HLSL_Vector_Truncation:
case ICK_HLSL_Matrix_Truncation:
return false;

case ICK_Lvalue_To_Rvalue:
Expand Down
Loading