Skip to content

Commit 84ba55d

Browse files
authored
[NFC][SimplifyCFG] Refactor passingValueIsAlwaysUndefined to work on Use (#125519)
Address comment #125383 (comment)
1 parent b7c8271 commit 84ba55d

File tree

1 file changed

+25
-34
lines changed

1 file changed

+25
-34
lines changed

llvm/lib/Transforms/Utils/SimplifyCFG.cpp

Lines changed: 25 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -8175,8 +8175,8 @@ static bool passingValueIsAlwaysUndefined(Value *V, Instruction *I, bool PtrValu
81758175
if (C->isNullValue() || isa<UndefValue>(C)) {
81768176
// Only look at the first use we can handle, avoid hurting compile time with
81778177
// long uselists
8178-
auto FindUse = llvm::find_if(I->users(), [](auto *U) {
8179-
auto *Use = cast<Instruction>(U);
8178+
auto FindUse = llvm::find_if(I->uses(), [](auto &U) {
8179+
auto *Use = cast<Instruction>(U.getUser());
81808180
// Change this list when we want to add new instructions.
81818181
switch (Use->getOpcode()) {
81828182
default:
@@ -8199,26 +8199,28 @@ static bool passingValueIsAlwaysUndefined(Value *V, Instruction *I, bool PtrValu
81998199
return true;
82008200
}
82018201
});
8202-
if (FindUse == I->user_end())
8202+
if (FindUse == I->use_end())
82038203
return false;
8204-
auto *Use = cast<Instruction>(*FindUse);
8205-
// Bail out if Use is not in the same BB as I or Use == I or Use comes
8206-
// before I in the block. The latter two can be the case if Use is a
8204+
auto &Use = *FindUse;
8205+
auto *User = cast<Instruction>(Use.getUser());
8206+
// Bail out if User is not in the same BB as I or User == I or User comes
8207+
// before I in the block. The latter two can be the case if User is a
82078208
// PHI node.
8208-
if (Use->getParent() != I->getParent() || Use == I || Use->comesBefore(I))
8209+
if (User->getParent() != I->getParent() || User == I ||
8210+
User->comesBefore(I))
82098211
return false;
82108212

82118213
// Now make sure that there are no instructions in between that can alter
82128214
// control flow (eg. calls)
82138215
auto InstrRange =
8214-
make_range(std::next(I->getIterator()), Use->getIterator());
8216+
make_range(std::next(I->getIterator()), User->getIterator());
82158217
if (any_of(InstrRange, [](Instruction &I) {
82168218
return !isGuaranteedToTransferExecutionToSuccessor(&I);
82178219
}))
82188220
return false;
82198221

82208222
// Look through GEPs. A load from a GEP derived from NULL is still undefined
8221-
if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Use))
8223+
if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(User))
82228224
if (GEP->getPointerOperand() == I) {
82238225
// The current base address is null, there are four cases to consider:
82248226
// getelementptr (TY, null, 0) -> null
@@ -8235,7 +8237,7 @@ static bool passingValueIsAlwaysUndefined(Value *V, Instruction *I, bool PtrValu
82358237
}
82368238

82378239
// Look through return.
8238-
if (ReturnInst *Ret = dyn_cast<ReturnInst>(Use)) {
8240+
if (ReturnInst *Ret = dyn_cast<ReturnInst>(User)) {
82398241
bool HasNoUndefAttr =
82408242
Ret->getFunction()->hasRetAttribute(Attribute::NoUndef);
82418243
// Return undefined to a noundef return value is undefined.
@@ -8249,56 +8251,45 @@ static bool passingValueIsAlwaysUndefined(Value *V, Instruction *I, bool PtrValu
82498251
}
82508252

82518253
// Load from null is undefined.
8252-
if (LoadInst *LI = dyn_cast<LoadInst>(Use))
8254+
if (LoadInst *LI = dyn_cast<LoadInst>(User))
82538255
if (!LI->isVolatile())
82548256
return !NullPointerIsDefined(LI->getFunction(),
82558257
LI->getPointerAddressSpace());
82568258

82578259
// Store to null is undefined.
8258-
if (StoreInst *SI = dyn_cast<StoreInst>(Use))
8260+
if (StoreInst *SI = dyn_cast<StoreInst>(User))
82598261
if (!SI->isVolatile())
82608262
return (!NullPointerIsDefined(SI->getFunction(),
82618263
SI->getPointerAddressSpace())) &&
82628264
SI->getPointerOperand() == I;
82638265

82648266
// llvm.assume(false/undef) always triggers immediate UB.
8265-
if (auto *Assume = dyn_cast<AssumeInst>(Use)) {
8267+
if (auto *Assume = dyn_cast<AssumeInst>(User)) {
82668268
// Ignore assume operand bundles.
82678269
if (I == Assume->getArgOperand(0))
82688270
return true;
82698271
}
82708272

8271-
if (auto *CB = dyn_cast<CallBase>(Use)) {
8273+
if (auto *CB = dyn_cast<CallBase>(User)) {
82728274
if (C->isNullValue() && NullPointerIsDefined(CB->getFunction()))
82738275
return false;
82748276
// A call to null is undefined.
82758277
if (CB->getCalledOperand() == I)
82768278
return true;
82778279

8278-
if (C->isNullValue()) {
8279-
for (const llvm::Use &Arg : CB->args())
8280-
if (Arg == I) {
8281-
unsigned ArgIdx = CB->getArgOperandNo(&Arg);
8282-
if (CB->isPassingUndefUB(ArgIdx) &&
8283-
CB->paramHasAttr(ArgIdx, Attribute::NonNull)) {
8284-
// Passing null to a nonnnull+noundef argument is undefined.
8285-
return !PtrValueMayBeModified;
8286-
}
8287-
}
8288-
} else if (isa<UndefValue>(C)) {
8280+
if (CB->isArgOperand(&Use)) {
8281+
unsigned ArgIdx = CB->getArgOperandNo(&Use);
8282+
// Passing null to a nonnnull+noundef argument is undefined.
8283+
if (C->isNullValue() && CB->isPassingUndefUB(ArgIdx) &&
8284+
CB->paramHasAttr(ArgIdx, Attribute::NonNull))
8285+
return !PtrValueMayBeModified;
82898286
// Passing undef to a noundef argument is undefined.
8290-
for (const llvm::Use &Arg : CB->args())
8291-
if (Arg == I) {
8292-
unsigned ArgIdx = CB->getArgOperandNo(&Arg);
8293-
if (CB->isPassingUndefUB(ArgIdx)) {
8294-
// Passing undef to a noundef argument is undefined.
8295-
return true;
8296-
}
8297-
}
8287+
if (isa<UndefValue>(C) && CB->isPassingUndefUB(ArgIdx))
8288+
return true;
82988289
}
82998290
}
83008291
// Div/Rem by zero is immediate UB
8301-
if (match(Use, m_BinOp(m_Value(), m_Specific(I))) && Use->isIntDivRem())
8292+
if (match(User, m_BinOp(m_Value(), m_Specific(I))) && User->isIntDivRem())
83028293
return true;
83038294
}
83048295
return false;

0 commit comments

Comments
 (0)