This is an archive of the discontinued LLVM Phabricator instance.

[InstCombine] Extend peephole DSE to handle unordered atomics
ClosedPublic

Authored by reames on Dec 8 2015, 2:58 PM.

Details

Summary

This extends the same line of reasoning used in EarlyCSE w/http://reviews.llvm.org/D15352 to the DSE implementation in InstCombine.

Key points:

  • We only remove unordered or simple stores.
  • The loads producing values consumed by dead stores don't influence whether the store is dead.

Diff Detail

Repository
rL LLVM

Event Timeline

reames updated this revision to Diff 42231.Dec 8 2015, 2:58 PM
reames retitled this revision from to [InstCombine] Extend peephole DSE to handle unordered atomics.
reames updated this object.
reames added a subscriber: llvm-commits.
jfb added inline comments.Dec 9 2015, 3:00 AM
lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
984 ↗(On Diff #42231)

"for ordered atomic stores"

1031 ↗(On Diff #42231)

Doesn't this need to test for && LI->isUnordered()? Otherwise it can remove a volatile or ordered load.

1058 ↗(On Diff #42231)

"to be audited"

test/Transforms/InstCombine/store.ll
127 ↗(On Diff #42231)

Same as in D15352: I think the remaining store should still be atomic, and store the latest value.

136 ↗(On Diff #42231)

Same.

196 ↗(On Diff #42231)

We could just have a fence, or make it a no-op RMW to the stack top? Maybe worth documenting, not implementing yet.

replying to JF's comments, updated diff to follow

lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
1031 ↗(On Diff #42231)

Nope. We can remove the store even if the load is ordered. Removing the load wouldn't be valid, but removing the store is.

test/Transforms/InstCombine/store.ll
127 ↗(On Diff #42231)

Same as in that review, the second store is undefined behaviour if access is racy. The location is no longer atomic and we can pick either store.

136 ↗(On Diff #42231)

same answer

196 ↗(On Diff #42231)

This is documented in EarlyCSE already. I don't see the point in duplicating this in a bunch of places.

reames updated this revision to Diff 42951.Dec 15 2015, 5:57 PM
jfb added inline comments.Dec 16 2015, 2:24 PM
lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
1089 ↗(On Diff #42951)

An ordered load has ordering semantics that you'd be losing. The *value* stored can be eliminated, but you still need to keep atomic *ordering*.

And you just can't remove volatile :-)

Though it looks like the write-back tests are already correct? I'm confused now.

test/Transforms/InstCombine/store.ll
127 ↗(On Diff #42951)

We should at least check that the latest value gets stored (here and below).

reames added inline comments.Dec 16 2015, 4:29 PM
lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
1089 ↗(On Diff #42951)

@JF - I'm 99% certain you're misreading the code and my comments. We're *only* removing the *store* here. The *load* is not being changed. Whether the load is ordered/volatile does not effect the legality of removing the store. In fact, this exact case is covered by the tests @write_back6 and @write_back7.

Or, am I missing something?

test/Transforms/InstCombine/store.ll
127 ↗(On Diff #42951)

Will do. I also need to update the comment slightly. The store is well defined; it's the *contents* of the memory location which isn't. The rest is still correct, but the wording was misleading.

jfb edited edge metadata.Dec 17 2015, 8:55 AM

Looks good with the 2 suggested updates (assert, and extra check in test).

lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
1089 ↗(On Diff #42951)

Ah yes, you're totally right! Could you assert(SI->isUnordered() && "can't eliminate volatile or ordered store"); here? I know it's checked above, but the intent seems to be to relax this later so the assert will prevent sadness.

This revision was automatically updated to reflect the committed changes.