@@ -4294,6 +4294,21 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
4294
4294
return From;
4295
4295
}
4296
4296
4297
+ // GetIntermediateVectorType - Compute the intermediate cast type casting
4298
+ // elements of the from type to the elements of the to type without resizing the
4299
+ // vector.
4300
+ static QualType adjustVectorType(ASTContext &Context, QualType FromTy,
4301
+ QualType ToType, QualType *ElTy = nullptr) {
4302
+ auto *ToVec = ToType->castAs<VectorType>();
4303
+ QualType ElType = ToVec->getElementType();
4304
+ if (ElTy)
4305
+ *ElTy = ElType;
4306
+ if (!FromTy->isVectorType())
4307
+ return ElType;
4308
+ auto *FromVec = FromTy->castAs<VectorType>();
4309
+ return Context.getExtVectorType(ElType, FromVec->getNumElements());
4310
+ }
4311
+
4297
4312
ExprResult
4298
4313
Sema::PerformImplicitConversion(Expr *From, QualType ToType,
4299
4314
const StandardConversionSequence& SCS,
@@ -4443,27 +4458,36 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
4443
4458
break;
4444
4459
4445
4460
case ICK_Integral_Promotion:
4446
- case ICK_Integral_Conversion:
4447
- if (ToType->isBooleanType()) {
4461
+ case ICK_Integral_Conversion: {
4462
+ QualType ElTy = ToType;
4463
+ QualType StepTy = ToType;
4464
+ if (ToType->isVectorType())
4465
+ StepTy = adjustVectorType(Context, FromType, ToType, &ElTy);
4466
+ if (ElTy->isBooleanType()) {
4448
4467
assert(FromType->castAs<EnumType>()->getDecl()->isFixed() &&
4449
4468
SCS.Second == ICK_Integral_Promotion &&
4450
4469
"only enums with fixed underlying type can promote to bool");
4451
- From = ImpCastExprToType(From, ToType , CK_IntegralToBoolean, VK_PRValue,
4470
+ From = ImpCastExprToType(From, StepTy , CK_IntegralToBoolean, VK_PRValue,
4452
4471
/*BasePath=*/nullptr, CCK)
4453
4472
.get();
4454
4473
} else {
4455
- From = ImpCastExprToType(From, ToType , CK_IntegralCast, VK_PRValue,
4474
+ From = ImpCastExprToType(From, StepTy , CK_IntegralCast, VK_PRValue,
4456
4475
/*BasePath=*/nullptr, CCK)
4457
4476
.get();
4458
4477
}
4459
4478
break;
4479
+ }
4460
4480
4461
4481
case ICK_Floating_Promotion:
4462
- case ICK_Floating_Conversion:
4463
- From = ImpCastExprToType(From, ToType, CK_FloatingCast, VK_PRValue,
4482
+ case ICK_Floating_Conversion: {
4483
+ QualType StepTy = ToType;
4484
+ if (ToType->isVectorType())
4485
+ StepTy = adjustVectorType(Context, FromType, ToType);
4486
+ From = ImpCastExprToType(From, StepTy, CK_FloatingCast, VK_PRValue,
4464
4487
/*BasePath=*/nullptr, CCK)
4465
4488
.get();
4466
4489
break;
4490
+ }
4467
4491
4468
4492
case ICK_Complex_Promotion:
4469
4493
case ICK_Complex_Conversion: {
@@ -4486,16 +4510,21 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
4486
4510
break;
4487
4511
}
4488
4512
4489
- case ICK_Floating_Integral:
4490
- if (ToType->isRealFloatingType())
4491
- From = ImpCastExprToType(From, ToType, CK_IntegralToFloating, VK_PRValue,
4513
+ case ICK_Floating_Integral: {
4514
+ QualType ElTy = ToType;
4515
+ QualType StepTy = ToType;
4516
+ if (ToType->isVectorType())
4517
+ StepTy = adjustVectorType(Context, FromType, ToType, &ElTy);
4518
+ if (ElTy->isRealFloatingType())
4519
+ From = ImpCastExprToType(From, StepTy, CK_IntegralToFloating, VK_PRValue,
4492
4520
/*BasePath=*/nullptr, CCK)
4493
4521
.get();
4494
4522
else
4495
- From = ImpCastExprToType(From, ToType , CK_FloatingToIntegral, VK_PRValue,
4523
+ From = ImpCastExprToType(From, StepTy , CK_FloatingToIntegral, VK_PRValue,
4496
4524
/*BasePath=*/nullptr, CCK)
4497
4525
.get();
4498
4526
break;
4527
+ }
4499
4528
4500
4529
case ICK_Fixed_Point_Conversion:
4501
4530
assert((FromType->isFixedPointType() || ToType->isFixedPointType()) &&
@@ -4617,18 +4646,26 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
4617
4646
break;
4618
4647
}
4619
4648
4620
- case ICK_Boolean_Conversion:
4649
+ case ICK_Boolean_Conversion: {
4621
4650
// Perform half-to-boolean conversion via float.
4622
4651
if (From->getType()->isHalfType()) {
4623
4652
From = ImpCastExprToType(From, Context.FloatTy, CK_FloatingCast).get();
4624
4653
FromType = Context.FloatTy;
4625
4654
}
4655
+ QualType ElTy = FromType;
4656
+ QualType StepTy = ToType;
4657
+ if (FromType->isVectorType()) {
4658
+ if (getLangOpts().HLSL)
4659
+ StepTy = adjustVectorType(Context, FromType, ToType);
4660
+ ElTy = FromType->castAs<VectorType>()->getElementType();
4661
+ }
4626
4662
4627
- From = ImpCastExprToType(From, Context.BoolTy ,
4628
- ScalarTypeToBooleanCastKind(FromType ), VK_PRValue,
4663
+ From = ImpCastExprToType(From, StepTy ,
4664
+ ScalarTypeToBooleanCastKind(ElTy ), VK_PRValue,
4629
4665
/*BasePath=*/nullptr, CCK)
4630
4666
.get();
4631
4667
break;
4668
+ }
4632
4669
4633
4670
case ICK_Derived_To_Base: {
4634
4671
CXXCastPath BasePath;
@@ -4754,22 +4791,6 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
4754
4791
CK_ZeroToOCLOpaqueType,
4755
4792
From->getValueKind()).get();
4756
4793
break;
4757
- case ICK_HLSL_Vector_Truncation: {
4758
- // Note: HLSL built-in vectors are ExtVectors. Since this truncates a vector
4759
- // to a smaller vector, this can only operate on arguments where the source
4760
- // and destination types are ExtVectors.
4761
- assert(From->getType()->isExtVectorType() && ToType->isExtVectorType() &&
4762
- "HLSL vector truncation should only apply to ExtVectors");
4763
- auto *FromVec = From->getType()->castAs<VectorType>();
4764
- auto *ToVec = ToType->castAs<VectorType>();
4765
- QualType ElType = FromVec->getElementType();
4766
- QualType TruncTy =
4767
- Context.getExtVectorType(ElType, ToVec->getNumElements());
4768
- From = ImpCastExprToType(From, TruncTy, CK_HLSLVectorTruncation,
4769
- From->getValueKind())
4770
- .get();
4771
- break;
4772
- }
4773
4794
4774
4795
case ICK_Lvalue_To_Rvalue:
4775
4796
case ICK_Array_To_Pointer:
@@ -4780,73 +4801,45 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
4780
4801
case ICK_C_Only_Conversion:
4781
4802
case ICK_Incompatible_Pointer_Conversion:
4782
4803
case ICK_HLSL_Array_RValue:
4804
+ case ICK_HLSL_Vector_Truncation:
4805
+ case ICK_HLSL_Vector_Splat:
4783
4806
llvm_unreachable("Improper second standard conversion");
4784
4807
}
4785
4808
4786
- if (SCS.Element != ICK_Identity) {
4809
+ if (SCS.Dimension != ICK_Identity) {
4787
4810
// If SCS.Element is not ICK_Identity the To and From types must be HLSL
4788
4811
// vectors or matrices.
4789
4812
4790
4813
// TODO: Support HLSL matrices.
4791
4814
assert((!From->getType()->isMatrixType() && !ToType->isMatrixType()) &&
4792
- "Element conversion for matrix types is not implemented yet.");
4793
- assert(From->getType()->isVectorType() && ToType->isVectorType() &&
4794
- "Element conversion is only supported for vector types.");
4795
- assert(From->getType()->getAs<VectorType>()->getNumElements() ==
4796
- ToType->getAs<VectorType>()->getNumElements() &&
4797
- "Element conversion is only supported for vectors with the same "
4798
- "element counts.");
4799
- QualType FromElTy = From->getType()->getAs<VectorType>()->getElementType();
4800
- unsigned NumElts = ToType->getAs<VectorType>()->getNumElements();
4801
- switch (SCS.Element) {
4802
- case ICK_Boolean_Conversion:
4803
- // Perform half-to-boolean conversion via float.
4804
- if (FromElTy->isHalfType()) {
4805
- QualType FPExtType = Context.getExtVectorType(FromElTy, NumElts);
4806
- From = ImpCastExprToType(From, FPExtType, CK_FloatingCast).get();
4807
- FromType = FPExtType;
4808
- }
4809
-
4810
- From =
4811
- ImpCastExprToType(From, ToType, ScalarTypeToBooleanCastKind(FromElTy),
4812
- VK_PRValue,
4813
- /*BasePath=*/nullptr, CCK)
4814
- .get();
4815
- break;
4816
- case ICK_Integral_Promotion:
4817
- case ICK_Integral_Conversion:
4818
- if (ToType->isBooleanType()) {
4819
- assert(FromType->castAs<EnumType>()->getDecl()->isFixed() &&
4820
- SCS.Second == ICK_Integral_Promotion &&
4821
- "only enums with fixed underlying type can promote to bool");
4822
- From = ImpCastExprToType(From, ToType, CK_IntegralToBoolean, VK_PRValue,
4823
- /*BasePath=*/nullptr, CCK)
4824
- .get();
4825
- } else {
4826
- From = ImpCastExprToType(From, ToType, CK_IntegralCast, VK_PRValue,
4827
- /*BasePath=*/nullptr, CCK)
4828
- .get();
4829
- }
4830
- break;
4831
-
4832
- case ICK_Floating_Promotion:
4833
- case ICK_Floating_Conversion:
4834
- From = ImpCastExprToType(From, ToType, CK_FloatingCast, VK_PRValue,
4815
+ "Dimension conversion for matrix types is not implemented yet.");
4816
+ assert(ToType->isVectorType() &&
4817
+ "Dimension conversion is only supported for vector types.");
4818
+ switch (SCS.Dimension) {
4819
+ case ICK_HLSL_Vector_Splat: {
4820
+ // Vector splat from any arithmetic type to a vector.
4821
+ Expr *Elem = prepareVectorSplat(ToType, From).get();
4822
+ From = ImpCastExprToType(Elem, ToType, CK_VectorSplat, VK_PRValue,
4835
4823
/*BasePath=*/nullptr, CCK)
4836
4824
.get();
4837
4825
break;
4838
- case ICK_Floating_Integral:
4839
- if (ToType->hasFloatingRepresentation())
4840
- From =
4841
- ImpCastExprToType(From, ToType, CK_IntegralToFloating, VK_PRValue,
4842
- /*BasePath=*/nullptr, CCK)
4843
- .get();
4844
- else
4845
- From =
4846
- ImpCastExprToType(From, ToType, CK_FloatingToIntegral, VK_PRValue,
4847
- /*BasePath=*/nullptr, CCK)
4848
- .get();
4826
+ }
4827
+ case ICK_HLSL_Vector_Truncation: {
4828
+ // Note: HLSL built-in vectors are ExtVectors. Since this truncates a
4829
+ // vector to a smaller vector, this can only operate on arguments where
4830
+ // the source and destination types are ExtVectors.
4831
+ assert(From->getType()->isExtVectorType() && ToType->isExtVectorType() &&
4832
+ "HLSL vector truncation should only apply to ExtVectors");
4833
+ auto *FromVec = From->getType()->castAs<VectorType>();
4834
+ auto *ToVec = ToType->castAs<VectorType>();
4835
+ QualType ElType = FromVec->getElementType();
4836
+ QualType TruncTy =
4837
+ Context.getExtVectorType(ElType, ToVec->getNumElements());
4838
+ From = ImpCastExprToType(From, TruncTy, CK_HLSLVectorTruncation,
4839
+ From->getValueKind())
4840
+ .get();
4849
4841
break;
4842
+ }
4850
4843
case ICK_Identity:
4851
4844
default:
4852
4845
llvm_unreachable("Improper element standard conversion");
0 commit comments