@@ -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?
11671167static 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
0 commit comments