-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[NFC][SimplifyCFG] Refactor passingValueIsAlwaysUndefined
to work on Use
#125519
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
Merged
dtcxzyw
merged 1 commit into
llvm:main
from
dtcxzyw:perf/simplifycfg-pass-val-undef-refactor
Feb 3, 2025
Merged
[NFC][SimplifyCFG] Refactor passingValueIsAlwaysUndefined
to work on Use
#125519
dtcxzyw
merged 1 commit into
llvm:main
from
dtcxzyw:perf/simplifycfg-pass-val-undef-refactor
Feb 3, 2025
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@llvm/pr-subscribers-llvm-transforms Author: Yingwei Zheng (dtcxzyw) ChangesAddress comment #125383 (comment) Full diff: https://github.com/llvm/llvm-project/pull/125519.diff 1 Files Affected:
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index 12dd49da279b9c..8743df8e9c8520 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -8175,8 +8175,8 @@ static bool passingValueIsAlwaysUndefined(Value *V, Instruction *I, bool PtrValu
if (C->isNullValue() || isa<UndefValue>(C)) {
// Only look at the first use we can handle, avoid hurting compile time with
// long uselists
- auto FindUse = llvm::find_if(I->users(), [](auto *U) {
- auto *Use = cast<Instruction>(U);
+ auto FindUse = llvm::find_if(I->uses(), [](auto &U) {
+ auto *Use = cast<Instruction>(U.getUser());
// Change this list when we want to add new instructions.
switch (Use->getOpcode()) {
default:
@@ -8199,26 +8199,28 @@ static bool passingValueIsAlwaysUndefined(Value *V, Instruction *I, bool PtrValu
return true;
}
});
- if (FindUse == I->user_end())
+ if (FindUse == I->use_end())
return false;
- auto *Use = cast<Instruction>(*FindUse);
- // Bail out if Use is not in the same BB as I or Use == I or Use comes
- // before I in the block. The latter two can be the case if Use is a
+ auto &Use = *FindUse;
+ auto *User = cast<Instruction>(Use.getUser());
+ // Bail out if User is not in the same BB as I or User == I or User comes
+ // before I in the block. The latter two can be the case if User is a
// PHI node.
- if (Use->getParent() != I->getParent() || Use == I || Use->comesBefore(I))
+ if (User->getParent() != I->getParent() || User == I ||
+ User->comesBefore(I))
return false;
// Now make sure that there are no instructions in between that can alter
// control flow (eg. calls)
auto InstrRange =
- make_range(std::next(I->getIterator()), Use->getIterator());
+ make_range(std::next(I->getIterator()), User->getIterator());
if (any_of(InstrRange, [](Instruction &I) {
return !isGuaranteedToTransferExecutionToSuccessor(&I);
}))
return false;
// Look through GEPs. A load from a GEP derived from NULL is still undefined
- if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Use))
+ if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(User))
if (GEP->getPointerOperand() == I) {
// The current base address is null, there are four cases to consider:
// getelementptr (TY, null, 0) -> null
@@ -8235,7 +8237,7 @@ static bool passingValueIsAlwaysUndefined(Value *V, Instruction *I, bool PtrValu
}
// Look through return.
- if (ReturnInst *Ret = dyn_cast<ReturnInst>(Use)) {
+ if (ReturnInst *Ret = dyn_cast<ReturnInst>(User)) {
bool HasNoUndefAttr =
Ret->getFunction()->hasRetAttribute(Attribute::NoUndef);
// Return undefined to a noundef return value is undefined.
@@ -8249,56 +8251,45 @@ static bool passingValueIsAlwaysUndefined(Value *V, Instruction *I, bool PtrValu
}
// Load from null is undefined.
- if (LoadInst *LI = dyn_cast<LoadInst>(Use))
+ if (LoadInst *LI = dyn_cast<LoadInst>(User))
if (!LI->isVolatile())
return !NullPointerIsDefined(LI->getFunction(),
LI->getPointerAddressSpace());
// Store to null is undefined.
- if (StoreInst *SI = dyn_cast<StoreInst>(Use))
+ if (StoreInst *SI = dyn_cast<StoreInst>(User))
if (!SI->isVolatile())
return (!NullPointerIsDefined(SI->getFunction(),
SI->getPointerAddressSpace())) &&
SI->getPointerOperand() == I;
// llvm.assume(false/undef) always triggers immediate UB.
- if (auto *Assume = dyn_cast<AssumeInst>(Use)) {
+ if (auto *Assume = dyn_cast<AssumeInst>(User)) {
// Ignore assume operand bundles.
if (I == Assume->getArgOperand(0))
return true;
}
- if (auto *CB = dyn_cast<CallBase>(Use)) {
+ if (auto *CB = dyn_cast<CallBase>(User)) {
if (C->isNullValue() && NullPointerIsDefined(CB->getFunction()))
return false;
// A call to null is undefined.
if (CB->getCalledOperand() == I)
return true;
- if (C->isNullValue()) {
- for (const llvm::Use &Arg : CB->args())
- if (Arg == I) {
- unsigned ArgIdx = CB->getArgOperandNo(&Arg);
- if (CB->isPassingUndefUB(ArgIdx) &&
- CB->paramHasAttr(ArgIdx, Attribute::NonNull)) {
- // Passing null to a nonnnull+noundef argument is undefined.
- return !PtrValueMayBeModified;
- }
- }
- } else if (isa<UndefValue>(C)) {
+ if (CB->isArgOperand(&Use)) {
+ unsigned ArgIdx = CB->getArgOperandNo(&Use);
+ // Passing null to a nonnnull+noundef argument is undefined.
+ if (C->isNullValue() && CB->isPassingUndefUB(ArgIdx) &&
+ CB->paramHasAttr(ArgIdx, Attribute::NonNull))
+ return !PtrValueMayBeModified;
// Passing undef to a noundef argument is undefined.
- for (const llvm::Use &Arg : CB->args())
- if (Arg == I) {
- unsigned ArgIdx = CB->getArgOperandNo(&Arg);
- if (CB->isPassingUndefUB(ArgIdx)) {
- // Passing undef to a noundef argument is undefined.
- return true;
- }
- }
+ if (isa<UndefValue>(C) && CB->isPassingUndefUB(ArgIdx))
+ return true;
}
}
// Div/Rem by zero is immediate UB
- if (match(Use, m_BinOp(m_Value(), m_Specific(I))) && Use->isIntDivRem())
+ if (match(User, m_BinOp(m_Value(), m_Specific(I))) && User->isIntDivRem())
return true;
}
return false;
|
nikic
approved these changes
Feb 3, 2025
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.
LGTM
Icohedron
pushed a commit
to Icohedron/llvm-project
that referenced
this pull request
Feb 11, 2025
…n `Use` (llvm#125519) Address comment llvm#125383 (comment)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Address comment #125383 (comment)