Skip to content

Commit 965b7c2

Browse files
authored
[clang][bytecode] Implement ia32_pmul* builtins (#154315)
1 parent ed0e531 commit 965b7c2

File tree

1 file changed

+51
-0
lines changed

1 file changed

+51
-0
lines changed

clang/lib/AST/ByteCode/InterpBuiltin.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2583,6 +2583,50 @@ static bool interp__builtin_elementwise_maxmin(InterpState &S, CodePtr OpPC,
25832583
return true;
25842584
}
25852585

2586+
static bool interp__builtin_ia32_pmul(InterpState &S, CodePtr OpPC,
2587+
const CallExpr *Call,
2588+
unsigned BuiltinID) {
2589+
assert(Call->getArg(0)->getType()->isVectorType() &&
2590+
Call->getArg(1)->getType()->isVectorType());
2591+
const Pointer &RHS = S.Stk.pop<Pointer>();
2592+
const Pointer &LHS = S.Stk.pop<Pointer>();
2593+
const Pointer &Dst = S.Stk.peek<Pointer>();
2594+
2595+
const auto *VT = Call->getArg(0)->getType()->castAs<VectorType>();
2596+
PrimType ElemT = *S.getContext().classify(VT->getElementType());
2597+
unsigned SourceLen = VT->getNumElements();
2598+
SmallVector<APValue, 4> ResultElements;
2599+
ResultElements.reserve(SourceLen / 2);
2600+
2601+
for (unsigned I = 0; I != SourceLen; I += 2) {
2602+
APSInt Elem1;
2603+
APSInt Elem2;
2604+
INT_TYPE_SWITCH_NO_BOOL(ElemT, {
2605+
Elem1 = LHS.elem<T>(I).toAPSInt();
2606+
Elem2 = RHS.elem<T>(I).toAPSInt();
2607+
});
2608+
2609+
APSInt Result;
2610+
switch (BuiltinID) {
2611+
case clang::X86::BI__builtin_ia32_pmuludq128:
2612+
case clang::X86::BI__builtin_ia32_pmuludq256:
2613+
case clang::X86::BI__builtin_ia32_pmuludq512:
2614+
Result = APSInt(llvm::APIntOps::muluExtended(Elem1, Elem2), true);
2615+
break;
2616+
case clang::X86::BI__builtin_ia32_pmuldq128:
2617+
case clang::X86::BI__builtin_ia32_pmuldq256:
2618+
case clang::X86::BI__builtin_ia32_pmuldq512:
2619+
Result = APSInt(llvm::APIntOps::mulsExtended(Elem1, Elem2), false);
2620+
break;
2621+
}
2622+
INT_TYPE_SWITCH_NO_BOOL(ElemT,
2623+
{ Dst.elem<T>(I) = static_cast<T>(Result); });
2624+
}
2625+
2626+
Dst.initializeAllElements();
2627+
return true;
2628+
}
2629+
25862630
bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
25872631
uint32_t BuiltinID) {
25882632
if (!S.getASTContext().BuiltinInfo.isConstantEvaluated(BuiltinID))
@@ -3003,6 +3047,13 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
30033047
case Builtin::BI__builtin_elementwise_min:
30043048
return interp__builtin_elementwise_maxmin(S, OpPC, Call, BuiltinID);
30053049

3050+
case clang::X86::BI__builtin_ia32_pmuldq128:
3051+
case clang::X86::BI__builtin_ia32_pmuldq256:
3052+
case clang::X86::BI__builtin_ia32_pmuldq512:
3053+
case clang::X86::BI__builtin_ia32_pmuludq128:
3054+
case clang::X86::BI__builtin_ia32_pmuludq256:
3055+
return interp__builtin_ia32_pmul(S, OpPC, Call, BuiltinID);
3056+
30063057
default:
30073058
S.FFDiag(S.Current->getLocation(OpPC),
30083059
diag::note_invalid_subexpr_in_const_expr)

0 commit comments

Comments
 (0)