Skip to content

Commit

Permalink
[DAG] Elide overlapping stores
Browse files Browse the repository at this point in the history
Relanding after fixing handling of pre-indexed memory operations in
BaseIndexOffset analysis (r322003).

Extend overlapping store elision to handle overwrites of stores by
larger stores.

Reviewers: craig.topper, rnk, t.p.northover

Subscribers: javed.absar, hiraditya, llvm-commits

Differential Revision: https://reviews.llvm.org/D40969

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@322085 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
niravhdave committed Jan 9, 2018
1 parent 9f32fd2 commit b56f822
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 24 deletions.
41 changes: 20 additions & 21 deletions lib/CodeGen/SelectionDAG/DAGCombiner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13798,30 +13798,29 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) {
}
}

if (StoreSDNode *ST1 = dyn_cast<StoreSDNode>(Chain)) {
if (ST->isUnindexed() && !ST->isVolatile() && ST1->isUnindexed() &&
!ST1->isVolatile() && ST1->getBasePtr() == Ptr &&
ST->getMemoryVT() == ST1->getMemoryVT()) {
// If this is a store followed by a store with the same value to the same
// location, then the store is dead/noop.
if (ST1->getValue() == Value) {
// The store is dead, remove it.
return Chain;
}

// If this is a store who's preceeding store to the same location
// and no one other node is chained to that store we can effectively
// drop the store. Do not remove stores to undef as they may be used as
// data sinks.
if (OptLevel != CodeGenOpt::None && ST1->hasOneUse() &&
!ST1->getBasePtr().isUndef()) {
// ST1 is fully overwritten and can be elided. Combine with it's chain
// value.
// Deal with elidable overlapping chained stores.
if (StoreSDNode *ST1 = dyn_cast<StoreSDNode>(Chain))
if (OptLevel != CodeGenOpt::None && ST->isUnindexed() &&
ST1->isUnindexed() && !ST1->isVolatile() && ST1->hasOneUse() &&
!ST1->getBasePtr().isUndef() && !ST->isVolatile()) {
BaseIndexOffset STBasePtr = BaseIndexOffset::match(ST, DAG);
BaseIndexOffset ST1BasePtr = BaseIndexOffset::match(ST1, DAG);
unsigned STBytes = ST->getMemoryVT().getStoreSize();
unsigned ST1Bytes = ST1->getMemoryVT().getStoreSize();
int64_t PtrDiff;
// If this is a store who's preceeding store to a subset of the same
// memory and no one other node is chained to that store we can
// effectively drop the store. Do not remove stores to undef as they may
// be used as data sinks.

if (((ST->getBasePtr() == ST1->getBasePtr()) &&
(ST->getValue() == ST1->getValue())) ||
(STBasePtr.equalBaseIndex(ST1BasePtr, DAG, PtrDiff) &&
(0 <= PtrDiff) && (PtrDiff + ST1Bytes <= STBytes))) {
CombineTo(ST1, ST1->getChain());
return SDValue();
return SDValue(N, 0);
}
}
}

// If this is an FP_ROUND or TRUNC followed by a store, fold this into a
// truncating store. We can do this even if this is already a truncstore.
Expand Down
5 changes: 2 additions & 3 deletions test/CodeGen/AArch64/ldst-paired-aliasing.ll
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,10 @@ declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) #3
define i32 @main() local_unnamed_addr #1 {
; Make sure the stores happen in the correct order (the exact instructions could change).
; CHECK-LABEL: main:
; CHECK: stp xzr, xzr, [sp, #72]
; CHECK: str xzr, [sp, #80]
; CHECK: str w9, [sp, #80]
; CHECK: str q0, [sp, #48]
; CHECK: stp q0, q0, [sp, #48]
; CHECK: ldr w8, [sp, #48]
; CHECK: str q0, [sp, #64]

for.body.lr.ph.i.i.i.i.i.i63:
%b1 = alloca [10 x i32], align 16
Expand Down

0 comments on commit b56f822

Please sign in to comment.