From eda941359fdb0f2fdf272d34c41cc80c2066a9df Mon Sep 17 00:00:00 2001 From: Simon Pilgrim Date: Wed, 8 Oct 2025 17:11:33 +0100 Subject: [PATCH] [clang][bytecode][x86] Merge interp__builtin_ia32_pmul/interp__builtin_ia32_pmadd implementations The interp__builtin_ia32_pmadd implementation can be correctly used for PMULDQ/PMULUDQ evaluation as well as we're ignoring the "hi" integers in each pair I've replaced the PMULDQ/PMULUDQ evaluation with callbacks and renamed interp__builtin_ia32_pmadd to interp__builtin_ia32_pmul for consistency --- clang/lib/AST/ByteCode/InterpBuiltin.cpp | 68 ++++++------------------ 1 file changed, 16 insertions(+), 52 deletions(-) diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp index 9125250b77347..922d67940e22f 100644 --- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp +++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp @@ -2549,7 +2549,7 @@ static bool interp__builtin_elementwise_maxmin(InterpState &S, CodePtr OpPC, return true; } -static bool interp__builtin_ia32_pmadd( +static bool interp__builtin_ia32_pmul( InterpState &S, CodePtr OpPC, const CallExpr *Call, llvm::function_ref @@ -2587,54 +2587,6 @@ static bool interp__builtin_ia32_pmadd( return true; } -static bool interp__builtin_ia32_pmul(InterpState &S, CodePtr OpPC, - const CallExpr *Call, - unsigned BuiltinID) { - assert(Call->getArg(0)->getType()->isVectorType() && - Call->getArg(1)->getType()->isVectorType()); - const Pointer &RHS = S.Stk.pop(); - const Pointer &LHS = S.Stk.pop(); - const Pointer &Dst = S.Stk.peek(); - - const auto *VT = Call->getArg(0)->getType()->castAs(); - PrimType ElemT = *S.getContext().classify(VT->getElementType()); - unsigned SourceLen = VT->getNumElements(); - - PrimType DstElemT = *S.getContext().classify( - Call->getType()->castAs()->getElementType()); - unsigned DstElem = 0; - for (unsigned I = 0; I != SourceLen; I += 2) { - APSInt Elem1; - APSInt Elem2; - INT_TYPE_SWITCH_NO_BOOL(ElemT, { - Elem1 = LHS.elem(I).toAPSInt(); - Elem2 = RHS.elem(I).toAPSInt(); - }); - - APSInt Result; - switch (BuiltinID) { - 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), - /*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), - /*IsUnsigned=*/false); - break; - } - INT_TYPE_SWITCH_NO_BOOL(DstElemT, - { Dst.elem(DstElem) = static_cast(Result); }); - ++DstElem; - } - - Dst.initializeAllElements(); - return true; -} - static bool interp__builtin_elementwise_triop_fp( InterpState &S, CodePtr OpPC, const CallExpr *Call, llvm::function_ref