https://github.com/llvm-beanz updated https://github.com/llvm/llvm-project/pull/195173
>From 5c806c3eade44b4ba5bd0758b0e9dc8a28ce8ece Mon Sep 17 00:00:00 2001 From: Chris Bieneman <[email protected]> Date: Thu, 30 Apr 2026 15:16:54 -0500 Subject: [PATCH 1/6] [HLSL] `constexpr` vector element conversions This PR updates the constant expression evaluators to support HLSL's element-wise vector element conversions. These conversions allow element-by-element conversion of a vector from one type to another vector of the same dimension. Fixes #163437 ../clang/test/SemaHLSL/Types/BuiltinVector/VectorCastConstantExpr.hlsl ../clang/test/SemaHLSL/Types/BuiltinVector/VectorCastConstantExpr.hlsl --- clang/lib/AST/ByteCode/Compiler.cpp | 56 ++++++++++++++++ clang/lib/AST/ByteCode/Compiler.h | 1 + clang/lib/AST/ExprConstant.cpp | 25 ++++++++ .../BuiltinVector/VectorCastConstantExpr.hlsl | 64 +++++++++++++++++++ 4 files changed, 146 insertions(+) create mode 100644 clang/test/SemaHLSL/Types/BuiltinVector/VectorCastConstantExpr.hlsl diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index 626068ce9eee5..6f0fdcc31ce2c 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -376,6 +376,8 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *E) { case CK_FloatingCast: { // HLSL uses CK_FloatingCast to cast between vectors. + if (E->getType()->isVectorType()) + return this->emitVectorElementwiseCast(E); if (!SubExpr->getType()->isFloatingType() || !E->getType()->isFloatingType()) return false; @@ -386,6 +388,8 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *E) { } case CK_IntegralToFloating: { + if (E->getType()->isVectorType()) + return this->emitVectorElementwiseCast(E); if (!E->getType()->isRealFloatingType()) return false; if (!this->visit(SubExpr)) @@ -396,6 +400,8 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *E) { } case CK_FloatingToBoolean: { + if (E->getType()->isVectorType()) + return this->emitVectorElementwiseCast(E); if (!SubExpr->getType()->isRealFloatingType() || !E->getType()->isBooleanType()) return false; @@ -407,6 +413,8 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *E) { } case CK_FloatingToIntegral: { + if (E->getType()->isVectorType()) + return this->emitVectorElementwiseCast(E); if (!E->getType()->isIntegralOrEnumerationType()) return false; if (!this->visit(SubExpr)) @@ -554,6 +562,8 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *E) { } case CK_IntegralToBoolean: case CK_FixedPointToBoolean: { + if (E->getType()->isVectorType()) + return this->emitVectorElementwiseCast(E); // HLSL uses this to cast to one-element vectors. OptPrimType FromT = classify(SubExpr->getType()); if (!FromT) @@ -568,6 +578,8 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *E) { case CK_BooleanToSignedIntegral: case CK_IntegralCast: { + if (E->getCastKind() == CK_IntegralCast && E->getType()->isVectorType()) + return this->emitVectorElementwiseCast(E); OptPrimType FromT = classify(SubExpr->getType()); OptPrimType ToT = classify(E->getType()); if (!FromT || !ToT) @@ -8111,6 +8123,50 @@ bool Compiler<Emitter>::emitBuiltinBitCast(const CastExpr *E) { return true; } +/// Cast each element of a source vector to the corresponding element type of a +/// destination vector using a scalar primitive cast. A pointer to the +/// destination must be on top of the interpreter stack when \p Initializing is +/// true; otherwise a new local is allocated for the result. +template <class Emitter> +bool Compiler<Emitter>::emitVectorElementwiseCast(const CastExpr *E) { + const Expr *SubExpr = E->getSubExpr(); + assert(SubExpr->getType()->isVectorType() && "expected vector source type"); + assert(E->getType()->isVectorType() && "expected vector destination type"); + + const auto *DstVTy = E->getType()->getAs<VectorType>(); + unsigned NumElts = DstVTy->getNumElements(); + PrimType SrcElemT = classifyVectorElementType(SubExpr->getType()); + PrimType DstElemT = classifyVectorElementType(E->getType()); + QualType DstElemType = DstVTy->getElementType(); + + if (!Initializing) { + UnsignedOrNone LocalIndex = allocateLocal(E); + if (!LocalIndex) + return false; + if (!this->emitGetPtrLocal(*LocalIndex, E)) + return false; + } + + unsigned SrcOffset = + allocateLocalPrimitive(SubExpr, PT_Ptr, /*IsConst=*/true); + if (!this->visit(SubExpr)) + return false; + if (!this->emitSetLocal(PT_Ptr, SrcOffset, E)) + return false; + + for (unsigned I = 0; I < NumElts; ++I) { + if (!this->emitGetLocal(PT_Ptr, SrcOffset, E)) + return false; + if (!this->emitArrayElemPop(SrcElemT, I, E)) + return false; + if (!this->emitPrimCast(SrcElemT, DstElemT, DstElemType, E)) + return false; + if (!this->emitInitElem(DstElemT, I, E)) + return false; + } + return true; +} + /// Replicate a scalar value into every scalar element of an aggregate. /// The scalar is stored in a local at \p SrcOffset and a pointer to the /// destination must be on top of the interpreter stack. Each element receives diff --git a/clang/lib/AST/ByteCode/Compiler.h b/clang/lib/AST/ByteCode/Compiler.h index de6ea524897a0..3626fd62f7f1f 100644 --- a/clang/lib/AST/ByteCode/Compiler.h +++ b/clang/lib/AST/ByteCode/Compiler.h @@ -415,6 +415,7 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>, bool emitComplexBoolCast(const Expr *E); bool emitComplexComparison(const Expr *LHS, const Expr *RHS, const BinaryOperator *E); + bool emitVectorElementwiseCast(const CastExpr *E); bool emitRecordDestructionPop(const Record *R, SourceInfo Loc); bool emitDestructionPop(const Descriptor *Desc, SourceInfo Loc); bool emitDummyPtr(const DeclTy &D, const Expr *E); diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 1a4c962801077..f92e04666413a 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -11772,6 +11772,31 @@ bool VectorExprEvaluator::VisitCastExpr(const CastExpr *E) { return false; return Success(ResultEls, E); } + case CK_IntegralToFloating: + case CK_FloatingToIntegral: + case CK_IntegralCast: + case CK_FloatingCast: + case CK_FloatingToBoolean: + case CK_IntegralToBoolean: { + // These casts apply element-wise when the source is a vector type. + assert(SETy->isVectorType() && "expected vector source type"); + APValue SrcVal; + if (!EvaluateVector(SE, SrcVal, Info)) + return Error(E); + + assert(SrcVal.getVectorLength() == NElts); + QualType SrcEltTy = SETy->castAs<VectorType>()->getElementType(); + QualType DstEltTy = VTy->getElementType(); + const FPOptions FPO = E->getFPFeaturesInEffect(Info.Ctx.getLangOpts()); + + SmallVector<APValue, 4> ResultEls(NElts); + for (unsigned I = 0; I < NElts; ++I) { + if (!handleScalarCast(Info, FPO, E, SrcEltTy, DstEltTy, + SrcVal.getVectorElt(I), ResultEls[I])) + return false; + } + return Success(ResultEls, E); + } default: return ExprEvaluatorBaseTy::VisitCastExpr(E); } diff --git a/clang/test/SemaHLSL/Types/BuiltinVector/VectorCastConstantExpr.hlsl b/clang/test/SemaHLSL/Types/BuiltinVector/VectorCastConstantExpr.hlsl new file mode 100644 index 0000000000000..a2fee7f80ec08 --- /dev/null +++ b/clang/test/SemaHLSL/Types/BuiltinVector/VectorCastConstantExpr.hlsl @@ -0,0 +1,64 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.6-library -finclude-default-header -std=hlsl202x -verify %s +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.6-library -finclude-default-header -std=hlsl202x -fexperimental-new-constant-interpreter -verify %s + +// expected-no-diagnostics + +// Tests for constexpr evaluation of element-wise vector casts. + +export void fn() { + // CK_IntegralToFloating: int4 -> float4 + constexpr float4 ItF = (float4)int4(1, 2, 3, 4); + _Static_assert(ItF.x == 1.0f, ""); + _Static_assert(ItF.y == 2.0f, ""); + _Static_assert(ItF.z == 3.0f, ""); + _Static_assert(ItF.w == 4.0f, ""); + + // CK_FloatingToIntegral: float4 -> int4 (truncation toward zero) + constexpr int4 FtI = (int4)float4(1.9f, 2.1f, -3.9f, -4.1f); + _Static_assert(FtI.x == 1, ""); + _Static_assert(FtI.y == 2, ""); + _Static_assert(FtI.z == -3, ""); + _Static_assert(FtI.w == -4, ""); + + // CK_IntegralCast: int4 -> uint4 + constexpr uint4 IC = (uint4)int4(1, 2, 3, 4); + _Static_assert(IC.x == 1u, ""); + _Static_assert(IC.y == 2u, ""); + _Static_assert(IC.z == 3u, ""); + _Static_assert(IC.w == 4u, ""); + + // CK_FloatingCast: float4 -> double4 + constexpr double4 FC = (double4)float4(1.0f, 2.0f, 3.0f, 4.0f); + _Static_assert(FC.x == 1.0, ""); + _Static_assert(FC.y == 2.0, ""); + _Static_assert(FC.z == 3.0, ""); + _Static_assert(FC.w == 4.0, ""); + + // CK_IntegralToBoolean: int4 -> bool4 + constexpr bool4 ItB = (bool4)int4(1, 0, -1, 2); + _Static_assert(ItB.x == true, ""); + _Static_assert(ItB.y == false, ""); + _Static_assert(ItB.z == true, ""); + _Static_assert(ItB.w == true, ""); + + // CK_FloatingToBoolean: float4 -> bool4 + constexpr bool4 FtB = (bool4)float4(1.0f, 0.0f, -1.0f, 2.0f); + _Static_assert(FtB.x == true, ""); + _Static_assert(FtB.y == false, ""); + _Static_assert(FtB.z == true, ""); + _Static_assert(FtB.w == true, ""); + + // Bool source: CK_IntegralToFloating with bool4 -> float4 + constexpr float4 BtF = (float4)bool4(true, false, true, false); + _Static_assert(BtF.x == 1.0f, ""); + _Static_assert(BtF.y == 0.0f, ""); + _Static_assert(BtF.z == 1.0f, ""); + _Static_assert(BtF.w == 0.0f, ""); + + // Bool source: CK_IntegralCast with bool4 -> int4 + constexpr int4 BtI = (int4)bool4(true, false, true, false); + _Static_assert(BtI.x == 1, ""); + _Static_assert(BtI.y == 0, ""); + _Static_assert(BtI.z == 1, ""); + _Static_assert(BtI.w == 0, ""); +} >From f4188ab66fa3f3c5d87547d3122db957e2acc223 Mon Sep 17 00:00:00 2001 From: Chris Bieneman <[email protected]> Date: Mon, 11 May 2026 10:54:37 -0500 Subject: [PATCH 2/6] Updates based on PR feedback --- clang/lib/AST/ByteCode/Compiler.cpp | 43 ++++++------------- clang/lib/AST/ByteCode/Compiler.h | 1 + .../Language/ConstexprVectorCasts.hlsl | 24 +++++++++++ 3 files changed, 37 insertions(+), 31 deletions(-) create mode 100644 clang/test/SemaHLSL/Language/ConstexprVectorCasts.hlsl diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index 6f0fdcc31ce2c..e0410ceeeb97c 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -576,10 +576,11 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *E) { return this->emitCast(*FromT, classifyPrim(E), E); } - case CK_BooleanToSignedIntegral: - case CK_IntegralCast: { - if (E->getCastKind() == CK_IntegralCast && E->getType()->isVectorType()) + case CK_IntegralCast: + if (E->getType()->isVectorType()) return this->emitVectorElementwiseCast(E); + [[fallthrough]]; + case CK_BooleanToSignedIntegral: { OptPrimType FromT = classify(SubExpr->getType()); OptPrimType ToT = classify(E->getType()); if (!FromT || !ToT) @@ -4358,12 +4359,10 @@ bool Compiler<Emitter>::VisitAddrLabelExpr(const AddrLabelExpr *E) { } template <class Emitter> -bool Compiler<Emitter>::VisitConvertVectorExpr(const ConvertVectorExpr *E) { - assert(Initializing); +bool Compiler<Emitter>::emitVectorConversion(const Expr *Src, const Expr *E) { const auto *VT = E->getType()->castAs<VectorType>(); QualType ElemType = VT->getElementType(); PrimType ElemT = classifyPrim(ElemType); - const Expr *Src = E->getSrcExpr(); QualType SrcType = Src->getType(); PrimType SrcElemT = classifyVectorElementType(SrcType); @@ -4392,10 +4391,15 @@ bool Compiler<Emitter>::VisitConvertVectorExpr(const ConvertVectorExpr *E) { if (!this->emitInitElem(ElemT, I, E)) return false; } - return true; } +template <class Emitter> +bool Compiler<Emitter>::VisitConvertVectorExpr(const ConvertVectorExpr *E) { + assert(Initializing); + return emitVectorConversion(E->getSrcExpr(), E); +} + template <class Emitter> bool Compiler<Emitter>::VisitShuffleVectorExpr(const ShuffleVectorExpr *E) { // FIXME: Unary shuffle with mask not currently supported. @@ -8133,12 +8137,6 @@ bool Compiler<Emitter>::emitVectorElementwiseCast(const CastExpr *E) { assert(SubExpr->getType()->isVectorType() && "expected vector source type"); assert(E->getType()->isVectorType() && "expected vector destination type"); - const auto *DstVTy = E->getType()->getAs<VectorType>(); - unsigned NumElts = DstVTy->getNumElements(); - PrimType SrcElemT = classifyVectorElementType(SubExpr->getType()); - PrimType DstElemT = classifyVectorElementType(E->getType()); - QualType DstElemType = DstVTy->getElementType(); - if (!Initializing) { UnsignedOrNone LocalIndex = allocateLocal(E); if (!LocalIndex) @@ -8147,24 +8145,7 @@ bool Compiler<Emitter>::emitVectorElementwiseCast(const CastExpr *E) { return false; } - unsigned SrcOffset = - allocateLocalPrimitive(SubExpr, PT_Ptr, /*IsConst=*/true); - if (!this->visit(SubExpr)) - return false; - if (!this->emitSetLocal(PT_Ptr, SrcOffset, E)) - return false; - - for (unsigned I = 0; I < NumElts; ++I) { - if (!this->emitGetLocal(PT_Ptr, SrcOffset, E)) - return false; - if (!this->emitArrayElemPop(SrcElemT, I, E)) - return false; - if (!this->emitPrimCast(SrcElemT, DstElemT, DstElemType, E)) - return false; - if (!this->emitInitElem(DstElemT, I, E)) - return false; - } - return true; + return emitVectorConversion(SubExpr, E); } /// Replicate a scalar value into every scalar element of an aggregate. diff --git a/clang/lib/AST/ByteCode/Compiler.h b/clang/lib/AST/ByteCode/Compiler.h index 3626fd62f7f1f..257e2716ce7d0 100644 --- a/clang/lib/AST/ByteCode/Compiler.h +++ b/clang/lib/AST/ByteCode/Compiler.h @@ -427,6 +427,7 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>, bool emitHLSLAggregateSplat(PrimType SrcT, unsigned SrcOffset, QualType DestType, const Expr *E); + bool emitVectorConversion(const Expr *Src, const Expr *E); /// A scalar element extracted during HLSL aggregate flattening. struct HLSLFlatElement { diff --git a/clang/test/SemaHLSL/Language/ConstexprVectorCasts.hlsl b/clang/test/SemaHLSL/Language/ConstexprVectorCasts.hlsl new file mode 100644 index 0000000000000..e69a714bdbfad --- /dev/null +++ b/clang/test/SemaHLSL/Language/ConstexprVectorCasts.hlsl @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-compute -finclude-default-header -fnative-int16-type -fnative-half-type -fexperimental-new-constant-interpreter -verify=expected,both %s +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-compute -finclude-default-header -fnative-int16-type -fnative-half-type -verify=ref,both %s + +const float3 F; + +struct S { + float V; +}; + +[numthreads(1,1,1)] +void main () { + S Vals[] = {1,2,3}; // expected-note {{declared here}} + constexpr int3 I = false ? (float3)Vals : Vals[0].V.xxx; // #conversions + // both-warning@#conversions {{implicit conversion turns floating-point number into integer: 'float3' (aka 'vector<float, 3>') to 'vector<int, 3>' (vector of 3 'int' values)}} + // both-warning@#conversions {{implicit conversion turns floating-point number into integer: 'vector<float, 3>' (vector of 3 'float' values) to 'vector<int, 3>' (vector of 3 'int' values)}} + // both-error@#conversions {{constexpr variable 'I' must be initialized by a constant expression}} + // expected-note@#conversions {{read of non-constexpr variable 'Vals' is not allowed in a constant expression}} + + constexpr float2 F2 = {4800000, -4800000}; + constexpr vector<int16_t,2> I16 = F2; // #range + // both-warning@#range {{implicit conversion turns floating-point number into integer: 'const float2' (aka 'const vector<float, 2>') to 'vector<int16_t, 2>' (vector of 2 'int16_t' values)}} + // both-error@#range {{constexpr variable 'I16' must be initialized by a constant expression}} + // both-note@#range {{value 4.8E+6 is outside the range of representable values of type 'int16_t' (aka 'short')}} +} >From 33aeafc5bc8bde3b96207dea592f83cd66fea7bb Mon Sep 17 00:00:00 2001 From: Chris Bieneman <[email protected]> Date: Mon, 11 May 2026 11:11:41 -0500 Subject: [PATCH 3/6] Oops. Forgot to save before pushing. ../clang/test/SemaHLSL/Language/ConstexprVectorCasts.hlsl --- clang/test/SemaHLSL/Language/ConstexprVectorCasts.hlsl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang/test/SemaHLSL/Language/ConstexprVectorCasts.hlsl b/clang/test/SemaHLSL/Language/ConstexprVectorCasts.hlsl index e69a714bdbfad..fbacb44931c99 100644 --- a/clang/test/SemaHLSL/Language/ConstexprVectorCasts.hlsl +++ b/clang/test/SemaHLSL/Language/ConstexprVectorCasts.hlsl @@ -20,5 +20,6 @@ void main () { constexpr vector<int16_t,2> I16 = F2; // #range // both-warning@#range {{implicit conversion turns floating-point number into integer: 'const float2' (aka 'const vector<float, 2>') to 'vector<int16_t, 2>' (vector of 2 'int16_t' values)}} // both-error@#range {{constexpr variable 'I16' must be initialized by a constant expression}} - // both-note@#range {{value 4.8E+6 is outside the range of representable values of type 'int16_t' (aka 'short')}} + // ref-note@#range {{value 4.8E+6 is outside the range of representable values of type 'int16_t' (aka 'short')}} + // expected-note@#range {{value 4.8E+6 is outside the range of representable values of type 'vector<int16_t, 2>' (vector of 2 'int16_t' values)}} } >From 06e65b507d81a7fff6e679c29a7e932146a6f952 Mon Sep 17 00:00:00 2001 From: Chris Bieneman <[email protected]> Date: Mon, 11 May 2026 13:08:37 -0500 Subject: [PATCH 4/6] Forgot to include this file in my last push --- clang/lib/AST/ExprConstant.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index f92e04666413a..3a7a67838879f 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -11793,7 +11793,7 @@ bool VectorExprEvaluator::VisitCastExpr(const CastExpr *E) { for (unsigned I = 0; I < NElts; ++I) { if (!handleScalarCast(Info, FPO, E, SrcEltTy, DstEltTy, SrcVal.getVectorElt(I), ResultEls[I])) - return false; + return Error(E); } return Success(ResultEls, E); } >From 3be9052e258e48beaf70833a41b454d45fefa45d Mon Sep 17 00:00:00 2001 From: Chris Bieneman <[email protected]> Date: Wed, 13 May 2026 18:38:38 -0500 Subject: [PATCH 5/6] Cleanup based on PR feedback --- clang/lib/AST/ByteCode/Compiler.cpp | 42 ++++++++++------------------- 1 file changed, 14 insertions(+), 28 deletions(-) diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index e0410ceeeb97c..343b569346807 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -377,7 +377,7 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *E) { case CK_FloatingCast: { // HLSL uses CK_FloatingCast to cast between vectors. if (E->getType()->isVectorType()) - return this->emitVectorElementwiseCast(E); + return this->emitVectorConversion(E->getSubExpr(), E); if (!SubExpr->getType()->isFloatingType() || !E->getType()->isFloatingType()) return false; @@ -389,7 +389,7 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *E) { case CK_IntegralToFloating: { if (E->getType()->isVectorType()) - return this->emitVectorElementwiseCast(E); + return this->emitVectorConversion(E->getSubExpr(), E); if (!E->getType()->isRealFloatingType()) return false; if (!this->visit(SubExpr)) @@ -401,7 +401,7 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *E) { case CK_FloatingToBoolean: { if (E->getType()->isVectorType()) - return this->emitVectorElementwiseCast(E); + return this->emitVectorConversion(E->getSubExpr(), E); if (!SubExpr->getType()->isRealFloatingType() || !E->getType()->isBooleanType()) return false; @@ -414,7 +414,7 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *E) { case CK_FloatingToIntegral: { if (E->getType()->isVectorType()) - return this->emitVectorElementwiseCast(E); + return this->emitVectorConversion(E->getSubExpr(), E); if (!E->getType()->isIntegralOrEnumerationType()) return false; if (!this->visit(SubExpr)) @@ -563,7 +563,7 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *E) { case CK_IntegralToBoolean: case CK_FixedPointToBoolean: { if (E->getType()->isVectorType()) - return this->emitVectorElementwiseCast(E); + return this->emitVectorConversion(E->getSubExpr(), E); // HLSL uses this to cast to one-element vectors. OptPrimType FromT = classify(SubExpr->getType()); if (!FromT) @@ -578,7 +578,7 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *E) { case CK_IntegralCast: if (E->getType()->isVectorType()) - return this->emitVectorElementwiseCast(E); + return this->emitVectorConversion(E->getSubExpr(), E); [[fallthrough]]; case CK_BooleanToSignedIntegral: { OptPrimType FromT = classify(SubExpr->getType()); @@ -4366,6 +4366,14 @@ bool Compiler<Emitter>::emitVectorConversion(const Expr *Src, const Expr *E) { QualType SrcType = Src->getType(); PrimType SrcElemT = classifyVectorElementType(SrcType); + if (!Initializing) { + UnsignedOrNone LocalIndex = allocateLocal(E); + if (!LocalIndex) + return false; + if (!this->emitGetPtrLocal(*LocalIndex, E)) + return false; + } + unsigned SrcOffset = this->allocateLocalPrimitive(Src, PT_Ptr, /*IsConst=*/true); if (!this->visit(Src)) @@ -4396,7 +4404,6 @@ bool Compiler<Emitter>::emitVectorConversion(const Expr *Src, const Expr *E) { template <class Emitter> bool Compiler<Emitter>::VisitConvertVectorExpr(const ConvertVectorExpr *E) { - assert(Initializing); return emitVectorConversion(E->getSrcExpr(), E); } @@ -8127,27 +8134,6 @@ bool Compiler<Emitter>::emitBuiltinBitCast(const CastExpr *E) { return true; } -/// Cast each element of a source vector to the corresponding element type of a -/// destination vector using a scalar primitive cast. A pointer to the -/// destination must be on top of the interpreter stack when \p Initializing is -/// true; otherwise a new local is allocated for the result. -template <class Emitter> -bool Compiler<Emitter>::emitVectorElementwiseCast(const CastExpr *E) { - const Expr *SubExpr = E->getSubExpr(); - assert(SubExpr->getType()->isVectorType() && "expected vector source type"); - assert(E->getType()->isVectorType() && "expected vector destination type"); - - if (!Initializing) { - UnsignedOrNone LocalIndex = allocateLocal(E); - if (!LocalIndex) - return false; - if (!this->emitGetPtrLocal(*LocalIndex, E)) - return false; - } - - return emitVectorConversion(SubExpr, E); -} - /// Replicate a scalar value into every scalar element of an aggregate. /// The scalar is stored in a local at \p SrcOffset and a pointer to the /// destination must be on top of the interpreter stack. Each element receives >From 785b72e97a6072d13d5c2159bf27b36f22eeca35 Mon Sep 17 00:00:00 2001 From: Chris B <[email protected]> Date: Wed, 27 May 2026 17:52:35 -0500 Subject: [PATCH 6/6] Update clang/lib/AST/ByteCode/Compiler.h Co-authored-by: Deric C. <[email protected]> --- clang/lib/AST/ByteCode/Compiler.h | 1 - 1 file changed, 1 deletion(-) diff --git a/clang/lib/AST/ByteCode/Compiler.h b/clang/lib/AST/ByteCode/Compiler.h index 257e2716ce7d0..ce5548f557152 100644 --- a/clang/lib/AST/ByteCode/Compiler.h +++ b/clang/lib/AST/ByteCode/Compiler.h @@ -415,7 +415,6 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>, bool emitComplexBoolCast(const Expr *E); bool emitComplexComparison(const Expr *LHS, const Expr *RHS, const BinaryOperator *E); - bool emitVectorElementwiseCast(const CastExpr *E); bool emitRecordDestructionPop(const Record *R, SourceInfo Loc); bool emitDestructionPop(const Descriptor *Desc, SourceInfo Loc); bool emitDummyPtr(const DeclTy &D, const Expr *E); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
