@@ -2829,9 +2829,10 @@ static bool interp__builtin_select(InterpState &S, CodePtr OpPC,
28292829 return true ;
28302830}
28312831
2832- static bool interp__builtin_elementwise_fsh (InterpState &S, CodePtr OpPC,
2833- const CallExpr *Call,
2834- unsigned BuiltinID) {
2832+ static bool interp__builtin_elementwise_triop (
2833+ InterpState &S, CodePtr OpPC, const CallExpr *Call, unsigned BuiltinID,
2834+ llvm::function_ref<APInt(const APSInt &, const APSInt &, const APSInt &)>
2835+ Fn) {
28352836 assert (Call->getNumArgs () == 3 );
28362837
28372838 QualType Arg0Type = Call->getArg (0 )->getType ();
@@ -2840,17 +2841,10 @@ static bool interp__builtin_elementwise_fsh(InterpState &S, CodePtr OpPC,
28402841
28412842 // Non-vector integer types.
28422843 if (!Arg0Type->isVectorType ()) {
2843- const APSInt &Shift =
2844- popToAPSInt (S.Stk , *S.getContext ().classify (Arg2Type));
2845- const APSInt &Lo = popToAPSInt (S.Stk , *S.getContext ().classify (Arg1Type));
2846- const APSInt &Hi = popToAPSInt (S.Stk , *S.getContext ().classify (Arg0Type));
2847- APSInt Result;
2848- if (BuiltinID == Builtin::BI__builtin_elementwise_fshl)
2849- Result = APSInt (llvm::APIntOps::fshl (Hi, Lo, Shift), Hi.isUnsigned ());
2850- else if (BuiltinID == Builtin::BI__builtin_elementwise_fshr)
2851- Result = APSInt (llvm::APIntOps::fshr (Hi, Lo, Shift), Hi.isUnsigned ());
2852- else
2853- llvm_unreachable (" Wrong builtin ID" );
2844+ const APSInt &Op2 = popToAPSInt (S.Stk , *S.getContext ().classify (Arg2Type));
2845+ const APSInt &Op1 = popToAPSInt (S.Stk , *S.getContext ().classify (Arg1Type));
2846+ const APSInt &Op0 = popToAPSInt (S.Stk , *S.getContext ().classify (Arg0Type));
2847+ APSInt Result = APSInt (Fn (Op0, Op1, Op2), Op0.isUnsigned ());
28542848 pushInteger (S, Result, Call->getType ());
28552849 return true ;
28562850 }
@@ -2860,26 +2854,18 @@ static bool interp__builtin_elementwise_fsh(InterpState &S, CodePtr OpPC,
28602854 const PrimType &ElemT = *S.getContext ().classify (VecT->getElementType ());
28612855 unsigned NumElems = VecT->getNumElements ();
28622856
2863- const Pointer &VecShift = S.Stk .pop <Pointer>();
2864- const Pointer &VecLo = S.Stk .pop <Pointer>();
2865- const Pointer &VecHi = S.Stk .pop <Pointer>();
2857+ const Pointer &Op2 = S.Stk .pop <Pointer>();
2858+ const Pointer &Op1 = S.Stk .pop <Pointer>();
2859+ const Pointer &Op0 = S.Stk .pop <Pointer>();
28662860 const Pointer &Dst = S.Stk .peek <Pointer>();
28672861 for (unsigned I = 0 ; I != NumElems; ++I) {
2868- APSInt Hi;
2869- APSInt Lo;
2870- APSInt Shift;
2862+ APSInt Val0, Val1, Val2;
28712863 INT_TYPE_SWITCH_NO_BOOL (ElemT, {
2872- Hi = VecHi .elem <T>(I).toAPSInt ();
2873- Lo = VecLo .elem <T>(I).toAPSInt ();
2874- Shift = VecShift .elem <T>(I).toAPSInt ();
2864+ Val0 = Op0 .elem <T>(I).toAPSInt ();
2865+ Val1 = Op1 .elem <T>(I).toAPSInt ();
2866+ Val2 = Op2 .elem <T>(I).toAPSInt ();
28752867 });
2876- APSInt Result;
2877- if (BuiltinID == Builtin::BI__builtin_elementwise_fshl)
2878- Result = APSInt (llvm::APIntOps::fshl (Hi, Lo, Shift), Hi.isUnsigned ());
2879- else if (BuiltinID == Builtin::BI__builtin_elementwise_fshr)
2880- Result = APSInt (llvm::APIntOps::fshr (Hi, Lo, Shift), Hi.isUnsigned ());
2881- else
2882- llvm_unreachable (" Wrong builtin ID" );
2868+ APSInt Result = APSInt (Fn (Val0, Val1, Val2), Val0.isUnsigned ());
28832869 INT_TYPE_SWITCH_NO_BOOL (ElemT,
28842870 { Dst.elem <T>(I) = static_cast <T>(Result); });
28852871 }
@@ -3453,8 +3439,11 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
34533439 return interp__builtin_select (S, OpPC, Call);
34543440
34553441 case Builtin::BI__builtin_elementwise_fshl:
3442+ return interp__builtin_elementwise_triop (S, OpPC, Call, BuiltinID,
3443+ llvm::APIntOps::fshl);
34563444 case Builtin::BI__builtin_elementwise_fshr:
3457- return interp__builtin_elementwise_fsh (S, OpPC, Call, BuiltinID);
3445+ return interp__builtin_elementwise_triop (S, OpPC, Call, BuiltinID,
3446+ llvm::APIntOps::fshr);
34583447
34593448 default :
34603449 S.FFDiag (S.Current ->getLocation (OpPC),
0 commit comments