[llvm] f364b2e - [LLVM] Don't peek through bitcast on pointers and gep with zero indices. NFC. (#102889)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 13 07:38:53 PDT 2024
Author: Yingwei Zheng
Date: 2024-08-13T22:38:50+08:00
New Revision: f364b2ee22209e4072c39a153b3385806974f8b0
URL: https://github.com/llvm/llvm-project/commit/f364b2ee22209e4072c39a153b3385806974f8b0
DIFF: https://github.com/llvm/llvm-project/commit/f364b2ee22209e4072c39a153b3385806974f8b0.diff
LOG: [LLVM] Don't peek through bitcast on pointers and gep with zero indices. NFC. (#102889)
Since we are using opaque pointers now, we don't need to peek through
bitcast on pointers and gep with zero indices.
Added:
Modified:
llvm/lib/Analysis/MemoryDependenceAnalysis.cpp
llvm/lib/Analysis/MemorySSA.cpp
llvm/lib/Transforms/IPO/ArgumentPromotion.cpp
llvm/lib/Transforms/IPO/AttributorAttributes.cpp
llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
llvm/lib/Transforms/IPO/GlobalOpt.cpp
llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
llvm/lib/Transforms/Utils/GlobalStatus.cpp
llvm/lib/Transforms/Utils/SimplifyCFG.cpp
llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp b/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp
index 9f7baa983f1229..79504ca7b73c8f 100644
--- a/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp
+++ b/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp
@@ -291,10 +291,6 @@ MemoryDependenceResults::getInvariantGroupPointerDependency(LoadInst *LI,
if (isa<GlobalValue>(LoadOperand))
return MemDepResult::getUnknown();
- // Queue to process all pointers that are equivalent to load operand.
- SmallVector<const Value *, 8> LoadOperandsQueue;
- LoadOperandsQueue.push_back(LoadOperand);
-
Instruction *ClosestDependency = nullptr;
// Order of instructions in uses list is unpredictible. In order to always
// get the same result, we will look for the closest dominance.
@@ -305,44 +301,19 @@ MemoryDependenceResults::getInvariantGroupPointerDependency(LoadInst *LI,
return Best;
};
- // FIXME: This loop is O(N^2) because dominates can be O(n) and in worst case
- // we will see all the instructions. This should be fixed in MSSA.
- while (!LoadOperandsQueue.empty()) {
- const Value *Ptr = LoadOperandsQueue.pop_back_val();
- assert(Ptr && !isa<GlobalValue>(Ptr) &&
- "Null or GlobalValue should not be inserted");
-
- for (const Use &Us : Ptr->uses()) {
- auto *U = dyn_cast<Instruction>(Us.getUser());
- if (!U || U == LI || !DT.dominates(U, LI))
- continue;
-
- // Bitcast or gep with zeros are using Ptr. Add to queue to check it's
- // users. U = bitcast Ptr
- if (isa<BitCastInst>(U)) {
- LoadOperandsQueue.push_back(U);
- continue;
- }
- // Gep with zeros is equivalent to bitcast.
- // FIXME: we are not sure if some bitcast should be canonicalized to gep 0
- // or gep 0 to bitcast because of SROA, so there are 2 forms. When
- // typeless pointers will be ready then both cases will be gone
- // (and this BFS also won't be needed).
- if (auto *GEP = dyn_cast<GetElementPtrInst>(U))
- if (GEP->hasAllZeroIndices()) {
- LoadOperandsQueue.push_back(U);
- continue;
- }
+ for (const Use &Us : LoadOperand->uses()) {
+ auto *U = dyn_cast<Instruction>(Us.getUser());
+ if (!U || U == LI || !DT.dominates(U, LI))
+ continue;
- // If we hit load/store with the same invariant.group metadata (and the
- // same pointer operand) we can assume that value pointed by pointer
- // operand didn't change.
- if ((isa<LoadInst>(U) ||
- (isa<StoreInst>(U) &&
- cast<StoreInst>(U)->getPointerOperand() == Ptr)) &&
- U->hasMetadata(LLVMContext::MD_invariant_group))
- ClosestDependency = GetClosestDependency(ClosestDependency, U);
- }
+ // If we hit load/store with the same invariant.group metadata (and the
+ // same pointer operand) we can assume that value pointed by pointer
+ // operand didn't change.
+ if ((isa<LoadInst>(U) ||
+ (isa<StoreInst>(U) &&
+ cast<StoreInst>(U)->getPointerOperand() == LoadOperand)) &&
+ U->hasMetadata(LLVMContext::MD_invariant_group))
+ ClosestDependency = GetClosestDependency(ClosestDependency, U);
}
if (!ClosestDependency)
diff --git a/llvm/lib/Analysis/MemorySSA.cpp b/llvm/lib/Analysis/MemorySSA.cpp
index 48ef73e59045e7..1583e0e31efc14 100644
--- a/llvm/lib/Analysis/MemorySSA.cpp
+++ b/llvm/lib/Analysis/MemorySSA.cpp
@@ -2507,45 +2507,22 @@ getInvariantGroupClobberingInstruction(Instruction &I, DominatorTree &DT) {
if (isa<Constant>(PointerOperand))
return nullptr;
- // Queue to process all pointers that are equivalent to load operand.
- SmallVector<const Value *, 8> PointerUsesQueue;
- PointerUsesQueue.push_back(PointerOperand);
-
const Instruction *MostDominatingInstruction = &I;
- // FIXME: This loop is O(n^2) because dominates can be O(n) and in worst case
- // we will see all the instructions. It may not matter in practice. If it
- // does, we will have to support MemorySSA construction and updates.
- while (!PointerUsesQueue.empty()) {
- const Value *Ptr = PointerUsesQueue.pop_back_val();
- assert(Ptr && !isa<GlobalValue>(Ptr) &&
- "Null or GlobalValue should not be inserted");
-
- for (const User *Us : Ptr->users()) {
- auto *U = dyn_cast<Instruction>(Us);
- if (!U || U == &I || !DT.dominates(U, MostDominatingInstruction))
- continue;
-
- // Add bitcasts and zero GEPs to queue.
- if (isa<BitCastInst>(U)) {
- PointerUsesQueue.push_back(U);
- continue;
- }
- if (auto *GEP = dyn_cast<GetElementPtrInst>(U)) {
- if (GEP->hasAllZeroIndices())
- PointerUsesQueue.push_back(U);
- continue;
- }
+ for (const User *Us : PointerOperand->users()) {
+ auto *U = dyn_cast<Instruction>(Us);
+ if (!U || U == &I || !DT.dominates(U, MostDominatingInstruction))
+ continue;
- // If we hit a load/store with an invariant.group metadata and the same
- // pointer operand, we can assume that value pointed to by the pointer
- // operand didn't change.
- if (U->hasMetadata(LLVMContext::MD_invariant_group) &&
- getLoadStorePointerOperand(U) == Ptr && !U->isVolatile()) {
- MostDominatingInstruction = U;
- }
+ // If we hit a load/store with an invariant.group metadata and the same
+ // pointer operand, we can assume that value pointed to by the pointer
+ // operand didn't change.
+ if (U->hasMetadata(LLVMContext::MD_invariant_group) &&
+ getLoadStorePointerOperand(U) == PointerOperand && !U->isVolatile()) {
+ MostDominatingInstruction = U;
}
}
+
return MostDominatingInstruction == &I ? nullptr : MostDominatingInstruction;
}
diff --git a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp
index 99ec50aa4775c8..452fff7898d0ea 100644
--- a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp
+++ b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp
@@ -371,7 +371,7 @@ doPromotion(Function *F, FunctionAnalysisManager &FAM,
append_range(Worklist, Arg.users());
while (!Worklist.empty()) {
Value *V = Worklist.pop_back_val();
- if (isa<BitCastInst>(V) || isa<GetElementPtrInst>(V)) {
+ if (isa<GetElementPtrInst>(V)) {
DeadInsts.push_back(cast<Instruction>(V));
append_range(Worklist, V->users());
continue;
@@ -608,10 +608,6 @@ static bool findArgParts(Argument *Arg, const DataLayout &DL, AAResults &AAR,
while (!Worklist.empty()) {
const Use *U = Worklist.pop_back_val();
Value *V = U->getUser();
- if (isa<BitCastInst>(V)) {
- AppendUses(V);
- continue;
- }
if (auto *GEP = dyn_cast<GetElementPtrInst>(V)) {
if (!GEP->hasAllConstantIndices())
diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
index db5e94806e9a16..8ece5bbdfc77e1 100644
--- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
+++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
@@ -2327,8 +2327,8 @@ struct AANoFreeFloating : AANoFreeImpl {
DepClassTy::REQUIRED, IsKnown);
}
- if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) ||
- isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
+ if (isa<GetElementPtrInst>(UserI) || isa<PHINode>(UserI) ||
+ isa<SelectInst>(UserI)) {
Follow = true;
return true;
}
diff --git a/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp b/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
index 2d7b7355229eaf..548335d750e33d 100644
--- a/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
+++ b/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
@@ -481,11 +481,6 @@ Constant *FunctionSpecializer::getPromotableAlloca(AllocaInst *Alloca,
// the usage in the CallInst, which is what we check here.
if (User == Call)
continue;
- if (auto *Bitcast = dyn_cast<BitCastInst>(User)) {
- if (!Bitcast->hasOneUse() || *Bitcast->user_begin() != Call)
- return nullptr;
- continue;
- }
if (auto *Store = dyn_cast<StoreInst>(User)) {
// This is a duplicate store, bail out.
diff --git a/llvm/lib/Transforms/IPO/GlobalOpt.cpp b/llvm/lib/Transforms/IPO/GlobalOpt.cpp
index 5293a777496bc7..aae4926e027ff4 100644
--- a/llvm/lib/Transforms/IPO/GlobalOpt.cpp
+++ b/llvm/lib/Transforms/IPO/GlobalOpt.cpp
@@ -1050,11 +1050,6 @@ valueIsOnlyUsedLocallyOrStoredToOneGlobal(const CallInst *CI,
continue; // Otherwise, storing through it, or storing into GV... fine.
}
- if (auto *BCI = dyn_cast<BitCastInst>(U)) {
- Worklist.push_back(BCI);
- continue;
- }
-
if (auto *GEPI = dyn_cast<GetElementPtrInst>(U)) {
Worklist.push_back(GEPI);
continue;
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index ab3d8ca8db6f75..4f9a5bd2c17f03 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -104,7 +104,7 @@ static Type *getPromotedType(Type *Ty) {
/// requires a deeper change to allow either unread or unwritten objects.
static bool hasUndefSource(AnyMemTransferInst *MI) {
auto *Src = MI->getRawSource();
- while (isa<GetElementPtrInst>(Src) || isa<BitCastInst>(Src)) {
+ while (isa<GetElementPtrInst>(Src)) {
if (!Src->hasOneUse())
return false;
Src = cast<Instruction>(Src)->getOperand(0);
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 0fb8b639c97b95..877e4f591af5a0 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -4707,8 +4707,7 @@ static bool SoleWriteToDeadLocal(Instruction *I, TargetLibraryInfo &TLI) {
pushUsers(*AI);
while (!AllocaUsers.empty()) {
auto *UserI = cast<Instruction>(AllocaUsers.pop_back_val());
- if (isa<BitCastInst>(UserI) || isa<GetElementPtrInst>(UserI) ||
- isa<AddrSpaceCastInst>(UserI)) {
+ if (isa<GetElementPtrInst>(UserI) || isa<AddrSpaceCastInst>(UserI)) {
pushUsers(*UserI);
continue;
}
diff --git a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
index cee34f0a6da1f3..1d779128e454c1 100644
--- a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
+++ b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
@@ -980,12 +980,7 @@ bool MemCpyOptPass::performCallSlotOptzn(Instruction *cpyLoad,
while (!srcUseList.empty()) {
User *U = srcUseList.pop_back_val();
- if (isa<BitCastInst>(U) || isa<AddrSpaceCastInst>(U)) {
- append_range(srcUseList, U->users());
- continue;
- }
- if (const auto *G = dyn_cast<GetElementPtrInst>(U);
- G && G->hasAllZeroIndices()) {
+ if (isa<AddrSpaceCastInst>(U)) {
append_range(srcUseList, U->users());
continue;
}
diff --git a/llvm/lib/Transforms/Utils/GlobalStatus.cpp b/llvm/lib/Transforms/Utils/GlobalStatus.cpp
index b177e048faae0f..0b3016a86e2875 100644
--- a/llvm/lib/Transforms/Utils/GlobalStatus.cpp
+++ b/llvm/lib/Transforms/Utils/GlobalStatus.cpp
@@ -143,9 +143,8 @@ static bool analyzeGlobalAux(const Value *V, GlobalStatus &GS,
GS.StoredType = GlobalStatus::Stored;
}
}
- } else if (isa<BitCastInst>(I) || isa<GetElementPtrInst>(I) ||
- isa<AddrSpaceCastInst>(I)) {
- // Skip over bitcasts and GEPs; we don't care about the type or offset
+ } else if (isa<GetElementPtrInst>(I) || isa<AddrSpaceCastInst>(I)) {
+ // Skip over GEPs; we don't care about the type or offset
// of the pointer.
if (analyzeGlobalAux(I, GS, VisitedUsers))
return true;
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index ccdfe47ef81e7e..37c8761ca9383d 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -7652,10 +7652,6 @@ static bool passingValueIsAlwaysUndefined(Value *V, Instruction *I, bool PtrValu
}
}
- // Look through bitcasts.
- if (BitCastInst *BC = dyn_cast<BitCastInst>(Use))
- return passingValueIsAlwaysUndefined(V, BC, PtrValueMayBeModified);
-
// Load from null is undefined.
if (LoadInst *LI = dyn_cast<LoadInst>(Use))
if (!LI->isVolatile())
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index 0d1262fa187298..f5337b11edc977 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -3139,12 +3139,10 @@ void LoopVectorizationCostModel::collectLoopScalars(ElementCount VF) {
return WideningDecision != CM_GatherScatter;
};
- // A helper that returns true if the given value is a bitcast or
- // getelementptr instruction contained in the loop.
- auto isLoopVaryingBitCastOrGEP = [&](Value *V) {
- return ((isa<BitCastInst>(V) && V->getType()->isPointerTy()) ||
- isa<GetElementPtrInst>(V)) &&
- !TheLoop->isLoopInvariant(V);
+ // A helper that returns true if the given value is a getelementptr
+ // instruction contained in the loop.
+ auto isLoopVaryingGEP = [&](Value *V) {
+ return isa<GetElementPtrInst>(V) && !TheLoop->isLoopInvariant(V);
};
// A helper that evaluates a memory access's use of a pointer. If the use will
@@ -3154,7 +3152,7 @@ void LoopVectorizationCostModel::collectLoopScalars(ElementCount VF) {
auto evaluatePtrUse = [&](Instruction *MemAccess, Value *Ptr) {
// We only care about bitcast and getelementptr instructions contained in
// the loop.
- if (!isLoopVaryingBitCastOrGEP(Ptr))
+ if (!isLoopVaryingGEP(Ptr))
return;
// If the pointer has already been identified as scalar (e.g., if it was
@@ -3220,7 +3218,7 @@ void LoopVectorizationCostModel::collectLoopScalars(ElementCount VF) {
unsigned Idx = 0;
while (Idx != Worklist.size()) {
Instruction *Dst = Worklist[Idx++];
- if (!isLoopVaryingBitCastOrGEP(Dst->getOperand(0)))
+ if (!isLoopVaryingGEP(Dst->getOperand(0)))
continue;
auto *Src = cast<Instruction>(Dst->getOperand(0));
if (llvm::all_of(Src->users(), [&](User *U) -> bool {
More information about the llvm-commits
mailing list