-
Notifications
You must be signed in to change notification settings - Fork 15.6k
[clang] constexpr integer __builtin_elementwise_{max,min}
#152294
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11654,6 +11654,41 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) { | |
|
|
||
| return Success(APValue(ResultElements.data(), ResultElements.size()), E); | ||
| } | ||
| case Builtin::BI__builtin_elementwise_max: | ||
| case Builtin::BI__builtin_elementwise_min: { | ||
| APValue SourceLHS, SourceRHS; | ||
| if (!EvaluateAsRValue(Info, E->getArg(0), SourceLHS) || | ||
| !EvaluateAsRValue(Info, E->getArg(1), SourceRHS)) | ||
| return false; | ||
|
|
||
| QualType DestEltTy = E->getType()->castAs<VectorType>()->getElementType(); | ||
|
|
||
| if (!DestEltTy->isIntegerType()) | ||
| return false; | ||
|
|
||
| unsigned SourceLen = SourceLHS.getVectorLength(); | ||
| SmallVector<APValue, 4> ResultElements; | ||
| ResultElements.reserve(SourceLen); | ||
|
|
||
| for (unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) { | ||
| APSInt LHS = SourceLHS.getVectorElt(EltNum).getInt(); | ||
| APSInt RHS = SourceRHS.getVectorElt(EltNum).getInt(); | ||
| switch (E->getBuiltinCallee()) { | ||
| case Builtin::BI__builtin_elementwise_max: | ||
| ResultElements.push_back( | ||
| APValue(APSInt(std::max(LHS, RHS), | ||
| DestEltTy->isUnsignedIntegerOrEnumerationType()))); | ||
| break; | ||
| case Builtin::BI__builtin_elementwise_min: | ||
| ResultElements.push_back( | ||
| APValue(APSInt(std::min(LHS, RHS), | ||
| DestEltTy->isUnsignedIntegerOrEnumerationType()))); | ||
| break; | ||
| } | ||
| } | ||
|
|
||
| return Success(APValue(ResultElements.data(), ResultElements.size()), E); | ||
| } | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -13548,7 +13583,24 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, | |
| APInt Result = LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS); | ||
| return Success(APSInt(Result, !LHS.isSigned()), E); | ||
| } | ||
| case Builtin::BI__builtin_elementwise_max: { | ||
| APSInt LHS, RHS; | ||
| if (!EvaluateInteger(E->getArg(0), LHS, Info) || | ||
| !EvaluateInteger(E->getArg(1), RHS, Info)) | ||
| return false; | ||
|
|
||
| APInt Result = std::max(LHS, RHS); | ||
| return Success(APSInt(Result, !LHS.isSigned()), E); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't whether it is signed or not going to depend on which one is max? Same for below but min.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Those functions don't accept inputs of different types.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ahh ok, so then we should have tests showing that this case is rejected and does not work, do we have those someplace else? |
||
| } | ||
| case Builtin::BI__builtin_elementwise_min: { | ||
| APSInt LHS, RHS; | ||
| if (!EvaluateInteger(E->getArg(0), LHS, Info) || | ||
| !EvaluateInteger(E->getArg(1), RHS, Info)) | ||
| return false; | ||
|
|
||
| APInt Result = std::min(LHS, RHS); | ||
| return Success(APSInt(Result, !LHS.isSigned()), E); | ||
| } | ||
| case Builtin::BIstrlen: | ||
| case Builtin::BIwcslen: | ||
| // A call to strlen is not a constant expression. | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The cases for max and min look pretty much the same as for add_sat and sub_sat just above. Perhaps it makes sense to simply extend
switchon line 11642?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add/sub_sat only works for integer, but min/max will support floating point numbers.