Skip to content

Commit ea70b75

Browse files
arsenmtomtor
authored andcommitted
GVN: Fix trying to inspect uselist of constants when emitting remark (llvm#144009)
1 parent 321df1b commit ea70b75

File tree

2 files changed

+69
-32
lines changed

2 files changed

+69
-32
lines changed

llvm/lib/Transforms/Scalar/GVN.cpp

Lines changed: 43 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1165,28 +1165,23 @@ static bool isLifetimeStart(const Instruction *Inst) {
11651165
/// Assuming To can be reached from both From and Between, does Between lie on
11661166
/// every path from From to To?
11671167
static bool liesBetween(const Instruction *From, Instruction *Between,
1168-
const Instruction *To, DominatorTree *DT) {
1168+
const Instruction *To, const DominatorTree *DT) {
11691169
if (From->getParent() == Between->getParent())
11701170
return DT->dominates(From, Between);
11711171
SmallSet<BasicBlock *, 1> Exclusion;
11721172
Exclusion.insert(Between->getParent());
11731173
return !isPotentiallyReachable(From, To, &Exclusion, DT);
11741174
}
11751175

1176-
/// Try to locate the three instruction involved in a missed
1177-
/// load-elimination case that is due to an intervening store.
1178-
static void reportMayClobberedLoad(LoadInst *Load, MemDepResult DepInfo,
1179-
DominatorTree *DT,
1180-
OptimizationRemarkEmitter *ORE) {
1181-
using namespace ore;
1176+
static const Instruction *findMayClobberedPtrAccess(LoadInst *Load,
1177+
const DominatorTree *DT) {
1178+
Value *PtrOp = Load->getPointerOperand();
1179+
if (!PtrOp->hasUseList())
1180+
return nullptr;
11821181

11831182
Instruction *OtherAccess = nullptr;
11841183

1185-
OptimizationRemarkMissed R(DEBUG_TYPE, "LoadClobbered", Load);
1186-
R << "load of type " << NV("Type", Load->getType()) << " not eliminated"
1187-
<< setExtraArgs();
1188-
1189-
for (auto *U : Load->getPointerOperand()->users()) {
1184+
for (auto *U : PtrOp->users()) {
11901185
if (U != Load && (isa<LoadInst>(U) || isa<StoreInst>(U))) {
11911186
auto *I = cast<Instruction>(U);
11921187
if (I->getFunction() == Load->getFunction() && DT->dominates(I, Load)) {
@@ -1202,32 +1197,48 @@ static void reportMayClobberedLoad(LoadInst *Load, MemDepResult DepInfo,
12021197
}
12031198
}
12041199

1205-
if (!OtherAccess) {
1206-
// There is no dominating use, check if we can find a closest non-dominating
1207-
// use that lies between any other potentially available use and Load.
1208-
for (auto *U : Load->getPointerOperand()->users()) {
1209-
if (U != Load && (isa<LoadInst>(U) || isa<StoreInst>(U))) {
1210-
auto *I = cast<Instruction>(U);
1211-
if (I->getFunction() == Load->getFunction() &&
1212-
isPotentiallyReachable(I, Load, nullptr, DT)) {
1213-
if (OtherAccess) {
1214-
if (liesBetween(OtherAccess, I, Load, DT)) {
1215-
OtherAccess = I;
1216-
} else if (!liesBetween(I, OtherAccess, Load, DT)) {
1217-
// These uses are both partially available at Load were it not for
1218-
// the clobber, but neither lies strictly after the other.
1219-
OtherAccess = nullptr;
1220-
break;
1221-
} // else: keep current OtherAccess since it lies between U and
1222-
// Load.
1223-
} else {
1200+
if (OtherAccess)
1201+
return OtherAccess;
1202+
1203+
// There is no dominating use, check if we can find a closest non-dominating
1204+
// use that lies between any other potentially available use and Load.
1205+
for (auto *U : PtrOp->users()) {
1206+
if (U != Load && (isa<LoadInst>(U) || isa<StoreInst>(U))) {
1207+
auto *I = cast<Instruction>(U);
1208+
if (I->getFunction() == Load->getFunction() &&
1209+
isPotentiallyReachable(I, Load, nullptr, DT)) {
1210+
if (OtherAccess) {
1211+
if (liesBetween(OtherAccess, I, Load, DT)) {
12241212
OtherAccess = I;
1225-
}
1213+
} else if (!liesBetween(I, OtherAccess, Load, DT)) {
1214+
// These uses are both partially available at Load were it not for
1215+
// the clobber, but neither lies strictly after the other.
1216+
OtherAccess = nullptr;
1217+
break;
1218+
} // else: keep current OtherAccess since it lies between U and
1219+
// Load.
1220+
} else {
1221+
OtherAccess = I;
12261222
}
12271223
}
12281224
}
12291225
}
12301226

1227+
return OtherAccess;
1228+
}
1229+
1230+
/// Try to locate the three instruction involved in a missed
1231+
/// load-elimination case that is due to an intervening store.
1232+
static void reportMayClobberedLoad(LoadInst *Load, MemDepResult DepInfo,
1233+
const DominatorTree *DT,
1234+
OptimizationRemarkEmitter *ORE) {
1235+
using namespace ore;
1236+
1237+
OptimizationRemarkMissed R(DEBUG_TYPE, "LoadClobbered", Load);
1238+
R << "load of type " << NV("Type", Load->getType()) << " not eliminated"
1239+
<< setExtraArgs();
1240+
1241+
const Instruction *OtherAccess = findMayClobberedPtrAccess(Load, DT);
12311242
if (OtherAccess)
12321243
R << " in favor of " << NV("OtherAccess", OtherAccess);
12331244

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
; RUN: opt -passes='gvn' -pass-remarks-output=%t.yaml %s
2+
; RUN: FileCheck %s < %t.yaml
3+
4+
; Check that there's no assert from trying to the uses of the constant
5+
; null.
6+
7+
; CHECK: --- !Missed
8+
; CHECK-NEXT: Pass: gvn
9+
; CHECK-NEXT: Name: LoadClobbered
10+
; CHECK-NEXT: Function: c
11+
; CHECK-NEXT: Args:
12+
; CHECK-NEXT: - String: 'load of type '
13+
; CHECK-NEXT: - Type: i64
14+
; CHECK-NEXT: - String: ' not eliminated'
15+
; CHECK-NEXT: - String: ' because it is clobbered by '
16+
; CHECK-NEXT: - ClobberedBy: store
17+
; CHECK-NEXT: ...
18+
define void @c(ptr addrspace(21) %a) {
19+
entry:
20+
br label %for.cond
21+
22+
for.cond: ; preds = %for.cond, %entry
23+
%load = load i64, ptr addrspace(21) null, align 1
24+
store i64 %load, ptr addrspace(21) %a, align 1
25+
br label %for.cond
26+
}

0 commit comments

Comments
 (0)