-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[SCCP] Infer return attributes in SCCP as well #106732
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 |
---|---|---|
|
@@ -354,6 +354,34 @@ bool SCCPSolver::removeNonFeasibleEdges(BasicBlock *BB, DomTreeUpdater &DTU, | |
return true; | ||
} | ||
|
||
void SCCPSolver::inferReturnAttributes() const { | ||
for (const auto &[F, ReturnValue] : getTrackedRetVals()) { | ||
|
||
// If there is a known constant range for the return value, add range | ||
// attribute to the return value. | ||
if (ReturnValue.isConstantRange() && | ||
!ReturnValue.getConstantRange().isSingleElement()) { | ||
// Do not add range metadata if the return value may include undef. | ||
if (ReturnValue.isConstantRangeIncludingUndef()) | ||
continue; | ||
|
||
// Take the intersection of the existing attribute and the inferred range. | ||
ConstantRange CR = ReturnValue.getConstantRange(); | ||
if (F->hasRetAttribute(Attribute::Range)) | ||
CR = CR.intersectWith(F->getRetAttribute(Attribute::Range).getRange()); | ||
F->addRangeRetAttr(CR); | ||
continue; | ||
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. Do we ever want to infer 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. nonnull applies only to pointers, while range applies only to (vectors of) integers, so they can not apply at the same time. |
||
} | ||
// Infer nonnull return attribute. | ||
if (F->getReturnType()->isPointerTy() && ReturnValue.isNotConstant() && | ||
ReturnValue.getNotConstant()->isNullValue() && | ||
!F->hasRetAttribute(Attribute::NonNull)) { | ||
F->addRetAttr(Attribute::NonNull); | ||
continue; | ||
} | ||
} | ||
} | ||
|
||
/// Helper class for SCCPSolver. This implements the instruction visitor and | ||
/// holds all the state. | ||
class SCCPInstVisitor : public InstVisitor<SCCPInstVisitor> { | ||
|
@@ -2168,7 +2196,7 @@ const ValueLatticeElement &SCCPSolver::getLatticeValueFor(Value *V) const { | |
} | ||
|
||
const MapVector<Function *, ValueLatticeElement> & | ||
SCCPSolver::getTrackedRetVals() { | ||
SCCPSolver::getTrackedRetVals() const { | ||
return Visitor->getTrackedRetVals(); | ||
} | ||
|
||
|
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.
I don't see any tests for this.
Is the reason for this to avoid creating UB where we where just propagating poison beforehand? If so, do you also need
noundef
for propagatingnonnull
?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.
This is pre-existing code moved to a different place.
ConstantRangeIncludingUndef
meansConstantRange|undef
. In theundef
case any value may be picked, so the result is a full range.