https://github.com/ChiragPatel8 updated 
https://github.com/llvm/llvm-project/pull/214611

>From 9df2aae8c3a25ddc60baad658e756b0fcb1a42ab Mon Sep 17 00:00:00 2001
From: chirag <[email protected]>
Date: Thu, 6 Aug 2026 08:13:17 +0530
Subject: [PATCH 01/11] Adding const attribute.

---
 clang/include/clang/Basic/BuiltinsX86.td    |  7 +++--
 clang/include/clang/Basic/BuiltinsX86_64.td |  4 +--
 clang/lib/Headers/avxintrin.h               |  8 +++---
 clang/lib/Headers/emmintrin.h               | 29 ++++++++++++++-------
 clang/lib/Headers/xmmintrin.h               | 24 ++++++++---------
 5 files changed, 42 insertions(+), 30 deletions(-)

diff --git a/clang/include/clang/Basic/BuiltinsX86.td 
b/clang/include/clang/Basic/BuiltinsX86.td
index 9b7abefb75049..04f93db3aa0b0 100644
--- a/clang/include/clang/Basic/BuiltinsX86.td
+++ b/clang/include/clang/Basic/BuiltinsX86.td
@@ -129,7 +129,7 @@ let Features = "sse", Header = "xmmintrin.h", Attributes = 
[NoThrow, RequireDecl
   def _mm_getcsr : X86LibBuiltin<"unsigned int()">;
 }
 
-let Features = "sse", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] 
in {
+let Features = "sse", Attributes = [NoThrow, Const, Constexpr, 
RequiredVectorWidth<128>] in {
   def cvtss2si : X86Builtin<"int(_Vector<4, float>)">;
   def cvttss2si : X86Builtin<"int(_Vector<4, float>)">;
 }
@@ -179,7 +179,7 @@ let Features = "avx512f", Attributes = [NoThrow, Const, 
Constexpr, RequiredVecto
   def cvtsd2ss_round_mask : X86Builtin<"_Vector<4, float>(_Vector<4, float>, 
_Vector<2, double>, _Vector<4, float>, unsigned char, _Constant int)">;
 }
 
-let Features = "sse2", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] 
in {
+let Features = "sse2", Attributes = [NoThrow, Const, Constexpr, 
RequiredVectorWidth<128>] in {
   def cvtpd2dq : X86Builtin<"_Vector<4, int>(_Vector<2, double>)">;
   def cvttpd2dq : X86Builtin<"_Vector<4, int>(_Vector<2, double>)">;
   def cvtsd2si : X86Builtin<"int(_Vector<2, double>)">;
@@ -475,6 +475,9 @@ let Features = "avx", Attributes = [NoThrow, Const, 
RequiredVectorWidth<256>] in
   def dpps256 : X86Builtin<"_Vector<8, float>(_Vector<8, float>, _Vector<8, 
float>, _Constant char)">;
   def cmppd256 : X86Builtin<"_Vector<4, double>(_Vector<4, double>, _Vector<4, 
double>, _Constant char)">;
   def cmpps256 : X86Builtin<"_Vector<8, float>(_Vector<8, float>, _Vector<8, 
