-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[HLSL] Vector standard conversions #71098
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
Changes from all commits
91e8d9d
06c7a72
6cbf74c
899d529
86c0dc0
ac9711e
f86c51f
b958512
f2c4024
2b90d41
c5430b3
20a095e
003bd4b
f1c13db
34ad305
fdd6a97
ef34f7e
9982104
b2b0655
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2408,6 +2408,12 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) { | |
CE->getExprLoc()); | ||
|
||
case CK_IntegralCast: { | ||
if (E->getType()->isExtVectorType() && DestTy->isExtVectorType()) { | ||
QualType SrcElTy = E->getType()->castAs<VectorType>()->getElementType(); | ||
return Builder.CreateIntCast(Visit(E), ConvertType(DestTy), | ||
SrcElTy->isSignedIntegerOrEnumerationType(), | ||
"conv"); | ||
} | ||
ScalarConversionOpts Opts; | ||
if (auto *ICE = dyn_cast<ImplicitCastExpr>(CE)) { | ||
if (!ICE->isPartOfExplicitCast()) | ||
|
@@ -2416,9 +2422,50 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) { | |
return EmitScalarConversion(Visit(E), E->getType(), DestTy, | ||
CE->getExprLoc(), Opts); | ||
} | ||
case CK_IntegralToFloating: | ||
case CK_FloatingToIntegral: | ||
case CK_FloatingCast: | ||
case CK_IntegralToFloating: { | ||
if (E->getType()->isVectorType() && DestTy->isVectorType()) { | ||
// TODO: Support constrained FP intrinsics. | ||
assert(!Builder.getIsFPConstrained() && | ||
"FP Constrained vector casts not supported yet."); | ||
QualType SrcElTy = E->getType()->castAs<VectorType>()->getElementType(); | ||
if (SrcElTy->isSignedIntegerOrEnumerationType()) | ||
return Builder.CreateSIToFP(Visit(E), ConvertType(DestTy), "conv"); | ||
return Builder.CreateUIToFP(Visit(E), ConvertType(DestTy), "conv"); | ||
} | ||
CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE); | ||
return EmitScalarConversion(Visit(E), E->getType(), DestTy, | ||
CE->getExprLoc()); | ||
} | ||
case CK_FloatingToIntegral: { | ||
if (E->getType()->isVectorType() && DestTy->isVectorType()) { | ||
// TODO: Support constrained FP intrinsics. | ||
assert(!Builder.getIsFPConstrained() && | ||
"FP Constrained vector casts not supported yet."); | ||
QualType DstElTy = DestTy->castAs<VectorType>()->getElementType(); | ||
if (DstElTy->isSignedIntegerOrEnumerationType()) | ||
return Builder.CreateFPToSI(Visit(E), ConvertType(DestTy), "conv"); | ||
return Builder.CreateFPToUI(Visit(E), ConvertType(DestTy), "conv"); | ||
} | ||
CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE); | ||
return EmitScalarConversion(Visit(E), E->getType(), DestTy, | ||
CE->getExprLoc()); | ||
} | ||
case CK_FloatingCast: { | ||
if (E->getType()->isVectorType() && DestTy->isVectorType()) { | ||
// TODO: Support constrained FP intrinsics. | ||
assert(!Builder.getIsFPConstrained() && | ||
"FP Constrained vector casts not supported yet."); | ||
QualType SrcElTy = E->getType()->castAs<VectorType>()->getElementType(); | ||
QualType DstElTy = DestTy->castAs<VectorType>()->getElementType(); | ||
if (DstElTy->castAs<BuiltinType>()->getKind() < | ||
SrcElTy->castAs<BuiltinType>()->getKind()) | ||
return Builder.CreateFPTrunc(Visit(E), ConvertType(DestTy), "conv"); | ||
return Builder.CreateFPExt(Visit(E), ConvertType(DestTy), "conv"); | ||
} | ||
CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE); | ||
return EmitScalarConversion(Visit(E), E->getType(), DestTy, | ||
CE->getExprLoc()); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Interesting. I guess we would've had a miscompile here except that Sema currently never emits these cast kinds for vector types? Given that, I feel like this code shouldn't check for I guess HLSL probably doesn't care about any of the contextual things from the FP options. Do the constrained FP intrinsics even support vectors? Please at least leave a TODO about handling these properly. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will do. HLSL doesn't support constrained FP intrinsics (yet), but may eventually. |
||
case CK_FixedPointToFloating: | ||
case CK_FloatingToFixedPoint: { | ||
CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE); | ||
|
@@ -2468,6 +2515,17 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) { | |
case CK_IntToOCLSampler: | ||
return CGF.CGM.createOpenCLIntToSamplerConversion(E, CGF); | ||
|
||
case CK_HLSLVectorTruncation: { | ||
assert(DestTy->isVectorType() && "Expected dest type to be vector type"); | ||
Value *Vec = Visit(const_cast<Expr *>(E)); | ||
SmallVector<int, 16> Mask; | ||
unsigned NumElts = DestTy->castAs<VectorType>()->getNumElements(); | ||
for (unsigned I = 0; I != NumElts; ++I) | ||
Mask.push_back(I); | ||
|
||
return Builder.CreateShuffleVector(Vec, Mask, "trunc"); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay, please tell me this is wrong. The result of truncating There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Doh! |
||
|
||
} // end of switch | ||
|
||
llvm_unreachable("unknown scalar cast"); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6432,7 +6432,7 @@ void InitializationSequence::InitializeFrom(Sema &S, | |
// For HLSL ext vector types we allow list initialization behavior for C++ | ||
// constructor syntax. This is accomplished by converting initialization | ||
// arguments an InitListExpr late. | ||
if (S.getLangOpts().HLSL && DestType->isExtVectorType() && | ||
if (S.getLangOpts().HLSL && Args.size() > 1 && DestType->isExtVectorType() && | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This sort of looks like a separate bug fix. In any case I don't see a test for it (though maybe I missed it) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is subtle but there are tests that cover this. The tests introduced here cover the void Fn(double2 D);
void Call(float2 F) {
Fn(F);
} In the call to In other cases that we cover in the vector-constructors.hlsl test, we initialize vectors with initializer lists that are more than one argument like: float2 f = float2(1, 2); |
||
(SourceType.isNull() || | ||
!Context.hasSameUnqualifiedType(SourceType, DestType))) { | ||
|
||
|
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.
Unfortunately, we already use "truncate" a lot to talk about narrowing integer conversions. Ideally, the term here wouldn't be confusable with that; I don't have a great alternative to suggest, though. Even if we can't find a better name, though, please briefly describe the conversion here, since it's not obvious from context.
As an aside: uh, wow, that sure seems like an unfortunate conversion to have in the language. I guess it's not that bad for something like dropping the last element from a 4-vector, where often it's really a 3-vector in disguise. Still, oof, what a footgun.
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.
Yea... HLSL has a lot of unfortunate implicit language behaviors. Part of our goal with the Clang implementation is to capture those behaviors in a way we can diagnose them more accurately, and slowly tighten up the language as we evolve it.
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.
Okay. I think this patch overall looks fine to land, except please do expand on the comment here to explain what truncating a vector type means (dropping elements from the end).