Skip to content

Commit 4fa0ff0

Browse files
committed
[Clang][bytecode] Add interp__builtin_elementwise_triop to handle general 3-operand integer intrinsics
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
1 parent 69d0c3e commit 4fa0ff0

File tree

1 file changed

+20
-31
lines changed

1 file changed

+20
-31
lines changed

clang/lib/AST/ByteCode/InterpBuiltin.cpp

Lines changed: 20 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)