llvm.org GIT mirror llvm / 906007f
[LICM & MemorySSA] Don't sink/hoist stores in the presence of ordered loads. Summary: Before this patch, if any Use existed in the loop, with a defining access in the loop, we conservatively decide to not move the store. What this approach was missing, is that ordered loads are not Uses, they're Defs in MemorySSA. So, even when the clobbering walker does not find that volatile load to interfere, we still cannot hoist a store past a volatile load. Resolves PR41140. Reviewers: george.burgess.iv Subscribers: sanjoy, jlebar, Prazek, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D59564 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@356588 91177308-0d34-0410-b5e6-96231b3b80d8 Alina Sbirlea 6 months ago
2 changed file(s) with 31 addition(s) and 27 deletion(s). Raw diff Collapse all Expand all
11901190 } else { // MSSAU
11911191 if (isOnlyMemoryAccess(SI, CurLoop, MSSAU))
11921192 return true;
1193 if (*LicmMssaOptCounter < LicmMssaOptCap) {
1193 // If there are more accesses than the Promotion cap, give up, we're not
1194 // walking a list that long.
1195 if (NoOfMemAccTooLarge)
1196 return false;
1197 // Check store only if there's still "quota" to check clobber.
1198 if (*LicmMssaOptCounter >= LicmMssaOptCap)
1199 return false;
1200 // If there are interfering Uses (i.e. their defining access is in the
1201 // loop), or ordered loads (stored as Defs!), don't move this store.
1202 // Could do better here, but this is conservatively correct.
1203 // TODO: Cache set of Uses on the first walk in runOnLoop, update when
1204 // moving accesses. Can also extend to dominating uses.
1205 for (auto *BB : CurLoop->getBlocks())
1206 if (auto *Accesses = MSSA->getBlockAccesses(BB)) {
1207 for (const auto &MA : *Accesses)
1208 if (const auto *MU = dyn_cast(&MA)) {
1209 auto *MD = MU->getDefiningAccess();
1210 if (!MSSA->isLiveOnEntryDef(MD) &&
1211 CurLoop->contains(MD->getBlock()))
1212 return false;
1213 } else if (const auto *MD = dyn_cast(&MA))
1214 if (auto *LI = dyn_cast(MD->getMemoryInst())) {
1215 assert(!LI->isUnordered() && "Expected unordered load");
1216 return false;
1217 }
1218 }
1219
11941220 auto *Source = MSSA->getSkipSelfWalker()->getClobberingMemoryAccess(SI);
11951221 (*LicmMssaOptCounter)++;
1196 // If there are no clobbering Defs in the loop, we still need to check
1197 // for interfering Uses. If there are more accesses than the Promotion
1198 // cap, give up, we're not walking a list that long. Otherwise, walk the
1199 // list, check each Use if it's optimized to an access outside the loop.
1200 // If yes, store is safe to hoist. This is fairly restrictive, but
1201 // conservatively correct.
1202 // TODO: Cache set of Uses on the first walk in runOnLoop, update when
1203 // moving accesses. Can also extend to dominating uses.
1204 if ((!MSSA->isLiveOnEntryDef(Source) &&
1205 CurLoop->contains(Source->getBlock())) ||
1206 NoOfMemAccTooLarge)
1207 return false;
1208 for (auto *BB : CurLoop->getBlocks())
1209 if (auto *Accesses = MSSA->getBlockAccesses(BB))
1210 for (const auto &MA : *Accesses)
1211 if (const auto *MU = dyn_cast(&MA)) {
1212 auto *MD = MU->getDefiningAccess();
1213 if (!MSSA->isLiveOnEntryDef(MD) &&
1214 CurLoop->contains(MD->getBlock()))
1215 return false;
1216 }
1217 return true;
1218 }
1219 return false;
1222 // If there are no clobbering Defs in the loop, store is safe to hoist.
1223 return MSSA->isLiveOnEntryDef(Source) ||
1224 !CurLoop->contains(Source->getBlock());
12201225 }
12211226 }
12221227
0 ; RUN: opt < %s -licm -S | FileCheck %s
11 ; RUN: opt < %s -strip-debug -licm -S | FileCheck %s
2 ; RUN: opt < %s -licm -enable-mssa-loop-dependency=true -verify-memoryssa -S | FileCheck %s --check-prefixes=CHECK,MSSA
2 ; RUN: opt < %s -licm -enable-mssa-loop-dependency=true -verify-memoryssa -S | FileCheck %s
33
44 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
55 target triple = "x86_64-unknown-linux-gnu"
1616 ; CHECK-NEXT: [[_TMP2:%.*]] = load i32, i32* @a, align 4
1717 ; CHECK-NEXT: [[_TMP3:%.*]] = load i32, i32* @b, align 4
1818 ; CHECK-NEXT: [[_TMP4:%.*]] = sdiv i32 [[_TMP2]], [[_TMP3]]
19 ; MSSA-NEXT: store i32 [[_TMP4:%.*]], i32* @c, align 4
2019 ; CHECK-NEXT: br label [[BB3:%.*]]
2120
2221 br label %bb3