float>, _Constant char)">;
+}
+
+let Features = "avx", Attributes = [NoThrow, Const, Constexpr, 
RequiredVectorWidth<256>] in {
   def cvtps2dq256 : X86Builtin<"_Vector<8, int>(_Vector<8, float>)">;
   def cvttpd2dq256 : X86Builtin<"_Vector<4, int>(_Vector<4, double>)">;
   def cvtpd2dq256 : X86Builtin<"_Vector<4, int>(_Vector<4, double>)">;
diff --git a/clang/include/clang/Basic/BuiltinsX86_64.td 
b/clang/include/clang/Basic/BuiltinsX86_64.td
index 0a98b3049df34..cf76d9a257614 100644
--- a/clang/include/clang/Basic/BuiltinsX86_64.td
+++ b/clang/include/clang/Basic/BuiltinsX86_64.td
@@ -42,12 +42,12 @@ let Attributes = [NoThrow] in {
   def writeeflags_u64 : X86Builtin<"void(unsigned long long int)">;
 }
 
-let Features = "sse", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] 
in {
+let Features = "sse", Attributes = [NoThrow, Const, Constexpr, 
RequiredVectorWidth<128>] in {
   def cvtss2si64 : X86Builtin<"long long int(_Vector<4, float>)">;
   def cvttss2si64 : X86Builtin<"long long int(_Vector<4, float>)">;
 }
 
-let Features = "sse2", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] 
in {
+let Features = "sse2", Attributes = [NoThrow, Const, Constexpr, 
RequiredVectorWidth<128>] in {
   def cvtsd2si64 : X86Builtin<"long long int(_Vector<2, double>)">;
   def cvttsd2si64 : X86Builtin<"long long int(_Vector<2, double>)">;
 }
diff --git a/clang/lib/Headers/avxintrin.h b/clang/lib/Headers/avxintrin.h
index fbd20e58329a3..18b8c6c76a7ce 100644
--- a/clang/lib/Headers/avxintrin.h
+++ b/clang/lib/Headers/avxintrin.h
@@ -2200,7 +2200,7 @@ _mm256_cvtpd_ps(__m256d __a) {
 /// \param __a
 ///    A 256-bit vector of [8 x float].
 /// \returns A 256-bit integer vector containing the converted values.
-static __inline __m256i __DEFAULT_FN_ATTRS
+static __inline __m256i __DEFAULT_FN_ATTRS_CONSTEXPR
 _mm256_cvtps_epi32(__m256 __a)
 {
   return (__m256i)__builtin_ia32_cvtps2dq256((__v8sf) __a);
@@ -2236,7 +2236,7 @@ _mm256_cvtps_pd(__m128 __a) {
 /// \param __a
 ///    A 256-bit vector of [4 x double].
 /// \returns A 128-bit integer vector containing the converted values.
-static __inline __m128i __DEFAULT_FN_ATTRS
+static __inline __m128i __DEFAULT_FN_ATTRS_CONSTEXPR
 _mm256_cvttpd_epi32(__m256d __a)
 {
   return (__m128i)__builtin_ia32_cvttpd2dq256((__v4df) __a);
@@ -2256,7 +2256,7 @@ _mm256_cvttpd_epi32(__m256d __a)
 /// \param __a
 ///    A 256-bit vector of [4 x double].
 /// \returns A 128-bit integer vector containing the converted values.
-static __inline __m128i __DEFAULT_FN_ATTRS
+static __inline __m128i __DEFAULT_FN_ATTRS_CONSTEXPR
 _mm256_cvtpd_epi32(__m256d __a)
 {
   return (__m128i)__builtin_ia32_cvtpd2dq256((__v4df) __a);
@@ -2276,7 +2276,7 @@ _mm256_cvtpd_epi32(__m256d __a)
 /// \param __a
 ///    A 256-bit vector of [8 x float].
 /// \returns A 256-bit integer vector containing the converted values.
-static __inline __m256i __DEFAULT_FN_ATTRS
+static __inline __m256i __DEFAULT_FN_ATTRS_CONSTEXPR
 _mm256_cvttps_epi32(__m256 __a)
 {
   return (__m256i)__builtin_ia32_cvttps2dq256((__v8sf) __a);
diff --git a/clang/lib/Headers/emmintrin.h b/clang/lib/Headers/emmintrin.h
index 3f039edf87e81..eef7077f81e29 100644
--- a/clang/lib/Headers/emmintrin.h
+++ b/clang/lib/Headers/emmintrin.h
@@ -1342,7 +1342,8 @@ _mm_cvtepi32_pd(__m128i __a) {
 ///    A 128-bit vector of [2 x double].
 /// \returns A 128-bit vector of [4 x i32] whose lower 64 bits contain the
 ///    converted values. The upper 64 bits are set to zero.
-static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_cvtpd_epi32(__m128d __a) {
+static __inline__ __m128i __DEFAULT_FN_ATTRS_CONSTEXPR
+_mm_cvtpd_epi32(__m128d __a) {
   return (__m128i)__builtin_ia32_cvtpd2dq((__v2df)__a);
 }
 
@@ -1361,7 +1362,7 @@ static __inline__ __m128i __DEFAULT_FN_ATTRS 
_mm_cvtpd_epi32(__m128d __a) {
 ///    A 128-bit vector of [2 x double]. The lower 64 bits are used in the
 ///    conversion.
 /// \returns A 32-bit signed integer containing the converted value.
-static __inline__ int __DEFAULT_FN_ATTRS _mm_cvtsd_si32(__m128d __a) {
+static __inline__ int __DEFAULT_FN_ATTRS_CONSTEXPR _mm_cvtsd_si32(__m128d __a) 
{
   return __builtin_ia32_cvtsd2si((__v2df)__a);
 }
 
@@ -1455,7 +1456,8 @@ _mm_cvtss_sd(__m128d __a, __m128 __b) {
 ///    A 128-bit vector of [2 x double].
 /// \returns A 128-bit vector of [4 x i32] whose lower 64 bits contain the
 ///    converted values. The upper 64 bits are set to zero.
-static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_cvttpd_epi32(__m128d __a) {
+static __inline__ __m128i __DEFAULT_FN_ATTRS_CONSTEXPR
+_mm_cvttpd_epi32(__m128d __a) {
   return (__m128i)__builtin_ia32_cvttpd2dq((__v2df)__a);
 }
 
@@ -1475,7 +1477,8 @@ static __inline__ __m128i __DEFAULT_FN_ATTRS 
_mm_cvttpd_epi32(__m128d __a) {
 ///    A 128-bit vector of [2 x double]. The lower 64 bits are used in the
 ///    conversion.
 /// \returns A 32-bit signed integer containing the converted value.
-static __inline__ int __DEFAULT_FN_ATTRS _mm_cvttsd_si32(__m128d __a) {
+static __inline__ int __DEFAULT_FN_ATTRS_CONSTEXPR
+_mm_cvttsd_si32(__m128d __a) {
   return __builtin_ia32_cvttsd2si((__v2df)__a);
 }
 
@@ -1494,7 +1497,8 @@ static __inline__ int __DEFAULT_FN_ATTRS 
_mm_cvttsd_si32(__m128d __a) {
 /// \param __a
 ///    A 128-bit vector of [2 x double].
 /// \returns A 64-bit vector of [2 x i32] containing the converted values.
-static __inline__ __m64 __DEFAULT_FN_ATTRS _mm_cvtpd_pi32(__m128d __a) {
+static __inline__ __m64 __DEFAULT_FN_ATTRS_CONSTEXPR
+_mm_cvtpd_pi32(__m128d __a) {
   return __trunc64(__builtin_ia32_cvtpd2dq((__v2df)__a));
 }
 
@@ -1513,7 +1517,8 @@ static __inline__ __m64 __DEFAULT_FN_ATTRS 
_mm_cvtpd_pi32(__m128d __a) {
 /// \param __a
 ///    A 128-bit vector of [2 x double].
 /// \returns A 64-bit vector of [2 x i32] containing the converted values.
-static __inline__ __m64 __DEFAULT_FN_ATTRS _mm_cvttpd_pi32(__m128d __a) {
+static __inline__ __m64 __DEFAULT_FN_ATTRS_CONSTEXPR
+_mm_cvttpd_pi32(__m128d __a) {
   return __trunc64(__builtin_ia32_cvttpd2dq((__v2df)__a));
 }
 
@@ -3287,7 +3292,8 @@ _mm_cvtsi64_sd(__m128d __a, long long __b) {
 ///    A 128-bit vector of [2 x double]. The lower 64 bits are used in the
 ///    conversion.
 /// \returns A 64-bit signed integer containing the converted value.
-static __inline__ long long __DEFAULT_FN_ATTRS _mm_cvtsd_si64(__m128d __a) {
+static __inline__ long long __DEFAULT_FN_ATTRS_CONSTEXPR
+_mm_cvtsd_si64(__m128d __a) {
   return __builtin_ia32_cvtsd2si64((__v2df)__a);
 }
 
@@ -3307,7 +3313,8 @@ static __inline__ long long __DEFAULT_FN_ATTRS 
_mm_cvtsd_si64(__m128d __a) {
 ///    A 128-bit vector of [2 x double]. The lower 64 bits are used in the
 ///    conversion.
 /// \returns A 64-bit signed integer containing the converted value.
-static __inline__ long long __DEFAULT_FN_ATTRS _mm_cvttsd_si64(__m128d __a) {
+static __inline__ long long __DEFAULT_FN_ATTRS_CONSTEXPR
+_mm_cvttsd_si64(__m128d __a) {
   return __builtin_ia32_cvttsd2si64((__v2df)__a);
 }
 #endif
@@ -3340,7 +3347,8 @@ _mm_cvtepi32_ps(__m128i __a) {
 ///    A 128-bit vector of [4 x float].
 /// \returns A 128-bit integer vector of [4 x i32] containing the converted
 ///    values.
-static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_cvtps_epi32(__m128 __a) {
+static __inline__ __m128i __DEFAULT_FN_ATTRS_CONSTEXPR
+_mm_cvtps_epi32(__m128 __a) {
   return (__m128i)__builtin_ia32_cvtps2dq((__v4sf)__a);
 }
 
@@ -3359,7 +3367,8 @@ static __inline__ __m128i __DEFAULT_FN_ATTRS 
_mm_cvtps_epi32(__m128 __a) {
 /// \param __a
 ///    A 128-bit vector of [4 x float].
 /// \returns A 128-bit vector of [4 x i32] containing the converted values.
-static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_cvttps_epi32(__m128 __a) {
+static __inline__ __m128i __DEFAULT_FN_ATTRS_CONSTEXPR
+_mm_cvttps_epi32(__m128 __a) {
   return (__m128i)__builtin_ia32_cvttps2dq((__v4sf)__a);
 }
 
diff --git a/clang/lib/Headers/xmmintrin.h b/clang/lib/Headers/xmmintrin.h
index 73eab9e460ca5..3c7116a23d237 100644
--- a/clang/lib/Headers/xmmintrin.h
+++ b/clang/lib/Headers/xmmintrin.h
@@ -1382,7 +1382,7 @@ _mm_ucomineq_ss(__m128 __a, __m128 __b)
 ///    A 128-bit vector of [4 x float]. The lower 32 bits of this operand are
 ///    used in the conversion.
 /// \returns A 32-bit integer containing the converted value.
-static __inline__ int __DEFAULT_FN_ATTRS
+static __inline__ int __DEFAULT_FN_ATTRS_CONSTEXPR
 _mm_cvtss_si32(__m128 __a)
 {
   return __builtin_ia32_cvtss2si((__v4sf)__a);
@@ -1404,7 +1404,7 @@ _mm_cvtss_si32(__m128 __a)
 ///    A 128-bit vector of [4 x float]. The lower 32 bits of this operand are
 ///    used in the conversion.
 /// \returns A 32-bit integer containing the converted value.
-static __inline__ int __DEFAULT_FN_ATTRS
+static __inline__ int __DEFAULT_FN_ATTRS_CONSTEXPR
 _mm_cvt_ss2si(__m128 __a)
 {
   return _mm_cvtss_si32(__a);
@@ -1428,7 +1428,7 @@ _mm_cvt_ss2si(__m128 __a)
 ///    A 128-bit vector of [4 x float]. The lower 32 bits of this operand are
 ///    used in the conversion.
 /// \returns A 64-bit integer containing the converted value.
-static __inline__ long long __DEFAULT_FN_ATTRS
+static __inline__ long long __DEFAULT_FN_ATTRS_CONSTEXPR
 _mm_cvtss_si64(__m128 __a)
 {
   return __builtin_ia32_cvtss2si64((__v4sf)__a);
@@ -1450,7 +1450,7 @@ _mm_cvtss_si64(__m128 __a)
 /// \param __a
 ///    A 128-bit vector of [4 x float].
 /// \returns A 64-bit integer vector containing the converted values.
-static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2
+static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2_CONSTEXPR
 _mm_cvtps_pi32(__m128 __a)
 {
   return __trunc64(__builtin_ia32_cvtps2dq((__v4sf)__zeroupper64(__a)));
@@ -1470,7 +1470,7 @@ _mm_cvtps_pi32(__m128 __a)
 /// \param __a
 ///    A 128-bit vector of [4 x float].
 /// \returns A 64-bit integer vector containing the converted values.
-static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2
+static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2_CONSTEXPR
 _mm_cvt_ps2pi(__m128 __a)
 {
   return _mm_cvtps_pi32(__a);
@@ -1492,7 +1492,7 @@ _mm_cvt_ps2pi(__m128 __a)
 ///    A 128-bit vector of [4 x float]. The lower 32 bits of this operand are
 ///    used in the conversion.
 /// \returns A 32-bit integer containing the converted value.
-static __inline__ int __DEFAULT_FN_ATTRS
+static __inline__ int __DEFAULT_FN_ATTRS_CONSTEXPR
 _mm_cvttss_si32(__m128 __a)
 {
   return __builtin_ia32_cvttss2si((__v4sf)__a);
@@ -1514,7 +1514,7 @@ _mm_cvttss_si32(__m128 __a)
 ///    A 128-bit vector of [4 x float]. The lower 32 bits of this operand are
 ///    used in the conversion.
 /// \returns A 32-bit integer containing the converted value.
-static __inline__ int __DEFAULT_FN_ATTRS
+static __inline__ int __DEFAULT_FN_ATTRS_CONSTEXPR
 _mm_cvtt_ss2si(__m128 __a)
 {
   return _mm_cvttss_si32(__a);
@@ -1537,7 +1537,7 @@ _mm_cvtt_ss2si(__m128 __a)
 ///    A 128-bit vector of [4 x float]. The lower 32 bits of this operand are
 ///    used in the conversion.
 /// \returns A 64-bit integer containing the converted value.
-static __inline__ long long __DEFAULT_FN_ATTRS
+static __inline__ long long __DEFAULT_FN_ATTRS_CONSTEXPR
 _mm_cvttss_si64(__m128 __a)
 {
   return __builtin_ia32_cvttss2si64((__v4sf)__a);
@@ -1560,7 +1560,7 @@ _mm_cvttss_si64(__m128 __a)
 /// \param __a
 ///    A 128-bit vector of [4 x float].
 /// \returns A 64-bit integer vector containing the converted values.
-static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2
+static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2_CONSTEXPR
 _mm_cvttps_pi32(__m128 __a)
 {
   return __trunc64(__builtin_ia32_cvttps2dq((__v4sf)__zeroupper64(__a)));
@@ -1581,7 +1581,7 @@ _mm_cvttps_pi32(__m128 __a)
 /// \param __a
 ///    A 128-bit vector of [4 x float].
 /// \returns A 64-bit integer vector containing the converted values.
-static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2
+static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2_CONSTEXPR
 _mm_cvtt_ps2pi(__m128 __a)
 {
   return _mm_cvttps_pi32(__a);
@@ -2956,7 +2956,7 @@ _mm_cvtpi32x2_ps(__m64 __a, __m64 __b)
 ///    A 128-bit floating-point vector of [4 x float].
 /// \returns A 64-bit integer vector of [4 x i16] containing the converted
 ///    values.
-static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2
+static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2_CONSTEXPR
 _mm_cvtps_pi16(__m128 __a)
 {
   return __trunc64(__builtin_ia32_packssdw128(
@@ -2981,7 +2981,7 @@ _mm_cvtps_pi16(__m128 __a)
 ///    128-bit floating-point vector of [4 x float].
 /// \returns A 64-bit integer vector of [8 x i8]. The lower 32 bits contain the
 ///    converted values and the uppper 32 bits are set to zero.
-static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2
+static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2_CONSTEXPR
 _mm_cvtps_pi8(__m128 __a)
 {
   __m64 __b, __c;

>From 6b0b0e846f34fa69345e8f8663a788e7feb38f44 Mon Sep 17 00:00:00 2001
From: chirag <[email protected]>
Date: Thu, 6 Aug 2026 20:53:25 +0530
Subject: [PATCH 02/11] Initial implementation.

---
 clang/lib/AST/ByteCode/InterpBuiltin.cpp |  87 ++++++++++++++++++
 clang/lib/AST/ExprConstant.cpp           | 109 +++++++++++++++++++++++
 2 files changed, 196 insertions(+)

diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp 
b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index 68fab67ebe848..d34a7c25d066b 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -4668,6 +4668,61 @@ static bool interp__builtin_ia32_bmac(InterpState &S, 
CodePtr OpPC,
   return true;
 }
 
+static bool
+interp_builtin_ia32_cvt_scalar_to_int(InterpState &S, CodePtr OpPC,
+                                      const CallExpr *E, unsigned BitWidth,
+                                      llvm::RoundingMode RoundingMode) {
+  Pointer SrcVecPtr = S.Stk.pop<Pointer>();
+  Pointer Lane0Ptr = SrcVecPtr.atIndex(0);
+  const Floating &FloatElem = Lane0Ptr.deref<Floating>();
+
+  llvm::APSInt IntResult(BitWidth, /*isUnsigned=*/false);
+  bool IsExact = false;
+  llvm::APFloat::opStatus Status = FloatElem.getAPFloat().convertToInteger(
+      IntResult, RoundingMode, &IsExact);
+
+  if (Status & llvm::APFloat::opInvalidOp) {
+    IntResult = llvm::APSInt(llvm::APInt::getSignedMinValue(BitWidth),
+                             /*isUnsigned=*/false);
+  }
+  pushInteger(S, IntResult, E->getType());
+  return true;
+}
+
+static bool interp_builtin_ia32_cvt_vector_to_int(
+    InterpState &S, CodePtr OpPC, const CallExpr *E,
+    llvm::RoundingMode RoundingMode, bool zeroPad = false) {
+  Pointer SrcVecPtr = S.Stk.pop<Pointer>();
+  const Pointer &Dst = S.Stk.peek<Pointer>();
+  PrimType DstElemT = Dst.getFieldDesc()->getPrimType();
+
+  unsigned NumSrcElts = SrcVecPtr.getNumElems();
+  for (unsigned I = 0; I < NumSrcElts; ++I) {
+    const Floating &FloatElem = SrcVecPtr.atIndex(I).deref<Floating>();
+    llvm::APSInt IntResult(32, /*isUnsigned=*/false);
+    bool IsExact = false;
+
+    llvm::APFloat::opStatus Status = FloatElem.getAPFloat().convertToInteger(
+        IntResult, RoundingMode, &IsExact);
+
+    if (Status & llvm::APFloat::opInvalidOp) {
+      IntResult = llvm::APSInt(llvm::APInt::getSignedMinValue(32),
+                               /*isUnsigned=*/false);
+    }
+    INT_TYPE_SWITCH_NO_BOOL(
+        DstElemT, { Dst.elem<T>(I) = T::from(IntResult.getSExtValue()); });
+  }
+
+  if (zeroPad) {
+    INT_TYPE_SWITCH_NO_BOOL(DstElemT, {
+      Dst.elem<T>(2) = T::from(0);
+      Dst.elem<T>(3) = T::from(0);
+    });
+  }
+  Dst.initializeAllElements();
+  return true;
+}
+
 bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
                       uint32_t BuiltinID) {
   const ASTContext &ASTCtx = S.getASTContext();
@@ -6774,6 +6829,38 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, 
const CallExpr *Call,
   case X86::BI__builtin_ia32_vpdpbusds256:
   case X86::BI__builtin_ia32_vpdpbusds512:
     return interp__builtin_ia32_vpdp(S, OpPC, Call, true);
+  case X86::BI__builtin_ia32_cvtss2si:
+  case X86::BI__builtin_ia32_cvtsd2si:
+    return interp_builtin_ia32_cvt_scalar_to_int(
+        S, OpPC, Call, 32, llvm::RoundingMode::NearestTiesToEven);
+  case X86::BI__builtin_ia32_cvtss2si64:
+  case X86::BI__builtin_ia32_cvtsd2si64:
+    return interp_builtin_ia32_cvt_scalar_to_int(
+        S, OpPC, Call, 64, llvm::RoundingMode::NearestTiesToEven);
+  case X86::BI__builtin_ia32_cvttss2si:
+  case X86::BI__builtin_ia32_cvttsd2si:
+    return interp_builtin_ia32_cvt_scalar_to_int(
+        S, OpPC, Call, 32, llvm::RoundingMode::TowardZero);
+  case X86::BI__builtin_ia32_cvttss2si64:
+  case X86::BI__builtin_ia32_cvttsd2si64:
+    return interp_builtin_ia32_cvt_scalar_to_int(
+        S, OpPC, Call, 64, llvm::RoundingMode::TowardZero);
+  case X86::BI__builtin_ia32_cvtpd2dq:
+    return interp_builtin_ia32_cvt_vector_to_int(
+        S, OpPC, Call, llvm::RoundingMode::NearestTiesToEven, true);
+  case X86::BI__builtin_ia32_cvtps2dq:
+  case X86::BI__builtin_ia32_cvtpd2dq256:
+  case X86::BI__builtin_ia32_cvtps2dq256:
+    return interp_builtin_ia32_cvt_vector_to_int(
+        S, OpPC, Call, llvm::RoundingMode::NearestTiesToEven);
+  case X86::BI__builtin_ia32_cvttpd2dq:
+    return interp_builtin_ia32_cvt_vector_to_int(
+        S, OpPC, Call, llvm::RoundingMode::TowardZero, true);
+  case X86::BI__builtin_ia32_cvttps2dq:
+  case X86::BI__builtin_ia32_cvttpd2dq256:
+  case X86::BI__builtin_ia32_cvttps2dq256:
+    return interp_builtin_ia32_cvt_vector_to_int(
+        S, OpPC, Call, llvm::RoundingMode::TowardZero);
   default:
     S.FFDiag(S.Current->getLocation(OpPC),
              diag::note_invalid_subexpr_in_const_expr)
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 480d5119a5363..0c3d4ddcee685 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -15266,6 +15266,58 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr 
*E) {
   case X86::BI__builtin_ia32_vpdpbusds256:
   case X86::BI__builtin_ia32_vpdpbusds512:
     return EvalVectorDotProduct(true);
+  case X86::BI__builtin_ia32_cvtpd2dq:
+  case X86::BI__builtin_ia32_cvtps2dq:
+  case X86::BI__builtin_ia32_cvttpd2dq:
+  case X86::BI__builtin_ia32_cvttps2dq:
+  case X86::BI__builtin_ia32_cvtpd2dq256:
+  case X86::BI__builtin_ia32_cvtps2dq256:
+  case X86::BI__builtin_ia32_cvttpd2dq256:
+  case X86::BI__builtin_ia32_cvttps2dq256: {
+    APValue SrcVec;
+    if (!EvaluateAsRValue(Info, E->getArg(0), SrcVec) || !SrcVec.isVector())
+      return false;
+
+    llvm::RoundingMode RoundingMode;
+    switch (BuiltinOp) {
+    case X86::BI__builtin_ia32_cvttpd2dq:
+    case X86::BI__builtin_ia32_cvttps2dq:
+    case X86::BI__builtin_ia32_cvttpd2dq256:
+    case X86::BI__builtin_ia32_cvttps2dq256:
+      RoundingMode = llvm::RoundingMode::TowardZero;
+      break;
+    default:
+      RoundingMode = llvm::RoundingMode::NearestTiesToEven;
+      break;
+    }
+
+    unsigned NumSrcElts = SrcVec.getVectorLength();
+    SmallVector<APValue, 8> ResultElts;
+
+    for (unsigned i = 0; i < NumSrcElts; ++i) {
+      llvm::APFloat FloatElem = SrcVec.getVectorElt(i).getFloat();
+      llvm::APSInt IntResult(32, /*isUnsigned=*/false);
+      bool IsExact = false;
+
+      llvm::APFloat::opStatus Status =
+          FloatElem.convertToInteger(IntResult, RoundingMode, &IsExact);
+
+      if (Status & llvm::APFloat::opInvalidOp) {
+        IntResult = llvm::APSInt(llvm::APInt::getSignedMinValue(32),
+                                 /*isUnsigned=*/false);
+      }
+
+      ResultElts.push_back(APValue(IntResult));
+    }
+
+    if (BuiltinOp == X86::BI__builtin_ia32_cvtpd2dq ||
+        BuiltinOp == X86::BI__builtin_ia32_cvttpd2dq) {
+      llvm::APSInt ZeroInt(32, /*isUnsigned=*/false);
+      ResultElts.push_back(APValue(ZeroInt));
+      ResultElts.push_back(APValue(ZeroInt));
+    }
+    return Success(ResultElts, E);
+  }
   }
 }
 
@@ -18688,6 +18740,63 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const 
CallExpr *E,
 
     return Success(APValue(RetMask), E);
   }
+  case X86::BI__builtin_ia32_cvtss2si:
+  case X86::BI__builtin_ia32_cvtsd2si:
+  case X86::BI__builtin_ia32_cvttss2si:
+  case X86::BI__builtin_ia32_cvttsd2si:
+  case X86::BI__builtin_ia32_cvtss2si64:
+  case X86::BI__builtin_ia32_cvtsd2si64:
+  case X86::BI__builtin_ia32_cvttss2si64:
+  case X86::BI__builtin_ia32_cvttsd2si64: {
+    APValue ArgVal;
+    if (!EvaluateAsRValue(Info, E->getArg(0), ArgVal))
+      return false;
+
+    llvm::APFloat FloatElem(0.0f);
+    if (ArgVal.isVector()) {
+      FloatElem = ArgVal.getVectorElt(0).getFloat();
+    } else if (ArgVal.isFloat()) {
+      FloatElem = ArgVal.getFloat();
+    } else {
+      return false;
+    }
+
+    unsigned BitWidth = 32;
+    switch (BuiltinOp) {
+    case X86::BI__builtin_ia32_cvtss2si64:
+    case X86::BI__builtin_ia32_cvtsd2si64:
+    case X86::BI__builtin_ia32_cvttss2si64:
+    case X86::BI__builtin_ia32_cvttsd2si64:
+      BitWidth = 64;
+      break;
+    default:
+      BitWidth = 32;
+      break;
+    }
+
+    llvm::RoundingMode RoundingMode;
+    switch (BuiltinOp) {
+    case X86::BI__builtin_ia32_cvttss2si:
+    case X86::BI__builtin_ia32_cvttsd2si:
+    case X86::BI__builtin_ia32_cvttss2si64:
+    case X86::BI__builtin_ia32_cvttsd2si64:
+      RoundingMode = llvm::RoundingMode::TowardZero;
+      break;
+    default:
+      RoundingMode = llvm::RoundingMode::NearestTiesToEven;
+      break;
+    }
+
+    llvm::APSInt IntResult(BitWidth, false);
+    bool IsExact = false;
+    llvm::APFloat::opStatus Status =
+        FloatElem.convertToInteger(IntResult, RoundingMode, &IsExact);
+
+    if (Status & llvm::APFloat::opInvalidOp) {
+      IntResult = llvm::APSInt(llvm::APInt::getSignedMinValue(BitWidth), 
false);
+    }
+    return Success(IntResult, E);
+  }
   case X86::BI__builtin_ia32_vpshufbitqmb128_mask:
   case X86::BI__builtin_ia32_vpshufbitqmb256_mask:
   case X86::BI__builtin_ia32_vpshufbitqmb512_mask: {

>From 689b2d6e6fce5de4eaca8936c812c74aae343a6b Mon Sep 17 00:00:00 2001
From: chirag <[email protected]>
Date: Thu, 6 Aug 2026 21:10:05 +0530
Subject: [PATCH 03/11] refactoring, dst Type is already known.

---
 clang/lib/AST/ByteCode/InterpBuiltin.cpp | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp 
b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index d34a7c25d066b..87938526ca6a6 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -4709,15 +4709,13 @@ static bool interp_builtin_ia32_cvt_vector_to_int(
       IntResult = llvm::APSInt(llvm::APInt::getSignedMinValue(32),
                                /*isUnsigned=*/false);
     }
-    INT_TYPE_SWITCH_NO_BOOL(
-        DstElemT, { Dst.elem<T>(I) = T::from(IntResult.getSExtValue()); });
+    Dst.atIndex(I).deref<Integral<32, true>>() =
+        Integral<32, true>::from(IntResult.getSExtValue());
   }
 
   if (zeroPad) {
-    INT_TYPE_SWITCH_NO_BOOL(DstElemT, {
-      Dst.elem<T>(2) = T::from(0);
-      Dst.elem<T>(3) = T::from(0);
-    });
+    Dst.atIndex(2).deref<Integral<32, true>>() = Integral<32, true>::zero();
+    Dst.atIndex(3).deref<Integral<32, true>>() = Integral<32, true>::zero();
   }
   Dst.initializeAllElements();
   return true;

>From f84e5a9f0aec176e9c2629f8345a98d2a347303d Mon Sep 17 00:00:00 2001
From: chirag <[email protected]>
Date: Fri, 7 Aug 2026 06:56:42 +0530
Subject: [PATCH 04/11] Removing rounding and handling of nan/infs the issue
 description lists, " EXACT/INBOUNDS and FINITE conversions should be allowed
 at the moment".

---
 clang/lib/AST/ByteCode/InterpBuiltin.cpp | 21 +++++++++++----------
 clang/lib/AST/ExprConstant.cpp           | 11 ++++-------
 2 files changed, 15 insertions(+), 17 deletions(-)

diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp 
b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index 87938526ca6a6..2970b40e5e804 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -4681,10 +4681,9 @@ interp_builtin_ia32_cvt_scalar_to_int(InterpState &S, 
CodePtr OpPC,
   llvm::APFloat::opStatus Status = FloatElem.getAPFloat().convertToInteger(
       IntResult, RoundingMode, &IsExact);
 
-  if (Status & llvm::APFloat::opInvalidOp) {
-    IntResult = llvm::APSInt(llvm::APInt::getSignedMinValue(BitWidth),
-                             /*isUnsigned=*/false);
-  }
+  if (Status != llvm::APFloat::opOK || !IsExact)
+    return false;
+
   pushInteger(S, IntResult, E->getType());
   return true;
 }
@@ -4697,6 +4696,7 @@ static bool interp_builtin_ia32_cvt_vector_to_int(
   PrimType DstElemT = Dst.getFieldDesc()->getPrimType();
 
   unsigned NumSrcElts = SrcVecPtr.getNumElems();
+  llvm::SmallVector<int32_t, 8> ConvertedElts;
   for (unsigned I = 0; I < NumSrcElts; ++I) {
     const Floating &FloatElem = SrcVecPtr.atIndex(I).deref<Floating>();
     llvm::APSInt IntResult(32, /*isUnsigned=*/false);
@@ -4704,15 +4704,16 @@ static bool interp_builtin_ia32_cvt_vector_to_int(
 
     llvm::APFloat::opStatus Status = FloatElem.getAPFloat().convertToInteger(
         IntResult, RoundingMode, &IsExact);
+    if (Status != llvm::APFloat::opOK || !IsExact)
+      return false;
 
-    if (Status & llvm::APFloat::opInvalidOp) {
-      IntResult = llvm::APSInt(llvm::APInt::getSignedMinValue(32),
-                               /*isUnsigned=*/false);
-    }
-    Dst.atIndex(I).deref<Integral<32, true>>() =
-        Integral<32, true>::from(IntResult.getSExtValue());
+    ConvertedElts.push_back(IntResult.getSExtValue());
   }
 
+  for (unsigned I = 0; I < NumSrcElts; ++I)
+    Dst.atIndex(I).deref<Integral<32, true>>() =
+        Integral<32, true>::from(ConvertedElts[I]);
+
   if (zeroPad) {
     Dst.atIndex(2).deref<Integral<32, true>>() = Integral<32, true>::zero();
     Dst.atIndex(3).deref<Integral<32, true>>() = Integral<32, true>::zero();
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 0c3d4ddcee685..319cebe285fca 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -15302,10 +15302,8 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr 
*E) {
       llvm::APFloat::opStatus Status =
           FloatElem.convertToInteger(IntResult, RoundingMode, &IsExact);
 
-      if (Status & llvm::APFloat::opInvalidOp) {
-        IntResult = llvm::APSInt(llvm::APInt::getSignedMinValue(32),
-                                 /*isUnsigned=*/false);
-      }
+      if (Status != llvm::APFloat::opOK || !IsExact)
+          return false;
 
       ResultElts.push_back(APValue(IntResult));
     }
@@ -18791,10 +18789,9 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const 
CallExpr *E,
     bool IsExact = false;
     llvm::APFloat::opStatus Status =
         FloatElem.convertToInteger(IntResult, RoundingMode, &IsExact);
+    if (Status != llvm::APFloat::opOK || !IsExact)
+      return false;
 
-    if (Status & llvm::APFloat::opInvalidOp) {
-      IntResult = llvm::APSInt(llvm::APInt::getSignedMinValue(BitWidth), 
false);
-    }
     return Success(IntResult, E);
   }
   case X86::BI__builtin_ia32_vpshufbitqmb128_mask:

>From 5663a21377c2b643ece15e3d2f30fa1cafe477c3 Mon Sep 17 00:00:00 2001
From: chirag <[email protected]>
Date: Fri, 7 Aug 2026 08:12:22 +0530
Subject: [PATCH 05/11] Adding testcases.

---
 clang/test/CodeGen/X86/avx-builtins.c  |  4 ++++
 clang/test/CodeGen/X86/mmx-builtins.c  |  7 +++++++
 clang/test/CodeGen/X86/sse-builtins.c  | 10 ++++++++++
 clang/test/CodeGen/X86/sse2-builtins.c |  8 ++++++++
 4 files changed, 29 insertions(+)

diff --git a/clang/test/CodeGen/X86/avx-builtins.c 
b/clang/test/CodeGen/X86/avx-builtins.c
index 6ed4217231119..d2667432b0b78 100644
--- a/clang/test/CodeGen/X86/avx-builtins.c
+++ b/clang/test/CodeGen/X86/avx-builtins.c
@@ -961,6 +961,7 @@ __m128i test_mm256_cvtpd_epi32(__m256d A) {
   // CHECK: call <4 x i32> @llvm.x86.avx.cvt.pd2dq.256(<4 x double> %{{.*}})
   return _mm256_cvtpd_epi32(A);
 }
+TEST_CONSTEXPR(match_v4si(_mm256_cvtpd_epi32((__m256d){+96.0, -47.0, +13.0, 
-11.0}), 96, -47, 13, -11));
 
 __m128 test_mm256_cvtpd_ps(__m256d A) {
   // CHECK-LABEL: test_mm256_cvtpd_ps
@@ -975,6 +976,7 @@ __m256i test_mm256_cvtps_epi32(__m256 A) {
   // CHECK: call <8 x i32> @llvm.x86.avx.cvt.ps2dq.256(<8 x float> %{{.*}})
   return _mm256_cvtps_epi32(A);
 }
+TEST_CONSTEXPR(match_v8si(_mm256_cvtps_epi32((__m256){+6.0f, -7.0f, +1.0f, 
-11.0f, +0.0f, 2.0f, -5.0f, +10.0f}), 6, -7, 1, -11, 0, 2, -5, 10));
 
 __m256d test_mm256_cvtps_pd(__m128 A) {
   // CHECK-LABEL: test_mm256_cvtps_pd
@@ -1010,12 +1012,14 @@ __m128i test_mm256_cvttpd_epi32(__m256d A) {
   // CHECK: call <4 x i32> @llvm.x86.avx.cvtt.pd2dq.256(<4 x double> %{{.*}})
   return _mm256_cvttpd_epi32(A);
 }
+TEST_CONSTEXPR(match_v4si(_mm256_cvttpd_epi32((__m256d){+96.0, -47.0, +13.0, 
-11.0}), 96, -47, 13, -11));
 
 __m256i test_mm256_cvttps_epi32(__m256 A) {
   // CHECK-LABEL: test_mm256_cvttps_epi32
   // CHECK: call <8 x i32> @llvm.x86.avx.cvtt.ps2dq.256(<8 x float> %{{.*}})
   return _mm256_cvttps_epi32(A);
 }
+TEST_CONSTEXPR(match_v8si(_mm256_cvttps_epi32((__m256){+36.0f, -74.0f, +91.0f, 
-11.0f, +10.0f, -2.0f, 5.0f, +11.0f}), 36, -74, 91, -11, 10, -2, 5, 11));
 
 __m256d test_mm256_div_pd(__m256d A, __m256d B) {
   // CHECK-LABEL: test_mm256_div_pd
diff --git a/clang/test/CodeGen/X86/mmx-builtins.c 
b/clang/test/CodeGen/X86/mmx-builtins.c
index 90b42ba3cf099..3cae57b6500c8 100644
--- a/clang/test/CodeGen/X86/mmx-builtins.c
+++ b/clang/test/CodeGen/X86/mmx-builtins.c
@@ -194,12 +194,14 @@ __m64 test_mm_cvt_ps2pi(__m128 a) {
   // CHECK: call <4 x i32> @llvm.x86.sse2.cvtps2dq(
   return _mm_cvt_ps2pi(a);
 }
+TEST_CONSTEXPR(match_v2si(_mm_cvt_ps2pi((__m128){-12.0f, +3.0f, +0.0f, 
+1.0f}), -12, 3));
 
 __m64 test_mm_cvtpd_pi32(__m128d a) {
   // CHECK-LABEL: test_mm_cvtpd_pi32
   // CHECK: call <4 x i32> @llvm.x86.sse2.cvtpd2dq(
   return _mm_cvtpd_pi32(a);
 }
+TEST_CONSTEXPR(match_v2si(_mm_cvtpd_pi32((__m128d){+96.0, -24.0}), 96, -24));
 
 __m128 test_mm_cvtpi8_ps(__m64 a) {
   // CHECK-LABEL: test_mm_cvtpi8_ps
@@ -242,12 +244,15 @@ __m64 test_mm_cvtps_pi16(__m128 a) {
   // CHECK: call <8 x i16> @llvm.x86.sse2.packssdw.128(<4 x i32> [[TMP0]],
   return _mm_cvtps_pi16(a);
 }
+TEST_CONSTEXPR(match_v4hi(_mm_cvtps_pi16((__m128){+1.0f, -2.0f, +0.0f, 
-32768.0f}), 1, -2, 0, -32768));
 
 __m64 test_mm_cvtps_pi32(__m128 a) {
   // CHECK-LABEL: test_mm_cvtps_pi32
   // CHECK: call <4 x i32> @llvm.x86.sse2.cvtps2dq(
   return _mm_cvtps_pi32(a);
 }
+TEST_CONSTEXPR(match_v2si(_mm_cvtps_pi32((__m128){+2.0f, 0.0f, 1.0f, -3.0f}), 
2, 0));
+TEST_CONSTEXPR(match_v2si(_mm_cvtps_pi32((__m128){-7.0f, +4.0f, 0.0f, 
-18.0f}), -7, 4));
 
 __m128 test_mm_cvtpu8_ps(__m64 a) {
   // CHECK-LABEL: test_mm_cvtpu8_ps
@@ -282,12 +287,14 @@ __m64 test_mm_cvttpd_pi32(__m128d a) {
   // CHECK: call <4 x i32> @llvm.x86.sse2.cvttpd2dq(
   return _mm_cvttpd_pi32(a);
 }
+TEST_CONSTEXPR(match_v2si(_mm_cvttpd_pi32((__m128d){-69.0, +32.0}), -69, 32));
 
 __m64 test_mm_cvttps_pi32(__m128 a) {
   // CHECK-LABEL: test_mm_cvttps_pi32
   // CHECK: call <4 x i32> @llvm.x86.sse2.cvttps2dq(
   return _mm_cvttps_pi32(a);
 }
+TEST_CONSTEXPR(match_v2si(_mm_cvttps_pi32((__m128){+2.0f, -3.0f, +0.0f, 
+1.0f}), 2, -3));
 
 int test_mm_extract_pi16(__m64 a) {
   // CHECK-LABEL: test_mm_extract_pi16
diff --git a/clang/test/CodeGen/X86/sse-builtins.c 
b/clang/test/CodeGen/X86/sse-builtins.c
index 87b9a99a0e058..8bc8f3161296b 100644
--- a/clang/test/CodeGen/X86/sse-builtins.c
+++ b/clang/test/CodeGen/X86/sse-builtins.c
@@ -325,6 +325,8 @@ int test_mm_cvt_ss2si(__m128 A) {
   // CHECK: call {{.*}}i32 @llvm.x86.sse.cvtss2si(<4 x float> %{{.*}})
   return _mm_cvt_ss2si(A);
 }
+TEST_CONSTEXPR(_mm_cvt_ss2si((__m128){+3.0f}) == 3);
+TEST_CONSTEXPR(_mm_cvt_ss2si((__m128){-5.0f}) == -5);
 
 __m128 test_mm_cvtsi32_ss(__m128 A, int B) {
   // CHECK-LABEL: test_mm_cvtsi32_ss
@@ -364,6 +366,8 @@ int test_mm_cvtss_si32(__m128 A) {
   // CHECK: call {{.*}}i32 @llvm.x86.sse.cvtss2si(<4 x float> %{{.*}})
   return _mm_cvtss_si32(A);
 }
+TEST_CONSTEXPR(_mm_cvtss_si32((__m128){+3.0f}) == 3);
+TEST_CONSTEXPR(_mm_cvtss_si32((__m128){-2.0f}) == -2);
 
 #ifdef __x86_64__
 long long test_mm_cvtss_si64(__m128 A) {
@@ -371,6 +375,8 @@ long long test_mm_cvtss_si64(__m128 A) {
   // CHECK: call {{.*}}i64 @llvm.x86.sse.cvtss2si64(<4 x float> %{{.*}})
   return _mm_cvtss_si64(A);
 }
+TEST_CONSTEXPR(_mm_cvtss_si64((__m128){+1.0f}) == 1LL);
+TEST_CONSTEXPR(_mm_cvtss_si64((__m128){-7.0f}) == -7LL);
 #endif
 
 int test_mm_cvtt_ss2si(__m128 A) {
@@ -378,12 +384,15 @@ int test_mm_cvtt_ss2si(__m128 A) {
   // CHECK: call {{.*}}i32 @llvm.x86.sse.cvttss2si(<4 x float> %{{.*}})
   return _mm_cvtt_ss2si(A);
 }
+TEST_CONSTEXPR(_mm_cvtt_ss2si((__m128){+3.0f}) == 3);
 
 int test_mm_cvttss_si32(__m128 A) {
   // CHECK-LABEL: test_mm_cvttss_si32
   // CHECK: call {{.*}}i32 @llvm.x86.sse.cvttss2si(<4 x float> %{{.*}})
   return _mm_cvttss_si32(A);
 }
+TEST_CONSTEXPR(_mm_cvttss_si32((__m128){+3.0f}) == 3);
+
 
 #ifdef __x86_64__
 long long test_mm_cvttss_si64(__m128 A) {
@@ -391,6 +400,7 @@ long long test_mm_cvttss_si64(__m128 A) {
   // CHECK: call {{.*}}i64 @llvm.x86.sse.cvttss2si64(<4 x float> %{{.*}})
   return _mm_cvttss_si64(A);
 }
+TEST_CONSTEXPR(_mm_cvttss_si64((__m128){-12.0f}) == -12LL);
 #endif
 
 __m128 test_mm_div_ps(__m128 A, __m128 B) {
diff --git a/clang/test/CodeGen/X86/sse2-builtins.c 
b/clang/test/CodeGen/X86/sse2-builtins.c
index 3e36c0047baf0..dca93bbe5b810 100644
--- a/clang/test/CodeGen/X86/sse2-builtins.c
+++ b/clang/test/CodeGen/X86/sse2-builtins.c
@@ -566,6 +566,7 @@ __m128i test_mm_cvtpd_epi32(__m128d A) {
   // CHECK: call <4 x i32> @llvm.x86.sse2.cvtpd2dq(<2 x double> %{{.*}})
   return _mm_cvtpd_epi32(A);
 }
+TEST_CONSTEXPR(match_v4si(_mm_cvtpd_epi32((__m128d){12.0, -45.0}), 12, -45, 0, 
0));
 
 __m128 test_mm_cvtpd_ps(__m128d A) {
   // CHECK-LABEL: test_mm_cvtpd_ps
@@ -580,6 +581,7 @@ __m128i test_mm_cvtps_epi32(__m128 A) {
   // CHECK: call <4 x i32> @llvm.x86.sse2.cvtps2dq(<4 x float> %{{.*}})
   return _mm_cvtps_epi32(A);
 }
+TEST_CONSTEXPR(match_v4si(_mm_cvtps_epi32((__m128){-96.0f, +32.0f, -12.0f, 
+0.0f}), -96, 32, -12, 0));
 
 __m128d test_mm_cvtps_pd(__m128 A) {
   // CHECK-LABEL: test_mm_cvtps_pd
@@ -601,6 +603,7 @@ int test_mm_cvtsd_si32(__m128d A) {
   // CHECK: call {{.*}}i32 @llvm.x86.sse2.cvtsd2si(<2 x double> %{{.*}})
   return _mm_cvtsd_si32(A);
 }
+TEST_CONSTEXPR(_mm_cvtsd_si32((__m128d){+45.0, -12.0}) == 45);
 
 #ifdef __x86_64__
 long long test_mm_cvtsd_si64(__m128d A) {
@@ -608,6 +611,7 @@ long long test_mm_cvtsd_si64(__m128d A) {
   // X64: call {{.*}}i64 @llvm.x86.sse2.cvtsd2si64(<2 x double> %{{.*}})
   return _mm_cvtsd_si64(A);
 }
+TEST_CONSTEXPR(_mm_cvtsd_si64((__m128d){-78.0, +32.0}) == -78LL);
 #endif
 
 __m128 test_mm_cvtsd_ss(__m128 A, __m128d B) {
@@ -682,18 +686,21 @@ __m128i test_mm_cvttpd_epi32(__m128d A) {
   // CHECK: call <4 x i32> @llvm.x86.sse2.cvttpd2dq(<2 x double> %{{.*}})
   return _mm_cvttpd_epi32(A);
 }
+TEST_CONSTEXPR(match_v4si(_mm_cvttpd_epi32((__m128d){+45.0, -96.0}), 45, -96, 
0, 0));
 
 __m128i test_mm_cvttps_epi32(__m128 A) {
   // CHECK-LABEL: test_mm_cvttps_epi32
   // CHECK: call <4 x i32> @llvm.x86.sse2.cvttps2dq(<4 x float> %{{.*}})
   return _mm_cvttps_epi32(A);
 }
+TEST_CONSTEXPR(match_v4si(_mm_cvttps_epi32((__m128){-16.0f, +34.0f, -2.0f, 
+1.0f}), -16, 34, -2, 1));
 
 int test_mm_cvttsd_si32(__m128d A) {
   // CHECK-LABEL: test_mm_cvttsd_si32
   // CHECK: call {{.*}}i32 @llvm.x86.sse2.cvttsd2si(<2 x double> %{{.*}})
   return _mm_cvttsd_si32(A);
 }
+TEST_CONSTEXPR(_mm_cvttsd_si32((__m128d){-326.0, -96.0}) == -326);
 
 #ifdef __x86_64__
 long long test_mm_cvttsd_si64(__m128d A) {
@@ -701,6 +708,7 @@ long long test_mm_cvttsd_si64(__m128d A) {
   // X64: call {{.*}}i64 @llvm.x86.sse2.cvttsd2si64(<2 x double> %{{.*}})
   return _mm_cvttsd_si64(A);
 }
+TEST_CONSTEXPR(_mm_cvttsd_si64((__m128d){-78.0, +45.0}) == -78LL);
 #endif
 
 __m128d test_mm_div_pd(__m128d A, __m128d B) {

>From 3dee34c65167e89bb2f686428e5245d96764ba2d Mon Sep 17 00:00:00 2001
From: chirag <[email protected]>
Date: Fri, 7 Aug 2026 08:28:06 +0530
Subject: [PATCH 06/11] clang-format

---
 clang/lib/AST/ExprConstant.cpp |  2 +-
 clang/lib/Headers/avxintrin.h  | 20 +++++++----------
 clang/lib/Headers/xmmintrin.h  | 40 ++++++++++------------------------
 3 files changed, 21 insertions(+), 41 deletions(-)

diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 319cebe285fca..89f38637fac28 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -15303,7 +15303,7 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr 
*E) {
           FloatElem.convertToInteger(IntResult, RoundingMode, &IsExact);
 
       if (Status != llvm::APFloat::opOK || !IsExact)
-          return false;
+        return false;
 
       ResultElts.push_back(APValue(IntResult));
     }
diff --git a/clang/lib/Headers/avxintrin.h b/clang/lib/Headers/avxintrin.h
index 18b8c6c76a7ce..372ece7a04298 100644
--- a/clang/lib/Headers/avxintrin.h
+++ b/clang/lib/Headers/avxintrin.h
@@ -2201,9 +2201,8 @@ _mm256_cvtpd_ps(__m256d __a) {
 ///    A 256-bit vector of [8 x float].
 /// \returns A 256-bit integer vector containing the converted values.
 static __inline __m256i __DEFAULT_FN_ATTRS_CONSTEXPR
-_mm256_cvtps_epi32(__m256 __a)
-{
-  return (__m256i)__builtin_ia32_cvtps2dq256((__v8sf) __a);
+_mm256_cvtps_epi32(__m256 __a) {
+  return (__m256i)__builtin_ia32_cvtps2dq256((__v8sf)__a);
 }
 
 /// Converts a 128-bit vector of [4 x float] into a 256-bit vector of [4
@@ -2237,9 +2236,8 @@ _mm256_cvtps_pd(__m128 __a) {
 ///    A 256-bit vector of [4 x double].
 /// \returns A 128-bit integer vector containing the converted values.
 static __inline __m128i __DEFAULT_FN_ATTRS_CONSTEXPR
-_mm256_cvttpd_epi32(__m256d __a)
-{
-  return (__m128i)__builtin_ia32_cvttpd2dq256((__v4df) __a);
+_mm256_cvttpd_epi32(__m256d __a) {
+  return (__m128i)__builtin_ia32_cvttpd2dq256((__v4df)__a);
 }
 
 /// Converts a 256-bit vector of [4 x double] into a 128-bit vector of
@@ -2257,9 +2255,8 @@ _mm256_cvttpd_epi32(__m256d __a)
 ///    A 256-bit vector of [4 x double].
 /// \returns A 128-bit integer vector containing the converted values.
 static __inline __m128i __DEFAULT_FN_ATTRS_CONSTEXPR
-_mm256_cvtpd_epi32(__m256d __a)
-{
-  return (__m128i)__builtin_ia32_cvtpd2dq256((__v4df) __a);
+_mm256_cvtpd_epi32(__m256d __a) {
+  return (__m128i)__builtin_ia32_cvtpd2dq256((__v4df)__a);
 }
 
 /// Converts a vector of [8 x float] into eight signed truncated (rounded
@@ -2277,9 +2274,8 @@ _mm256_cvtpd_epi32(__m256d __a)
 ///    A 256-bit vector of [8 x float].
 /// \returns A 256-bit integer vector containing the converted values.
 static __inline __m256i __DEFAULT_FN_ATTRS_CONSTEXPR
-_mm256_cvttps_epi32(__m256 __a)
-{
-  return (__m256i)__builtin_ia32_cvttps2dq256((__v8sf) __a);
+_mm256_cvttps_epi32(__m256 __a) {
+  return (__m256i)__builtin_ia32_cvttps2dq256((__v8sf)__a);
 }
 
 /// Returns the first element of the input vector of [4 x double].
diff --git a/clang/lib/Headers/xmmintrin.h b/clang/lib/Headers/xmmintrin.h
index 3c7116a23d237..36e133312c18d 100644
--- a/clang/lib/Headers/xmmintrin.h
+++ b/clang/lib/Headers/xmmintrin.h
@@ -1382,9 +1382,7 @@ _mm_ucomineq_ss(__m128 __a, __m128 __b)
 ///    A 128-bit vector of [4 x float]. The lower 32 bits of this operand are
 ///    used in the conversion.
 /// \returns A 32-bit integer containing the converted value.
-static __inline__ int __DEFAULT_FN_ATTRS_CONSTEXPR
-_mm_cvtss_si32(__m128 __a)
-{
+static __inline__ int __DEFAULT_FN_ATTRS_CONSTEXPR _mm_cvtss_si32(__m128 __a) {
   return __builtin_ia32_cvtss2si((__v4sf)__a);
 }
 
@@ -1404,9 +1402,7 @@ _mm_cvtss_si32(__m128 __a)
 ///    A 128-bit vector of [4 x float]. The lower 32 bits of this operand are
 ///    used in the conversion.
 /// \returns A 32-bit integer containing the converted value.
-static __inline__ int __DEFAULT_FN_ATTRS_CONSTEXPR
-_mm_cvt_ss2si(__m128 __a)
-{
+static __inline__ int __DEFAULT_FN_ATTRS_CONSTEXPR _mm_cvt_ss2si(__m128 __a) {
   return _mm_cvtss_si32(__a);
 }
 
@@ -1429,8 +1425,7 @@ _mm_cvt_ss2si(__m128 __a)
 ///    used in the conversion.
 /// \returns A 64-bit integer containing the converted value.
 static __inline__ long long __DEFAULT_FN_ATTRS_CONSTEXPR
-_mm_cvtss_si64(__m128 __a)
-{
+_mm_cvtss_si64(__m128 __a) {
   return __builtin_ia32_cvtss2si64((__v4sf)__a);
 }
 
@@ -1451,8 +1446,7 @@ _mm_cvtss_si64(__m128 __a)
 ///    A 128-bit vector of [4 x float].
 /// \returns A 64-bit integer vector containing the converted values.
 static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2_CONSTEXPR
-_mm_cvtps_pi32(__m128 __a)
-{
+_mm_cvtps_pi32(__m128 __a) {
   return __trunc64(__builtin_ia32_cvtps2dq((__v4sf)__zeroupper64(__a)));
 }
 
@@ -1471,8 +1465,7 @@ _mm_cvtps_pi32(__m128 __a)
 ///    A 128-bit vector of [4 x float].
 /// \returns A 64-bit integer vector containing the converted values.
 static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2_CONSTEXPR
-_mm_cvt_ps2pi(__m128 __a)
-{
+_mm_cvt_ps2pi(__m128 __a) {
   return _mm_cvtps_pi32(__a);
 }
 
@@ -1492,9 +1485,7 @@ _mm_cvt_ps2pi(__m128 __a)
 ///    A 128-bit vector of [4 x float]. The lower 32 bits of this operand are
 ///    used in the conversion.
 /// \returns A 32-bit integer containing the converted value.
-static __inline__ int __DEFAULT_FN_ATTRS_CONSTEXPR
-_mm_cvttss_si32(__m128 __a)
-{
+static __inline__ int __DEFAULT_FN_ATTRS_CONSTEXPR _mm_cvttss_si32(__m128 __a) 
{
   return __builtin_ia32_cvttss2si((__v4sf)__a);
 }
 
@@ -1514,9 +1505,7 @@ _mm_cvttss_si32(__m128 __a)
 ///    A 128-bit vector of [4 x float]. The lower 32 bits of this operand are
 ///    used in the conversion.
 /// \returns A 32-bit integer containing the converted value.
-static __inline__ int __DEFAULT_FN_ATTRS_CONSTEXPR
-_mm_cvtt_ss2si(__m128 __a)
-{
+static __inline__ int __DEFAULT_FN_ATTRS_CONSTEXPR _mm_cvtt_ss2si(__m128 __a) {
   return _mm_cvttss_si32(__a);
 }
 
@@ -1538,8 +1527,7 @@ _mm_cvtt_ss2si(__m128 __a)
 ///    used in the conversion.
 /// \returns A 64-bit integer containing the converted value.
 static __inline__ long long __DEFAULT_FN_ATTRS_CONSTEXPR
-_mm_cvttss_si64(__m128 __a)
-{
+_mm_cvttss_si64(__m128 __a) {
   return __builtin_ia32_cvttss2si64((__v4sf)__a);
 }
 #endif
@@ -1561,8 +1549,7 @@ _mm_cvttss_si64(__m128 __a)
 ///    A 128-bit vector of [4 x float].
 /// \returns A 64-bit integer vector containing the converted values.
 static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2_CONSTEXPR
-_mm_cvttps_pi32(__m128 __a)
-{
+_mm_cvttps_pi32(__m128 __a) {
   return __trunc64(__builtin_ia32_cvttps2dq((__v4sf)__zeroupper64(__a)));
 }
 
@@ -1582,8 +1569,7 @@ _mm_cvttps_pi32(__m128 __a)
 ///    A 128-bit vector of [4 x float].
 /// \returns A 64-bit integer vector containing the converted values.
 static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2_CONSTEXPR
-_mm_cvtt_ps2pi(__m128 __a)
-{
+_mm_cvtt_ps2pi(__m128 __a) {
   return _mm_cvttps_pi32(__a);
 }
 
@@ -2957,8 +2943,7 @@ _mm_cvtpi32x2_ps(__m64 __a, __m64 __b)
 /// \returns A 64-bit integer vector of [4 x i16] containing the converted
 ///    values.
 static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2_CONSTEXPR
-_mm_cvtps_pi16(__m128 __a)
-{
+_mm_cvtps_pi16(__m128 __a) {
   return __trunc64(__builtin_ia32_packssdw128(
       (__v4si)__builtin_ia32_cvtps2dq((__v4sf)__a), (__v4si)_mm_setzero_ps()));
 }
@@ -2982,8 +2967,7 @@ _mm_cvtps_pi16(__m128 __a)
 /// \returns A 64-bit integer vector of [8 x i8]. The lower 32 bits contain the
 ///    converted values and the uppper 32 bits are set to zero.
 static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2_CONSTEXPR
-_mm_cvtps_pi8(__m128 __a)
-{
+_mm_cvtps_pi8(__m128 __a) {
   __m64 __b, __c;
 
   __b = _mm_cvtps_pi16(__a);

>From 65c2812fd3b0c10282709d6cdf66eaf35aa77433 Mon Sep 17 00:00:00 2001
From: chirag <[email protected]>
Date: Fri, 7 Aug 2026 08:59:13 +0530
Subject: [PATCH 07/11] Cleanup unused var

---
 clang/lib/AST/ByteCode/InterpBuiltin.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp 
b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index 2970b40e5e804..35ca70eec4d49 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -4693,7 +4693,6 @@ static bool interp_builtin_ia32_cvt_vector_to_int(
     llvm::RoundingMode RoundingMode, bool zeroPad = false) {
   Pointer SrcVecPtr = S.Stk.pop<Pointer>();
   const Pointer &Dst = S.Stk.peek<Pointer>();
-  PrimType DstElemT = Dst.getFieldDesc()->getPrimType();
 
   unsigned NumSrcElts = SrcVecPtr.getNumElems();
   llvm::SmallVector<int32_t, 8> ConvertedElts;

>From 80a0c75de3e71cc1fa87a3cd9114502c1647abda Mon Sep 17 00:00:00 2001
From: chirag <[email protected]>
Date: Fri, 7 Aug 2026 09:39:35 +0530
Subject: [PATCH 08/11] Build fix.

---
 clang/lib/Headers/xmmintrin.h | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/clang/lib/Headers/xmmintrin.h b/clang/lib/Headers/xmmintrin.h
index 36e133312c18d..dc84cbe5e274a 100644
--- a/clang/lib/Headers/xmmintrin.h
+++ b/clang/lib/Headers/xmmintrin.h
@@ -2968,12 +2968,7 @@ _mm_cvtps_pi16(__m128 __a) {
 ///    converted values and the uppper 32 bits are set to zero.
 static __inline__ __m64 __DEFAULT_FN_ATTRS_SSE2_CONSTEXPR
 _mm_cvtps_pi8(__m128 __a) {
-  __m64 __b, __c;
-
-  __b = _mm_cvtps_pi16(__a);
-  __c = _mm_setzero_si64();
-
-  return _mm_packs_pi16(__b, __c);
+  return _mm_packs_pi16(_mm_cvtps_pi16(__a), _mm_setzero_si64());
 }
 
 /// Extracts the sign bits from each single-precision floating-point

>From 59ada1801ec0ab7a8c94dd84600907f8141bf55f Mon Sep 17 00:00:00 2001
From: chirag <[email protected]>
Date: Mon, 10 Aug 2026 09:12:00 +0530
Subject: [PATCH 09/11] removed redudant checks.

---
 clang/lib/AST/ByteCode/InterpBuiltin.cpp | 12 ++++--------
 clang/lib/AST/ExprConstant.cpp           | 16 ++++++++--------
 2 files changed, 12 insertions(+), 16 deletions(-)

diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp 
b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index 35ca70eec4d49..a2d31d7c3f858 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -4678,10 +4678,8 @@ interp_builtin_ia32_cvt_scalar_to_int(InterpState &S, 
CodePtr OpPC,
 
   llvm::APSInt IntResult(BitWidth, /*isUnsigned=*/false);
   bool IsExact = false;
-  llvm::APFloat::opStatus Status = FloatElem.getAPFloat().convertToInteger(
-      IntResult, RoundingMode, &IsExact);
-
-  if (Status != llvm::APFloat::opOK || !IsExact)
+  FloatElem.getAPFloat().convertToInteger(IntResult, RoundingMode, &IsExact);
+  if (!IsExact)
     return false;
 
   pushInteger(S, IntResult, E->getType());
@@ -4700,10 +4698,8 @@ static bool interp_builtin_ia32_cvt_vector_to_int(
     const Floating &FloatElem = SrcVecPtr.atIndex(I).deref<Floating>();
     llvm::APSInt IntResult(32, /*isUnsigned=*/false);
     bool IsExact = false;
-
-    llvm::APFloat::opStatus Status = FloatElem.getAPFloat().convertToInteger(
-        IntResult, RoundingMode, &IsExact);
-    if (Status != llvm::APFloat::opOK || !IsExact)
+    FloatElem.getAPFloat().convertToInteger(IntResult, RoundingMode, &IsExact);
+    if (!IsExact)
       return false;
 
     ConvertedElts.push_back(IntResult.getSExtValue());
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 89f38637fac28..2a9d325db822f 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -15298,11 +15298,8 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr 
*E) {
       llvm::APFloat FloatElem = SrcVec.getVectorElt(i).getFloat();
       llvm::APSInt IntResult(32, /*isUnsigned=*/false);
       bool IsExact = false;
-
-      llvm::APFloat::opStatus Status =
-          FloatElem.convertToInteger(IntResult, RoundingMode, &IsExact);
-
-      if (Status != llvm::APFloat::opOK || !IsExact)
+      FloatElem.convertToInteger(IntResult, RoundingMode, &IsExact);
+      if (!IsExact)
         return false;
 
       ResultElts.push_back(APValue(IntResult));
@@ -18781,15 +18778,18 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const 
CallExpr *E,
       RoundingMode = llvm::RoundingMode::TowardZero;
       break;
     default:
+      // For builtins such as _mm_cvtss_si32, the default rounding is
+      // NearestTiesToEven as CPU reset default value. But, the actual rounding
+      // at runtime is read from MXCSR CPU register which is not known
+      // here. Hence, this cannot be deduced correctly here.
       RoundingMode = llvm::RoundingMode::NearestTiesToEven;
       break;
     }
 
     llvm::APSInt IntResult(BitWidth, false);
     bool IsExact = false;
-    llvm::APFloat::opStatus Status =
-        FloatElem.convertToInteger(IntResult, RoundingMode, &IsExact);
-    if (Status != llvm::APFloat::opOK || !IsExact)
+    FloatElem.convertToInteger(IntResult, RoundingMode, &IsExact);
+    if (!IsExact)
       return false;
 
     return Success(IntResult, E);

>From d42df8328276be0fef01f1b05df3bd1dfbdc93d3 Mon Sep 17 00:00:00 2001
From: chirag <[email protected]>
Date: Mon, 10 Aug 2026 10:18:36 +0530
Subject: [PATCH 10/11] Simplyfy code.

---
 clang/lib/AST/ByteCode/InterpBuiltin.cpp | 49 ++++++++++-------------
 clang/lib/AST/ExprConstant.cpp           | 51 +++++-------------------
 2 files changed, 31 insertions(+), 69 deletions(-)

diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp 
b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index a2d31d7c3f858..e365ff2ecf18e 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -4668,17 +4668,19 @@ static bool interp__builtin_ia32_bmac(InterpState &S, 
CodePtr OpPC,
   return true;
 }
 
-static bool
-interp_builtin_ia32_cvt_scalar_to_int(InterpState &S, CodePtr OpPC,
-                                      const CallExpr *E, unsigned BitWidth,
-                                      llvm::RoundingMode RoundingMode) {
+static bool interp_builtin_ia32_cvt_scalar_to_int(InterpState &S, CodePtr OpPC,
+                                                  const CallExpr *E,
+                                                  unsigned BitWidth) {
   Pointer SrcVecPtr = S.Stk.pop<Pointer>();
   Pointer Lane0Ptr = SrcVecPtr.atIndex(0);
   const Floating &FloatElem = Lane0Ptr.deref<Floating>();
 
   llvm::APSInt IntResult(BitWidth, /*isUnsigned=*/false);
   bool IsExact = false;
-  FloatElem.getAPFloat().convertToInteger(IntResult, RoundingMode, &IsExact);
+  // We only allow exact conversions so rounding mode does not matter for cvt*
+  // and cvtt* builtins
+  FloatElem.getAPFloat().convertToInteger(
+      IntResult, llvm::APFloat::rmTowardZero, &IsExact);
   if (!IsExact)
     return false;
 
@@ -4686,9 +4688,9 @@ interp_builtin_ia32_cvt_scalar_to_int(InterpState &S, 
CodePtr OpPC,
   return true;
 }
 
-static bool interp_builtin_ia32_cvt_vector_to_int(
-    InterpState &S, CodePtr OpPC, const CallExpr *E,
-    llvm::RoundingMode RoundingMode, bool zeroPad = false) {
+static bool interp_builtin_ia32_cvt_vector_to_int(InterpState &S, CodePtr OpPC,
+                                                  const CallExpr *E,
+                                                  bool zeroPad = false) {
   Pointer SrcVecPtr = S.Stk.pop<Pointer>();
   const Pointer &Dst = S.Stk.peek<Pointer>();
 
@@ -4698,7 +4700,10 @@ static bool interp_builtin_ia32_cvt_vector_to_int(
     const Floating &FloatElem = SrcVecPtr.atIndex(I).deref<Floating>();
     llvm::APSInt IntResult(32, /*isUnsigned=*/false);
     bool IsExact = false;
-    FloatElem.getAPFloat().convertToInteger(IntResult, RoundingMode, &IsExact);
+    // We only allow exact conversions so rounding mode does not matter for 
cvt*
+    // and cvtt* builtins
+    FloatElem.getAPFloat().convertToInteger(
+        IntResult, llvm::APFloat::rmTowardZero, &IsExact);
     if (!IsExact)
       return false;
 
@@ -6825,36 +6830,24 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, 
const CallExpr *Call,
     return interp__builtin_ia32_vpdp(S, OpPC, Call, true);
   case X86::BI__builtin_ia32_cvtss2si:
   case X86::BI__builtin_ia32_cvtsd2si:
-    return interp_builtin_ia32_cvt_scalar_to_int(
-        S, OpPC, Call, 32, llvm::RoundingMode::NearestTiesToEven);
-  case X86::BI__builtin_ia32_cvtss2si64:
-  case X86::BI__builtin_ia32_cvtsd2si64:
-    return interp_builtin_ia32_cvt_scalar_to_int(
-        S, OpPC, Call, 64, llvm::RoundingMode::NearestTiesToEven);
   case X86::BI__builtin_ia32_cvttss2si:
   case X86::BI__builtin_ia32_cvttsd2si:
-    return interp_builtin_ia32_cvt_scalar_to_int(
-        S, OpPC, Call, 32, llvm::RoundingMode::TowardZero);
+    return interp_builtin_ia32_cvt_scalar_to_int(S, OpPC, Call, 32);
+  case X86::BI__builtin_ia32_cvtss2si64:
+  case X86::BI__builtin_ia32_cvtsd2si64:
   case X86::BI__builtin_ia32_cvttss2si64:
   case X86::BI__builtin_ia32_cvttsd2si64:
-    return interp_builtin_ia32_cvt_scalar_to_int(
-        S, OpPC, Call, 64, llvm::RoundingMode::TowardZero);
+    return interp_builtin_ia32_cvt_scalar_to_int(S, OpPC, Call, 64);
   case X86::BI__builtin_ia32_cvtpd2dq:
-    return interp_builtin_ia32_cvt_vector_to_int(
-        S, OpPC, Call, llvm::RoundingMode::NearestTiesToEven, true);
+  case X86::BI__builtin_ia32_cvttpd2dq:
+    return interp_builtin_ia32_cvt_vector_to_int(S, OpPC, Call, true);
   case X86::BI__builtin_ia32_cvtps2dq:
   case X86::BI__builtin_ia32_cvtpd2dq256:
   case X86::BI__builtin_ia32_cvtps2dq256:
-    return interp_builtin_ia32_cvt_vector_to_int(
-        S, OpPC, Call, llvm::RoundingMode::NearestTiesToEven);
-  case X86::BI__builtin_ia32_cvttpd2dq:
-    return interp_builtin_ia32_cvt_vector_to_int(
-        S, OpPC, Call, llvm::RoundingMode::TowardZero, true);
   case X86::BI__builtin_ia32_cvttps2dq:
   case X86::BI__builtin_ia32_cvttpd2dq256:
   case X86::BI__builtin_ia32_cvttps2dq256:
-    return interp_builtin_ia32_cvt_vector_to_int(
-        S, OpPC, Call, llvm::RoundingMode::TowardZero);
+    return interp_builtin_ia32_cvt_vector_to_int(S, OpPC, Call);
   default:
     S.FFDiag(S.Current->getLocation(OpPC),
              diag::note_invalid_subexpr_in_const_expr)
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 2a9d325db822f..01ceb49cc3f2a 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -15278,19 +15278,6 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr 
*E) {
     if (!EvaluateAsRValue(Info, E->getArg(0), SrcVec) || !SrcVec.isVector())
       return false;
 
-    llvm::RoundingMode RoundingMode;
-    switch (BuiltinOp) {
-    case X86::BI__builtin_ia32_cvttpd2dq:
-    case X86::BI__builtin_ia32_cvttps2dq:
-    case X86::BI__builtin_ia32_cvttpd2dq256:
-    case X86::BI__builtin_ia32_cvttps2dq256:
-      RoundingMode = llvm::RoundingMode::TowardZero;
-      break;
-    default:
-      RoundingMode = llvm::RoundingMode::NearestTiesToEven;
-      break;
-    }
-
     unsigned NumSrcElts = SrcVec.getVectorLength();
     SmallVector<APValue, 8> ResultElts;
 
@@ -15298,7 +15285,10 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr 
*E) {
       llvm::APFloat FloatElem = SrcVec.getVectorElt(i).getFloat();
       llvm::APSInt IntResult(32, /*isUnsigned=*/false);
       bool IsExact = false;
-      FloatElem.convertToInteger(IntResult, RoundingMode, &IsExact);
+      // We only allow exact conversions so rounding mode does not matter for
+      // cvt* and cvtt* builtins
+      FloatElem.convertToInteger(IntResult, llvm::APFloat::rmTowardZero,
+                                 &IsExact);
       if (!IsExact)
         return false;
 
@@ -18747,14 +18737,8 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const 
CallExpr *E,
     if (!EvaluateAsRValue(Info, E->getArg(0), ArgVal))
       return false;
 
-    llvm::APFloat FloatElem(0.0f);
-    if (ArgVal.isVector()) {
-      FloatElem = ArgVal.getVectorElt(0).getFloat();
-    } else if (ArgVal.isFloat()) {
-      FloatElem = ArgVal.getFloat();
-    } else {
-      return false;
-    }
+    assert(ArgVal.isVector() && "Expected a vector argument");
+    llvm::APFloat FloatElem = ArgVal.getVectorElt(0).getFloat();
 
     unsigned BitWidth = 32;
     switch (BuiltinOp) {
@@ -18765,30 +18749,15 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const 
CallExpr *E,
       BitWidth = 64;
       break;
     default:
-      BitWidth = 32;
-      break;
-    }
-
-    llvm::RoundingMode RoundingMode;
-    switch (BuiltinOp) {
-    case X86::BI__builtin_ia32_cvttss2si:
-    case X86::BI__builtin_ia32_cvttsd2si:
-    case X86::BI__builtin_ia32_cvttss2si64:
-    case X86::BI__builtin_ia32_cvttsd2si64:
-      RoundingMode = llvm::RoundingMode::TowardZero;
-      break;
-    default:
-      // For builtins such as _mm_cvtss_si32, the default rounding is
-      // NearestTiesToEven as CPU reset default value. But, the actual rounding
-      // at runtime is read from MXCSR CPU register which is not known
-      // here. Hence, this cannot be deduced correctly here.
-      RoundingMode = llvm::RoundingMode::NearestTiesToEven;
       break;
     }
 
     llvm::APSInt IntResult(BitWidth, false);
     bool IsExact = false;
-    FloatElem.convertToInteger(IntResult, RoundingMode, &IsExact);
+    // We only allow exact conversions so rounding mode does not matter for 
cvt*
+    // and cvtt* builtins
+    FloatElem.convertToInteger(IntResult, llvm::APFloat::rmTowardZero,
+                               &IsExact);
     if (!IsExact)
       return false;
 

>From 16a5b34d33140028cd46f6f87e0c16512bdba4d7 Mon Sep 17 00:00:00 2001
From: chirag <[email protected]>
Date: Tue, 11 Aug 2026 23:07:56 +0530
Subject: [PATCH 11/11] Simplify more.

---
 clang/lib/AST/ByteCode/InterpBuiltin.cpp | 21 ++++------
 clang/lib/AST/ExprConstant.cpp           | 50 +++++++++---------------
 2 files changed, 26 insertions(+), 45 deletions(-)

diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp 
b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index e365ff2ecf18e..399cce197c977 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -4669,11 +4669,11 @@ static bool interp__builtin_ia32_bmac(InterpState &S, 
CodePtr OpPC,
 }
 
 static bool interp_builtin_ia32_cvt_scalar_to_int(InterpState &S, CodePtr OpPC,
-                                                  const CallExpr *E,
-                                                  unsigned BitWidth) {
+                                                  const CallExpr *E) {
   Pointer SrcVecPtr = S.Stk.pop<Pointer>();
   Pointer Lane0Ptr = SrcVecPtr.atIndex(0);
   const Floating &FloatElem = Lane0Ptr.deref<Floating>();
+  unsigned BitWidth = S.getASTContext().getIntWidth(E->getType());
 
   llvm::APSInt IntResult(BitWidth, /*isUnsigned=*/false);
   bool IsExact = false;
@@ -4689,12 +4689,12 @@ static bool 
interp_builtin_ia32_cvt_scalar_to_int(InterpState &S, CodePtr OpPC,
 }
 
 static bool interp_builtin_ia32_cvt_vector_to_int(InterpState &S, CodePtr OpPC,
-                                                  const CallExpr *E,
-                                                  bool zeroPad = false) {
+                                                  const CallExpr *E) {
   Pointer SrcVecPtr = S.Stk.pop<Pointer>();
   const Pointer &Dst = S.Stk.peek<Pointer>();
 
   unsigned NumSrcElts = SrcVecPtr.getNumElems();
+  unsigned NumDstElts = Dst.getNumElems();
   llvm::SmallVector<int32_t, 8> ConvertedElts;
   for (unsigned I = 0; I < NumSrcElts; ++I) {
     const Floating &FloatElem = SrcVecPtr.atIndex(I).deref<Floating>();
@@ -4710,14 +4710,11 @@ static bool 
interp_builtin_ia32_cvt_vector_to_int(InterpState &S, CodePtr OpPC,
     ConvertedElts.push_back(IntResult.getSExtValue());
   }
 
-  for (unsigned I = 0; I < NumSrcElts; ++I)
+  for (unsigned I = 0; I < NumDstElts; ++I)
     Dst.atIndex(I).deref<Integral<32, true>>() =
-        Integral<32, true>::from(ConvertedElts[I]);
+        I < NumSrcElts ? Integral<32, true>::from(ConvertedElts[I])
+                       : Integral<32, true>::zero();
 
-  if (zeroPad) {
-    Dst.atIndex(2).deref<Integral<32, true>>() = Integral<32, true>::zero();
-    Dst.atIndex(3).deref<Integral<32, true>>() = Integral<32, true>::zero();
-  }
   Dst.initializeAllElements();
   return true;
 }
@@ -6832,15 +6829,13 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, 
const CallExpr *Call,
   case X86::BI__builtin_ia32_cvtsd2si:
   case X86::BI__builtin_ia32_cvttss2si:
   case X86::BI__builtin_ia32_cvttsd2si:
-    return interp_builtin_ia32_cvt_scalar_to_int(S, OpPC, Call, 32);
   case X86::BI__builtin_ia32_cvtss2si64:
   case X86::BI__builtin_ia32_cvtsd2si64:
   case X86::BI__builtin_ia32_cvttss2si64:
   case X86::BI__builtin_ia32_cvttsd2si64:
-    return interp_builtin_ia32_cvt_scalar_to_int(S, OpPC, Call, 64);
+    return interp_builtin_ia32_cvt_scalar_to_int(S, OpPC, Call);
   case X86::BI__builtin_ia32_cvtpd2dq:
   case X86::BI__builtin_ia32_cvttpd2dq:
-    return interp_builtin_ia32_cvt_vector_to_int(S, OpPC, Call, true);
   case X86::BI__builtin_ia32_cvtps2dq:
   case X86::BI__builtin_ia32_cvtpd2dq256:
   case X86::BI__builtin_ia32_cvtps2dq256:
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 01ceb49cc3f2a..0743548ded3bc 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -15279,27 +15279,24 @@ bool VectorExprEvaluator::VisitCallExpr(const 
CallExpr *E) {
       return false;
 
     unsigned NumSrcElts = SrcVec.getVectorLength();
-    SmallVector<APValue, 8> ResultElts;
-
-    for (unsigned i = 0; i < NumSrcElts; ++i) {
-      llvm::APFloat FloatElem = SrcVec.getVectorElt(i).getFloat();
-      llvm::APSInt IntResult(32, /*isUnsigned=*/false);
-      bool IsExact = false;
-      // We only allow exact conversions so rounding mode does not matter for
-      // cvt* and cvtt* builtins
-      FloatElem.convertToInteger(IntResult, llvm::APFloat::rmTowardZero,
-                                 &IsExact);
-      if (!IsExact)
-        return false;
+    unsigned NumDestElts = 
E->getType()->castAs<VectorType>()->getNumElements();
 
-      ResultElts.push_back(APValue(IntResult));
-    }
-
-    if (BuiltinOp == X86::BI__builtin_ia32_cvtpd2dq ||
-        BuiltinOp == X86::BI__builtin_ia32_cvttpd2dq) {
-      llvm::APSInt ZeroInt(32, /*isUnsigned=*/false);
-      ResultElts.push_back(APValue(ZeroInt));
-      ResultElts.push_back(APValue(ZeroInt));
+    SmallVector<APValue, 8> ResultElts;
+    for (unsigned i = 0; i < NumDestElts; ++i) {
+      if (i < NumSrcElts) {
+        llvm::APFloat FloatElem = SrcVec.getVectorElt(i).getFloat();
+        llvm::APSInt IntResult(32, /*isUnsigned=*/false);
+        bool IsExact = false;
+        // We only allow exact conversions so rounding mode does not matter for
+        // cvt* and cvtt* builtins
+        FloatElem.convertToInteger(IntResult, llvm::APFloat::rmTowardZero,
+                                   &IsExact);
+        if (!IsExact)
+          return false;
+        ResultElts.push_back(APValue(IntResult));
+      } else
+        // Pad remaining lanes with zero
+        ResultElts.push_back(APValue(llvm::APSInt(32, /*isUnsigned=*/false)));
     }
     return Success(ResultElts, E);
   }
@@ -18739,18 +18736,7 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const 
CallExpr *E,
 
     assert(ArgVal.isVector() && "Expected a vector argument");
     llvm::APFloat FloatElem = ArgVal.getVectorElt(0).getFloat();
-
-    unsigned BitWidth = 32;
-    switch (BuiltinOp) {
-    case X86::BI__builtin_ia32_cvtss2si64:
-    case X86::BI__builtin_ia32_cvtsd2si64:
-    case X86::BI__builtin_ia32_cvttss2si64:
-    case X86::BI__builtin_ia32_cvttsd2si64:
-      BitWidth = 64;
-      break;
-    default:
-      break;
-    }
+    unsigned BitWidth = Info.Ctx.getIntWidth(E->getType());
 
     llvm::APSInt IntResult(BitWidth, false);
     bool IsExact = false;

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to