diff options
Diffstat (limited to 'clang/lib/AST/ExprConstant.cpp')
-rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 618e163..35a866e 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -11778,6 +11778,54 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) { case clang::X86::BI__builtin_ia32_pavgw512: return EvaluateBinOpExpr(llvm::APIntOps::avgCeilU); + case clang::X86::BI__builtin_ia32_pmaddubsw128: + case clang::X86::BI__builtin_ia32_pmaddubsw256: + case clang::X86::BI__builtin_ia32_pmaddubsw512: + case clang::X86::BI__builtin_ia32_pmaddwd128: + case clang::X86::BI__builtin_ia32_pmaddwd256: + case clang::X86::BI__builtin_ia32_pmaddwd512: { + APValue SourceLHS, SourceRHS; + if (!EvaluateAsRValue(Info, E->getArg(0), SourceLHS) || + !EvaluateAsRValue(Info, E->getArg(1), SourceRHS)) + return false; + + auto *DestTy = E->getType()->castAs<VectorType>(); + QualType DestEltTy = DestTy->getElementType(); + unsigned SourceLen = SourceLHS.getVectorLength(); + bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType(); + SmallVector<APValue, 4> ResultElements; + ResultElements.reserve(SourceLen / 2); + + for (unsigned EltNum = 0; EltNum < SourceLen; EltNum += 2) { + const APSInt &LoLHS = SourceLHS.getVectorElt(EltNum).getInt(); + const APSInt &HiLHS = SourceLHS.getVectorElt(EltNum + 1).getInt(); + const APSInt &LoRHS = SourceRHS.getVectorElt(EltNum).getInt(); + const APSInt &HiRHS = SourceRHS.getVectorElt(EltNum + 1).getInt(); + unsigned BitWidth = 2 * LoLHS.getBitWidth(); + + switch (E->getBuiltinCallee()) { + case clang::X86::BI__builtin_ia32_pmaddubsw128: + case clang::X86::BI__builtin_ia32_pmaddubsw256: + case clang::X86::BI__builtin_ia32_pmaddubsw512: + ResultElements.push_back(APValue( + APSInt((LoLHS.zext(BitWidth) * LoRHS.sext(BitWidth)) + .sadd_sat((HiLHS.zext(BitWidth) * HiRHS.sext(BitWidth))), + DestUnsigned))); + break; + case clang::X86::BI__builtin_ia32_pmaddwd128: + case clang::X86::BI__builtin_ia32_pmaddwd256: + case clang::X86::BI__builtin_ia32_pmaddwd512: + ResultElements.push_back( + APValue(APSInt((LoLHS.sext(BitWidth) * LoRHS.sext(BitWidth)) + + (HiLHS.sext(BitWidth) * HiRHS.sext(BitWidth)), + DestUnsigned))); + break; + } + } + + return Success(APValue(ResultElements.data(), ResultElements.size()), E); + } + case clang::X86::BI__builtin_ia32_pmulhuw128: case clang::X86::BI__builtin_ia32_pmulhuw256: case clang::X86::BI__builtin_ia32_pmulhuw512: |