-
Notifications
You must be signed in to change notification settings - Fork 14.4k
GVN: Fix trying to inspect uselist of constants when emitting remark #144009
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
GVN: Fix trying to inspect uselist of constants when emitting remark #144009
Conversation
This stack of pull requests is managed by Graphite. Learn more about stacking. |
@llvm/pr-subscribers-llvm-transforms Author: Matt Arsenault (arsenm) ChangesFull diff: https://github.com/llvm/llvm-project/pull/144009.diff 2 Files Affected:
diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp
index a0eed31fde792..c8a0479358eab 100644
--- a/llvm/lib/Transforms/Scalar/GVN.cpp
+++ b/llvm/lib/Transforms/Scalar/GVN.cpp
@@ -1165,7 +1165,7 @@ static bool isLifetimeStart(const Instruction *Inst) {
/// Assuming To can be reached from both From and Between, does Between lie on
/// every path from From to To?
static bool liesBetween(const Instruction *From, Instruction *Between,
- const Instruction *To, DominatorTree *DT) {
+ const Instruction *To, const DominatorTree *DT) {
if (From->getParent() == Between->getParent())
return DT->dominates(From, Between);
SmallSet<BasicBlock *, 1> Exclusion;
@@ -1173,20 +1173,15 @@ static bool liesBetween(const Instruction *From, Instruction *Between,
return !isPotentiallyReachable(From, To, &Exclusion, DT);
}
-/// Try to locate the three instruction involved in a missed
-/// load-elimination case that is due to an intervening store.
-static void reportMayClobberedLoad(LoadInst *Load, MemDepResult DepInfo,
- DominatorTree *DT,
- OptimizationRemarkEmitter *ORE) {
- using namespace ore;
+static const Instruction *findMayClobberedPtrAccess(LoadInst *Load,
+ const DominatorTree *DT) {
+ Value *PtrOp = Load->getPointerOperand();
+ if (!PtrOp->hasUseList())
+ return nullptr;
Instruction *OtherAccess = nullptr;
- OptimizationRemarkMissed R(DEBUG_TYPE, "LoadClobbered", Load);
- R << "load of type " << NV("Type", Load->getType()) << " not eliminated"
- << setExtraArgs();
-
- for (auto *U : Load->getPointerOperand()->users()) {
+ for (auto *U : PtrOp->users()) {
if (U != Load && (isa<LoadInst>(U) || isa<StoreInst>(U))) {
auto *I = cast<Instruction>(U);
if (I->getFunction() == Load->getFunction() && DT->dominates(I, Load)) {
@@ -1202,32 +1197,48 @@ static void reportMayClobberedLoad(LoadInst *Load, MemDepResult DepInfo,
}
}
- if (!OtherAccess) {
- // There is no dominating use, check if we can find a closest non-dominating
- // use that lies between any other potentially available use and Load.
- for (auto *U : Load->getPointerOperand()->users()) {
- if (U != Load && (isa<LoadInst>(U) || isa<StoreInst>(U))) {
- auto *I = cast<Instruction>(U);
- if (I->getFunction() == Load->getFunction() &&
- isPotentiallyReachable(I, Load, nullptr, DT)) {
- if (OtherAccess) {
- if (liesBetween(OtherAccess, I, Load, DT)) {
- OtherAccess = I;
- } else if (!liesBetween(I, OtherAccess, Load, DT)) {
- // These uses are both partially available at Load were it not for
- // the clobber, but neither lies strictly after the other.
- OtherAccess = nullptr;
- break;
- } // else: keep current OtherAccess since it lies between U and
- // Load.
- } else {
+ if (OtherAccess)
+ return OtherAccess;
+
+ // There is no dominating use, check if we can find a closest non-dominating
+ // use that lies between any other potentially available use and Load.
+ for (auto *U : PtrOp->users()) {
+ if (U != Load && (isa<LoadInst>(U) || isa<StoreInst>(U))) {
+ auto *I = cast<Instruction>(U);
+ if (I->getFunction() == Load->getFunction() &&
+ isPotentiallyReachable(I, Load, nullptr, DT)) {
+ if (OtherAccess) {
+ if (liesBetween(OtherAccess, I, Load, DT)) {
OtherAccess = I;
- }
+ } else if (!liesBetween(I, OtherAccess, Load, DT)) {
+ // These uses are both partially available at Load were it not for
+ // the clobber, but neither lies strictly after the other.
+ OtherAccess = nullptr;
+ break;
+ } // else: keep current OtherAccess since it lies between U and
+ // Load.
+ } else {
+ OtherAccess = I;
}
}
}
}
+ return OtherAccess;
+}
+
+/// Try to locate the three instruction involved in a missed
+/// load-elimination case that is due to an intervening store.
+static void reportMayClobberedLoad(LoadInst *Load, MemDepResult DepInfo,
+ const DominatorTree *DT,
+ OptimizationRemarkEmitter *ORE) {
+ using namespace ore;
+
+ OptimizationRemarkMissed R(DEBUG_TYPE, "LoadClobbered", Load);
+ R << "load of type " << NV("Type", Load->getType()) << " not eliminated"
+ << setExtraArgs();
+
+ const Instruction *OtherAccess = findMayClobberedPtrAccess(Load, DT);
if (OtherAccess)
R << " in favor of " << NV("OtherAccess", OtherAccess);
diff --git a/llvm/test/Transforms/GVN/opt-remark-assert-constant-uselistorder.ll b/llvm/test/Transforms/GVN/opt-remark-assert-constant-uselistorder.ll
new file mode 100644
index 0000000000000..e793728815a88
--- /dev/null
+++ b/llvm/test/Transforms/GVN/opt-remark-assert-constant-uselistorder.ll
@@ -0,0 +1,26 @@
+; RUN: opt -passes='gvn' -pass-remarks-output=%t.yaml %s
+; RUN: FileCheck %s < %t.yaml
+
+; Check that there's no assert from trying to the uses of the constant
+; null.
+
+; CHECK: --- !Missed
+; CHECK-NEXT: Pass: gvn
+; CHECK-NEXT: Name: LoadClobbered
+; CHECK-NEXT: Function: c
+; CHECK-NEXT: Args:
+; CHECK-NEXT: - String: 'load of type '
+; CHECK-NEXT: - Type: i64
+; CHECK-NEXT: - String: ' not eliminated'
+; CHECK-NEXT: - String: ' because it is clobbered by '
+; CHECK-NEXT: - ClobberedBy: store
+; CHECK-NEXT: ...
+define void @c(ptr addrspace(21) %a) {
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.cond, %entry
+ %load = load i64, ptr addrspace(21) null, align 1
+ store i64 %load, ptr addrspace(21) %a, align 1
+ br label %for.cond
+}
|
I've verified that this solves the crash I reported. Thanks! |
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
No description provided.