[clang] [clang][bytecode] Fix an out-of-bounds access with ia32_pmul* (PR #154750)

Timm Baeder via cfe-commits cfe-commits at lists.llvm.org
Thu Aug 21 05:38:07 PDT 2025


https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/154750

... builtins. We used to access the I'th index of the output vector, but that doesn't work since the output vector is only half the size of the input vector.

>From be53d0ef17b1bfe57d83863a86986b02a8b316c5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Thu, 21 Aug 2025 14:34:28 +0200
Subject: [PATCH] [clang][bytecode] Fix an out-of-bounds access with ia32_pmul*

... builtins. We used to access the I'th index of the output vector, but
that doesn't work since the output vector is only half the size of the
input vector.
---
 clang/lib/AST/ByteCode/InterpBuiltin.cpp | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index 93661d8e2ddf8..2cbebaf7b630e 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -2683,9 +2683,10 @@ static bool interp__builtin_ia32_pmul(InterpState &S, CodePtr OpPC,
   const auto *VT = Call->getArg(0)->getType()->castAs<VectorType>();
   PrimType ElemT = *S.getContext().classify(VT->getElementType());
   unsigned SourceLen = VT->getNumElements();
-  SmallVector<APValue, 4> ResultElements;
-  ResultElements.reserve(SourceLen / 2);
 
+  PrimType DstElemT = *S.getContext().classify(
+      Call->getType()->castAs<VectorType>()->getElementType());
+  unsigned DstElem = 0;
   for (unsigned I = 0; I != SourceLen; I += 2) {
     APSInt Elem1;
     APSInt Elem2;
@@ -2699,16 +2700,19 @@ static bool interp__builtin_ia32_pmul(InterpState &S, CodePtr OpPC,
     case clang::X86::BI__builtin_ia32_pmuludq128:
     case clang::X86::BI__builtin_ia32_pmuludq256:
     case clang::X86::BI__builtin_ia32_pmuludq512:
-      Result = APSInt(llvm::APIntOps::muluExtended(Elem1, Elem2), true);
+      Result = APSInt(llvm::APIntOps::muluExtended(Elem1, Elem2),
+                      /*IsUnsigned=*/true);
       break;
     case clang::X86::BI__builtin_ia32_pmuldq128:
     case clang::X86::BI__builtin_ia32_pmuldq256:
     case clang::X86::BI__builtin_ia32_pmuldq512:
-      Result = APSInt(llvm::APIntOps::mulsExtended(Elem1, Elem2), false);
+      Result = APSInt(llvm::APIntOps::mulsExtended(Elem1, Elem2),
+                      /*IsUnsigned=*/false);
       break;
     }
-    INT_TYPE_SWITCH_NO_BOOL(ElemT,
-                            { Dst.elem<T>(I) = static_cast<T>(Result); });
+    INT_TYPE_SWITCH_NO_BOOL(DstElemT,
+                            { Dst.elem<T>(DstElem) = static_cast<T>(Result); });
+    ++DstElem;
   }
 
   Dst.initializeAllElements();
@@ -3204,6 +3208,7 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
   case clang::X86::BI__builtin_ia32_pmuldq512:
   case clang::X86::BI__builtin_ia32_pmuludq128:
   case clang::X86::BI__builtin_ia32_pmuludq256:
+  case clang::X86::BI__builtin_ia32_pmuludq512:
     return interp__builtin_ia32_pmul(S, OpPC, Call, BuiltinID);
   case Builtin::BI__builtin_elementwise_fma:
     return interp__builtin_elementwise_fma(S, OpPC, Call);



More information about the cfe-commits mailing list