Author: Simon Pilgrim Date: 2025-09-05T08:19:32Z New Revision: d1050bf86d61ffc2abcff798671193b2f702bf87
URL: https://github.com/llvm/llvm-project/commit/d1050bf86d61ffc2abcff798671193b2f702bf87 DIFF: https://github.com/llvm/llvm-project/commit/d1050bf86d61ffc2abcff798671193b2f702bf87.diff LOG: [Clang][bytecode] Add interp__builtin_elementwise_triop to handle general 3-operand integer intrinsics (#156944) Refactor interp__builtin_elementwise_fsh into something similar to interp__builtin_elementwise_int_binop with a callback function argument to allow reuse with other intrinsics This will allow reuse with some upcoming x86 intrinsics We can flesh out handling for mixed vector/scalar args as the need arises Added: Modified: clang/lib/AST/ByteCode/InterpBuiltin.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp index ff6ef5a1f6864..713895b191c88 100644 --- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp +++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp @@ -2829,9 +2829,10 @@ static bool interp__builtin_select(InterpState &S, CodePtr OpPC, return true; } -static bool interp__builtin_elementwise_fsh(InterpState &S, CodePtr OpPC, - const CallExpr *Call, - unsigned BuiltinID) { +static bool interp__builtin_elementwise_triop( + InterpState &S, CodePtr OpPC, const CallExpr *Call, + llvm::function_ref<APInt(const APSInt &, const APSInt &, const APSInt &)> + Fn) { assert(Call->getNumArgs() == 3); QualType Arg0Type = Call->getArg(0)->getType(); @@ -2840,17 +2841,10 @@ static bool interp__builtin_elementwise_fsh(InterpState &S, CodePtr OpPC, // Non-vector integer types. if (!Arg0Type->isVectorType()) { - const APSInt &Shift = - popToAPSInt(S.Stk, *S.getContext().classify(Arg2Type)); - const APSInt &Lo = popToAPSInt(S.Stk, *S.getContext().classify(Arg1Type)); - const APSInt &Hi = popToAPSInt(S.Stk, *S.getContext().classify(Arg0Type)); - APSInt Result; - if (BuiltinID == Builtin::BI__builtin_elementwise_fshl) - Result = APSInt(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned()); - else if (BuiltinID == Builtin::BI__builtin_elementwise_fshr) - Result = APSInt(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned()); - else - llvm_unreachable("Wrong builtin ID"); + const APSInt &Op2 = popToAPSInt(S.Stk, *S.getContext().classify(Arg2Type)); + const APSInt &Op1 = popToAPSInt(S.Stk, *S.getContext().classify(Arg1Type)); + const APSInt &Op0 = popToAPSInt(S.Stk, *S.getContext().classify(Arg0Type)); + APSInt Result = APSInt(Fn(Op0, Op1, Op2), Op0.isUnsigned()); pushInteger(S, Result, Call->getType()); return true; } @@ -2860,26 +2854,18 @@ static bool interp__builtin_elementwise_fsh(InterpState &S, CodePtr OpPC, const PrimType &ElemT = *S.getContext().classify(VecT->getElementType()); unsigned NumElems = VecT->getNumElements(); - const Pointer &VecShift = S.Stk.pop<Pointer>(); - const Pointer &VecLo = S.Stk.pop<Pointer>(); - const Pointer &VecHi = S.Stk.pop<Pointer>(); + const Pointer &Op2 = S.Stk.pop<Pointer>(); + const Pointer &Op1 = S.Stk.pop<Pointer>(); + const Pointer &Op0 = S.Stk.pop<Pointer>(); const Pointer &Dst = S.Stk.peek<Pointer>(); for (unsigned I = 0; I != NumElems; ++I) { - APSInt Hi; - APSInt Lo; - APSInt Shift; + APSInt Val0, Val1, Val2; INT_TYPE_SWITCH_NO_BOOL(ElemT, { - Hi = VecHi.elem<T>(I).toAPSInt(); - Lo = VecLo.elem<T>(I).toAPSInt(); - Shift = VecShift.elem<T>(I).toAPSInt(); + Val0 = Op0.elem<T>(I).toAPSInt(); + Val1 = Op1.elem<T>(I).toAPSInt(); + Val2 = Op2.elem<T>(I).toAPSInt(); }); - APSInt Result; - if (BuiltinID == Builtin::BI__builtin_elementwise_fshl) - Result = APSInt(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned()); - else if (BuiltinID == Builtin::BI__builtin_elementwise_fshr) - Result = APSInt(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned()); - else - llvm_unreachable("Wrong builtin ID"); + APSInt Result = APSInt(Fn(Val0, Val1, Val2), Val0.isUnsigned()); INT_TYPE_SWITCH_NO_BOOL(ElemT, { Dst.elem<T>(I) = static_cast<T>(Result); }); } @@ -3453,8 +3439,11 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call, return interp__builtin_select(S, OpPC, Call); case Builtin::BI__builtin_elementwise_fshl: + return interp__builtin_elementwise_triop(S, OpPC, Call, + llvm::APIntOps::fshl); case Builtin::BI__builtin_elementwise_fshr: - return interp__builtin_elementwise_fsh(S, OpPC, Call, BuiltinID); + return interp__builtin_elementwise_triop(S, OpPC, Call, + llvm::APIntOps::fshr); default: S.FFDiag(S.Current->getLocation(OpPC), _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits