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

Reply via email to