Skip to content

Commit b9c7000

Browse files
committed
Modified InterpBuiltin.cpp and ExprConstant.cpp
1 parent 98759c5 commit b9c7000

File tree

2 files changed

+70
-14
lines changed

2 files changed

+70
-14
lines changed

clang/lib/AST/ByteCode/InterpBuiltin.cpp

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2579,10 +2579,30 @@ static bool interp__builtin_elementwise_maxmin(InterpState &S, CodePtr OpPC,
25792579
return true;
25802580
}
25812581

2582-
static bool interp__builtin_ia32_pmadd(InterpState &S, CodePtr OpPC,
2583-
const CallExpr *Call,
2584-
unsigned BuiltinID) {
2585-
return true; // TODO: Implement the builtin.
2582+
static bool interp__builtin_ia32_pmadd(
2583+
InterpState &S, CodePtr OpPC, const CallExpr *Call,
2584+
llvm::function_ref<APInt(const APSInt &, const APSInt &)> Fn) {
2585+
assert(Call->getArg(0)->getType()->isVectorType() &&
2586+
Call->getArg(1)->getType()->isVectorType());
2587+
const Pointer &RHS = S.Stk.pop<Pointer>();
2588+
const Pointer &LHS = S.Stk.pop<Pointer>();
2589+
const Pointer &Dst = S.Stk.peek<Pointer>();
2590+
2591+
const auto *VT = Call->getArg(0)->getType()->castAs<VectorType>();
2592+
PrimType ElemT = *S.getContext().classify(VT->getElementType());
2593+
unsigned NumElems = VT->getNumElements();
2594+
bool DestUnsigned = Call->getType()->isUnsignedIntegerOrEnumerationType();
2595+
2596+
for (unsigned I = 0; I != NumElems; ++I) {
2597+
INT_TYPE_SWITCH_NO_BOOL(ElemT, {
2598+
APSInt Elem1 = LHS.elem<T>(I).toAPSInt();
2599+
APSInt Elem2 = RHS.elem<T>(I).toAPSInt();
2600+
Dst.elem<T>(I) = static_cast<T>(APSInt(Fn(Elem1, Elem2), DestUnsigned));
2601+
});
2602+
}
2603+
2604+
Dst.initializeAllElements();
2605+
return true;
25862606
}
25872607

25882608
static bool interp__builtin_ia32_pmul(InterpState &S, CodePtr OpPC,
@@ -3457,12 +3477,20 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
34573477
case clang::X86::BI__builtin_ia32_pmaddubsw128:
34583478
case clang::X86::BI__builtin_ia32_pmaddubsw256:
34593479
case clang::X86::BI__builtin_ia32_pmaddubsw512:
3460-
return true; // TODO: Use interp__builtin_i32_pmadd.
3480+
return interp__builtin_ia32_pmadd(S, OpPC, Call,
3481+
[](const APSInt &LoLHS, const APSInt &HiLHS, const APSInt &LoRHS, const APSInt &HiRHS) {
3482+
unsigned BitWidth = 2 * LHS.getBitWidth();
3483+
return (LoLHS.zext(BitWidth) * LoRHS.sext(BitWidth)).sadd_sat((HiLHS.zext(BitWidth) * HiRHS.sext(BitWidth)));
3484+
});
34613485

34623486
case clang::X86::BI__builtin_ia32_pmaddwd128:
34633487
case clang::X86::BI__builtin_ia32_pmaddwd256:
34643488
case clang::X86::BI__builtin_ia32_pmaddwd512:
3465-
return true; // TODO: Use interp__builtin_i32_pmadd.
3489+
return interp__builtin_ia32_pmadd(S, OpPC, Call,
3490+
[](const APSInt &LoLHS, const APSInt &HiLHS, const APSInt &LoRHS, const APSInt &HiRHS) {
3491+
unsigned BitWidth = 2 * LHS.getBitWidth();
3492+
return (LoLHS.sext(BitWidth) * LoRHS.sext(BitWidth)) + (HiLHS.sext(BitWidth) * HiRHS.sext(BitWidth));
3493+
});
34663494

34673495
case clang::X86::BI__builtin_ia32_pmulhuw128:
34683496
case clang::X86::BI__builtin_ia32_pmulhuw256:

clang/lib/AST/ExprConstant.cpp

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11779,18 +11779,46 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) {
1177911779
return EvaluateBinOpExpr(llvm::APIntOps::avgCeilU);
1178011780

1178111781
case clang::X86::BI__builtin_ia32_pmaddubsw128:
11782-
case clang::X86::BI__builtin_ia32_pmaddwd128:
1178311782
case clang::X86::BI__builtin_ia32_pmaddubsw256:
11784-
case clang::X86::BI__builtin_ia32_pmaddwd256:
1178511783
case clang::X86::BI__builtin_ia32_pmaddubsw512:
11786-
case clang::X86::BI__builtin_ia32_pmaddwd512:
11787-
return true; // TODO: Handle __builtin_ia32_pmaddub
11788-
1178911784
case clang::X86::BI__builtin_ia32_pmaddwd128:
1179011785
case clang::X86::BI__builtin_ia32_pmaddwd256:
11791-
case clang::X86::BI__builtin_ia32_pmaddwd512:
11792-
return true; // TODO: Handle __builtin_ia32_pmadd
11793-
});
11786+
case clang::X86::BI__builtin_ia32_pmaddwd512: {
11787+
APValue SourceLHS, SourceRHS;
11788+
if (!EvaluateAsRValue(Info, E->getArg(0), SourceLHS) ||
11789+
!EvaluateAsRValue(Info, E->getArg(1), SourceRHS))
11790+
return false;
11791+
11792+
unsigned SourceLen = SourceLHS.getVectorLength();
11793+
bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
11794+
SmallVector<APValue, 4> ResultElements;
11795+
ResultElements.reserve(SourceLen / 2);
11796+
11797+
for (unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11798+
const APSInt &LoLHS = SourceLHS.getVectorElt(EltNum).getInt();
11799+
const APSInt &LoRHS = SourceRHS.getVectorElt(EltNum).getInt();
11800+
const APSInt &HiLHS = SourceLHS.getVectorElt(EltNum).getInt();
11801+
const APSInt &HiRHS = SourceRHS.getVectorElt(EltNum).getInt();
11802+
unsigned BitWidth = 2 * LHS.getBitWidth();
11803+
11804+
switch (E->getBuiltinCallee()) {
11805+
case clang::X86::BI__builtin_ia32_pmaddubsw128:
11806+
case clang::X86::BI__builtin_ia32_pmaddubsw256:
11807+
case clang::X86::BI__builtin_ia32_pmaddubsw512:
11808+
ResultElements.push_back(
11809+
APValue(APSInt((LoLHS.zext(BitWidth) * LoRHS.sext(BitWidth)).sadd_sat((HiLHS.zext(BitWidth) * HiRHS.sext(BitWidth)))), DestUnsigned));
11810+
break;
11811+
case clang::X86::BI__builtin_ia32_pmaddwd128:
11812+
case clang::X86::BI__builtin_ia32_pmaddwd256:
11813+
case clang::X86::BI__builtin_ia32_pmaddwd512:
11814+
ResultElements.push_back(
11815+
APValue(APSInt((LoLHS.sext(BitWidth) * LoRHS.sext(BitWidth)) + (HiLHS.sext(BitWidth) * HiRHS.sext(BitWidth))), DestUnsigned));
11816+
break;
11817+
}
11818+
}
11819+
11820+
return Success(APValue(ResultElements.data(), ResultElements.size()), E);
11821+
}
1179411822

1179511823
case clang::X86::BI__builtin_ia32_pmulhuw128:
1179611824
case clang::X86::BI__builtin_ia32_pmulhuw256:

0 commit comments

Comments
 (0)