@@ -11597,6 +11597,38 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) {
1159711597 if (!IsConstantEvaluatedBuiltinCall(E))
1159811598 return ExprEvaluatorBaseTy::VisitCallExpr(E);
1159911599
11600+ auto EvaluateBinOpExpr =
11601+ [&](llvm::function_ref<APInt(const APSInt &, const APSInt &)> Fn) {
11602+ APValue SourceLHS, SourceRHS;
11603+ if (!EvaluateAsRValue(Info, E->getArg(0), SourceLHS) ||
11604+ !EvaluateAsRValue(Info, E->getArg(1), SourceRHS))
11605+ return false;
11606+
11607+ auto *DestTy = E->getType()->castAs<VectorType>();
11608+ QualType DestEltTy = DestTy->getElementType();
11609+ bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
11610+ unsigned SourceLen = SourceLHS.getVectorLength();
11611+ SmallVector<APValue, 4> ResultElements;
11612+ ResultElements.reserve(SourceLen);
11613+
11614+ if (SourceRHS.isInt()) {
11615+ const APSInt &RHS = SourceRHS.getInt();
11616+ for (unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11617+ const APSInt &LHS = SourceLHS.getVectorElt(EltNum).getInt();
11618+ ResultElements.push_back(
11619+ APValue(APSInt(Fn(LHS, RHS), DestUnsigned)));
11620+ }
11621+ } else {
11622+ for (unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11623+ const APSInt &LHS = SourceLHS.getVectorElt(EltNum).getInt();
11624+ const APSInt &RHS = SourceRHS.getVectorElt(EltNum).getInt();
11625+ ResultElements.push_back(
11626+ APValue(APSInt(Fn(LHS, RHS), DestUnsigned)));
11627+ }
11628+ }
11629+ return Success(APValue(ResultElements.data(), SourceLen), E);
11630+ };
11631+
1160011632 switch (E->getBuiltinCallee()) {
1160111633 default:
1160211634 return false;
@@ -11653,27 +11685,30 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) {
1165311685 }
1165411686
1165511687 case Builtin::BI__builtin_elementwise_add_sat:
11688+ return EvaluateBinOpExpr([](const APSInt &LHS, const APSInt &RHS) {
11689+ return LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
11690+ });
11691+
1165611692 case Builtin::BI__builtin_elementwise_sub_sat:
11693+ return EvaluateBinOpExpr([](const APSInt &LHS, const APSInt &RHS) {
11694+ return LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
11695+ });
11696+
1165711697 case clang::X86::BI__builtin_ia32_pmulhuw128:
1165811698 case clang::X86::BI__builtin_ia32_pmulhuw256:
1165911699 case clang::X86::BI__builtin_ia32_pmulhuw512:
11700+ return EvaluateBinOpExpr(llvm::APIntOps::mulhu);
11701+
1166011702 case clang::X86::BI__builtin_ia32_pmulhw128:
1166111703 case clang::X86::BI__builtin_ia32_pmulhw256:
1166211704 case clang::X86::BI__builtin_ia32_pmulhw512:
11705+ return EvaluateBinOpExpr(llvm::APIntOps::mulhs);
11706+
1166311707 case clang::X86::BI__builtin_ia32_psllv2di:
1166411708 case clang::X86::BI__builtin_ia32_psllv4di:
1166511709 case clang::X86::BI__builtin_ia32_psllv4si:
1166611710 case clang::X86::BI__builtin_ia32_psllv8si:
1166711711 case clang::X86::BI__builtin_ia32_psllv16si:
11668- case clang::X86::BI__builtin_ia32_psrav4si:
11669- case clang::X86::BI__builtin_ia32_psrav8si:
11670- case clang::X86::BI__builtin_ia32_psrav16si:
11671- case clang::X86::BI__builtin_ia32_psrlv2di:
11672- case clang::X86::BI__builtin_ia32_psrlv4di:
11673- case clang::X86::BI__builtin_ia32_psrlv4si:
11674- case clang::X86::BI__builtin_ia32_psrlv8si:
11675- case clang::X86::BI__builtin_ia32_psrlv16si:
11676-
1167711712 case clang::X86::BI__builtin_ia32_psllwi128:
1167811713 case clang::X86::BI__builtin_ia32_pslldi128:
1167911714 case clang::X86::BI__builtin_ia32_psllqi128:
@@ -11683,17 +11718,16 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) {
1168311718 case clang::X86::BI__builtin_ia32_psllwi512:
1168411719 case clang::X86::BI__builtin_ia32_pslldi512:
1168511720 case clang::X86::BI__builtin_ia32_psllqi512:
11721+ return EvaluateBinOpExpr([](const APSInt &LHS, const APSInt &RHS) {
11722+ if (RHS.uge(LHS.getBitWidth())) {
11723+ return APInt::getZero(LHS.getBitWidth());
11724+ }
11725+ return LHS.shl(RHS.getZExtValue());
11726+ });
1168611727
11687- case clang::X86::BI__builtin_ia32_psrlwi128:
11688- case clang::X86::BI__builtin_ia32_psrldi128:
11689- case clang::X86::BI__builtin_ia32_psrlqi128:
11690- case clang::X86::BI__builtin_ia32_psrlwi256:
11691- case clang::X86::BI__builtin_ia32_psrldi256:
11692- case clang::X86::BI__builtin_ia32_psrlqi256:
11693- case clang::X86::BI__builtin_ia32_psrlwi512:
11694- case clang::X86::BI__builtin_ia32_psrldi512:
11695- case clang::X86::BI__builtin_ia32_psrlqi512:
11696-
11728+ case clang::X86::BI__builtin_ia32_psrav4si:
11729+ case clang::X86::BI__builtin_ia32_psrav8si:
11730+ case clang::X86::BI__builtin_ia32_psrav16si:
1169711731 case clang::X86::BI__builtin_ia32_psrawi128:
1169811732 case clang::X86::BI__builtin_ia32_psradi128:
1169911733 case clang::X86::BI__builtin_ia32_psraqi128:
@@ -11702,145 +11736,35 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) {
1170211736 case clang::X86::BI__builtin_ia32_psraqi256:
1170311737 case clang::X86::BI__builtin_ia32_psrawi512:
1170411738 case clang::X86::BI__builtin_ia32_psradi512:
11705- case clang::X86::BI__builtin_ia32_psraqi512: {
11706-
11707- APValue SourceLHS, SourceRHS;
11708- if (!EvaluateAsRValue(Info, E->getArg(0), SourceLHS) ||
11709- !EvaluateAsRValue(Info, E->getArg(1), SourceRHS))
11710- return false;
11711-
11712- QualType DestEltTy = E->getType()->castAs<VectorType>()->getElementType();
11713- bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
11714- unsigned SourceLen = SourceLHS.getVectorLength();
11715- SmallVector<APValue, 4> ResultElements;
11716- ResultElements.reserve(SourceLen);
11717-
11718- for (unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11719- APSInt LHS = SourceLHS.getVectorElt(EltNum).getInt();
11720-
11721- if (SourceRHS.isInt()) {
11722- const unsigned LaneBitWidth = LHS.getBitWidth();
11723- const unsigned ShiftAmount = SourceRHS.getInt().getZExtValue();
11724-
11725- switch (E->getBuiltinCallee()) {
11726- case clang::X86::BI__builtin_ia32_psllwi128:
11727- case clang::X86::BI__builtin_ia32_psllwi256:
11728- case clang::X86::BI__builtin_ia32_psllwi512:
11729- case clang::X86::BI__builtin_ia32_pslldi128:
11730- case clang::X86::BI__builtin_ia32_pslldi256:
11731- case clang::X86::BI__builtin_ia32_pslldi512:
11732- case clang::X86::BI__builtin_ia32_psllqi128:
11733- case clang::X86::BI__builtin_ia32_psllqi256:
11734- case clang::X86::BI__builtin_ia32_psllqi512:
11735- if (ShiftAmount >= LaneBitWidth) {
11736- ResultElements.push_back(
11737- APValue(APSInt(APInt::getZero(LaneBitWidth), DestUnsigned)));
11738- } else {
11739- ResultElements.push_back(
11740- APValue(APSInt(LHS.shl(ShiftAmount), DestUnsigned)));
11741- }
11742- break;
11743- case clang::X86::BI__builtin_ia32_psrlwi128:
11744- case clang::X86::BI__builtin_ia32_psrlwi256:
11745- case clang::X86::BI__builtin_ia32_psrlwi512:
11746- case clang::X86::BI__builtin_ia32_psrldi128:
11747- case clang::X86::BI__builtin_ia32_psrldi256:
11748- case clang::X86::BI__builtin_ia32_psrldi512:
11749- case clang::X86::BI__builtin_ia32_psrlqi128:
11750- case clang::X86::BI__builtin_ia32_psrlqi256:
11751- case clang::X86::BI__builtin_ia32_psrlqi512:
11752- if (ShiftAmount >= LaneBitWidth) {
11753- ResultElements.push_back(
11754- APValue(APSInt(APInt::getZero(LaneBitWidth), DestUnsigned)));
11755- } else {
11756- ResultElements.push_back(
11757- APValue(APSInt(LHS.lshr(ShiftAmount), DestUnsigned)));
11758- }
11759- break;
11760- case clang::X86::BI__builtin_ia32_psrawi128:
11761- case clang::X86::BI__builtin_ia32_psrawi256:
11762- case clang::X86::BI__builtin_ia32_psrawi512:
11763- case clang::X86::BI__builtin_ia32_psradi128:
11764- case clang::X86::BI__builtin_ia32_psradi256:
11765- case clang::X86::BI__builtin_ia32_psradi512:
11766- case clang::X86::BI__builtin_ia32_psraqi128:
11767- case clang::X86::BI__builtin_ia32_psraqi256:
11768- case clang::X86::BI__builtin_ia32_psraqi512:
11769- ResultElements.push_back(
11770- APValue(APSInt(LHS.ashr(std::min(ShiftAmount, LaneBitWidth - 1)),
11771- DestUnsigned)));
11772- break;
11773- default:
11774- llvm_unreachable("Unexpected builtin callee");
11775- }
11776- continue;
11739+ case clang::X86::BI__builtin_ia32_psraqi512:
11740+ return EvaluateBinOpExpr([](const APSInt &LHS, const APSInt &RHS) {
11741+ if (RHS.uge(LHS.getBitWidth())) {
11742+ return LHS.ashr(LHS.getBitWidth() - 1);
1177711743 }
11778- APSInt RHS = SourceRHS.getVectorElt(EltNum).getInt();
11779- switch (E->getBuiltinCallee()) {
11780- case Builtin::BI__builtin_elementwise_add_sat:
11781- ResultElements.push_back(APValue(
11782- APSInt(LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS),
11783- DestUnsigned)));
11784- break;
11785- case Builtin::BI__builtin_elementwise_sub_sat:
11786- ResultElements.push_back(APValue(
11787- APSInt(LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS),
11788- DestUnsigned)));
11789- break;
11790- case clang::X86::BI__builtin_ia32_pmulhuw128:
11791- case clang::X86::BI__builtin_ia32_pmulhuw256:
11792- case clang::X86::BI__builtin_ia32_pmulhuw512:
11793- ResultElements.push_back(APValue(APSInt(llvm::APIntOps::mulhu(LHS, RHS),
11794- /*isUnsigned=*/true)));
11795- break;
11796- case clang::X86::BI__builtin_ia32_pmulhw128:
11797- case clang::X86::BI__builtin_ia32_pmulhw256:
11798- case clang::X86::BI__builtin_ia32_pmulhw512:
11799- ResultElements.push_back(APValue(APSInt(llvm::APIntOps::mulhs(LHS, RHS),
11800- /*isUnsigned=*/false)));
11801- break;
11802- case clang::X86::BI__builtin_ia32_psllv2di:
11803- case clang::X86::BI__builtin_ia32_psllv4di:
11804- case clang::X86::BI__builtin_ia32_psllv4si:
11805- case clang::X86::BI__builtin_ia32_psllv8si:
11806- case clang::X86::BI__builtin_ia32_psllv16si:
11807- if (RHS.uge(RHS.getBitWidth())) {
11808- ResultElements.push_back(
11809- APValue(APSInt(APInt::getZero(RHS.getBitWidth()), DestUnsigned)));
11810- break;
11811- }
11812- ResultElements.push_back(
11813- APValue(APSInt(LHS.shl(RHS.getZExtValue()), DestUnsigned)));
11814- break;
11815- case clang::X86::BI__builtin_ia32_psrav4si:
11816- case clang::X86::BI__builtin_ia32_psrav8si:
11817- case clang::X86::BI__builtin_ia32_psrav16si:
11818- if (RHS.uge(RHS.getBitWidth())) {
11819- ResultElements.push_back(
11820- APValue(APSInt(LHS.ashr(RHS.getBitWidth() - 1), DestUnsigned)));
11821- break;
11822- }
11823- ResultElements.push_back(
11824- APValue(APSInt(LHS.ashr(RHS.getZExtValue()), DestUnsigned)));
11825- break;
11826- case clang::X86::BI__builtin_ia32_psrlv2di:
11827- case clang::X86::BI__builtin_ia32_psrlv4di:
11828- case clang::X86::BI__builtin_ia32_psrlv4si:
11829- case clang::X86::BI__builtin_ia32_psrlv8si:
11830- case clang::X86::BI__builtin_ia32_psrlv16si:
11831- if (RHS.uge(RHS.getBitWidth())) {
11832- ResultElements.push_back(
11833- APValue(APSInt(APInt::getZero(RHS.getBitWidth()), DestUnsigned)));
11834- break;
11835- }
11836- ResultElements.push_back(
11837- APValue(APSInt(LHS.lshr(RHS.getZExtValue()), DestUnsigned)));
11838- break;
11744+ return LHS.ashr(RHS.getZExtValue());
11745+ });
11746+
11747+ case clang::X86::BI__builtin_ia32_psrlv2di:
11748+ case clang::X86::BI__builtin_ia32_psrlv4di:
11749+ case clang::X86::BI__builtin_ia32_psrlv4si:
11750+ case clang::X86::BI__builtin_ia32_psrlv8si:
11751+ case clang::X86::BI__builtin_ia32_psrlv16si:
11752+ case clang::X86::BI__builtin_ia32_psrlwi128:
11753+ case clang::X86::BI__builtin_ia32_psrldi128:
11754+ case clang::X86::BI__builtin_ia32_psrlqi128:
11755+ case clang::X86::BI__builtin_ia32_psrlwi256:
11756+ case clang::X86::BI__builtin_ia32_psrldi256:
11757+ case clang::X86::BI__builtin_ia32_psrlqi256:
11758+ case clang::X86::BI__builtin_ia32_psrlwi512:
11759+ case clang::X86::BI__builtin_ia32_psrldi512:
11760+ case clang::X86::BI__builtin_ia32_psrlqi512:
11761+ return EvaluateBinOpExpr([](const APSInt &LHS, const APSInt &RHS) {
11762+ if (RHS.uge(LHS.getBitWidth())) {
11763+ return APInt::getZero(LHS.getBitWidth());
1183911764 }
11840- }
11765+ return LHS.lshr(RHS.getZExtValue());
11766+ });
1184111767
11842- return Success(APValue(ResultElements.data(), ResultElements.size()), E);
11843- }
1184411768 case clang::X86::BI__builtin_ia32_pmuldq128:
1184511769 case clang::X86::BI__builtin_ia32_pmuldq256:
1184611770 case clang::X86::BI__builtin_ia32_pmuldq512:
@@ -11878,6 +11802,7 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) {
1187811802
1187911803 return Success(APValue(ResultElements.data(), ResultElements.size()), E);
1188011804 }
11805+
1188111806 case clang::X86::BI__builtin_ia32_vprotbi:
1188211807 case clang::X86::BI__builtin_ia32_vprotdi:
1188311808 case clang::X86::BI__builtin_ia32_vprotqi:
@@ -11887,53 +11812,19 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) {
1188711812 case clang::X86::BI__builtin_ia32_prold512:
1188811813 case clang::X86::BI__builtin_ia32_prolq128:
1188911814 case clang::X86::BI__builtin_ia32_prolq256:
11890- case clang::X86::BI__builtin_ia32_prolq512: {
11891- APValue SourceLHS, SourceRHS;
11892- if (!EvaluateAsRValue(Info, E->getArg(0), SourceLHS) ||
11893- !EvaluateAsRValue(Info, E->getArg(1), SourceRHS))
11894- return false;
11895-
11896- QualType DestEltTy = E->getType()->castAs<VectorType>()->getElementType();
11897- bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
11898- unsigned SourceLen = SourceLHS.getVectorLength();
11899- SmallVector<APValue, 4> ResultElements;
11900- ResultElements.reserve(SourceLen);
11901-
11902- APSInt RHS = SourceRHS.getInt();
11903-
11904- for (unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11905- const APSInt &LHS = SourceLHS.getVectorElt(EltNum).getInt();
11906- ResultElements.push_back(APValue(APSInt(LHS.rotl(RHS), DestUnsigned)));
11907- }
11815+ case clang::X86::BI__builtin_ia32_prolq512:
11816+ return EvaluateBinOpExpr(
11817+ [](const APSInt &LHS, const APSInt &RHS) { return LHS.rotl(RHS); });
1190811818
11909- return Success(APValue(ResultElements.data(), ResultElements.size()), E);
11910- }
1191111819 case clang::X86::BI__builtin_ia32_prord128:
1191211820 case clang::X86::BI__builtin_ia32_prord256:
1191311821 case clang::X86::BI__builtin_ia32_prord512:
1191411822 case clang::X86::BI__builtin_ia32_prorq128:
1191511823 case clang::X86::BI__builtin_ia32_prorq256:
11916- case clang::X86::BI__builtin_ia32_prorq512: {
11917- APValue SourceLHS, SourceRHS;
11918- if (!EvaluateAsRValue(Info, E->getArg(0), SourceLHS) ||
11919- !EvaluateAsRValue(Info, E->getArg(1), SourceRHS))
11920- return false;
11824+ case clang::X86::BI__builtin_ia32_prorq512:
11825+ return EvaluateBinOpExpr(
11826+ [](const APSInt &LHS, const APSInt &RHS) { return LHS.rotr(RHS); });
1192111827
11922- QualType DestEltTy = E->getType()->castAs<VectorType>()->getElementType();
11923- bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
11924- unsigned SourceLen = SourceLHS.getVectorLength();
11925- SmallVector<APValue, 4> ResultElements;
11926- ResultElements.reserve(SourceLen);
11927-
11928- APSInt RHS = SourceRHS.getInt();
11929-
11930- for (unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11931- const APSInt &LHS = SourceLHS.getVectorElt(EltNum).getInt();
11932- ResultElements.push_back(APValue(APSInt(LHS.rotr(RHS), DestUnsigned)));
11933- }
11934-
11935- return Success(APValue(ResultElements.data(), ResultElements.size()), E);
11936- }
1193711828 case Builtin::BI__builtin_elementwise_max:
1193811829 case Builtin::BI__builtin_elementwise_min: {
1193911830 APValue SourceLHS, SourceRHS;
0 commit comments