[PATCH] D25601: DAGCombiner: fix use-after-free when merging consecutive stores
Justin Bogner via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 2 12:13:52 PDT 2016
Nicolai Hähnle <nhaehnle at gmail.com> writes:
>>>> - do {
>>>> + for (;;) {
>>>> // There can be multiple store sequences on the same chain.
>>>> // Keep trying to merge store sequences until we are unable to
>>>> do so
>>>> // or until we merge the last store on the chain.
>>>> - bool Changed = MergeConsecutiveStores(ST);
>>>> + SmallVector<MemOpLink, 8> StoreNodes;
>>>> + bool Changed = MergeConsecutiveStores(ST, StoreNodes);
>>>
>>> What do you think of returning the SmallVector instead of the bool, then
>>> just doing `EverChanged |= !StoreNodes.empty()`? It seems a bit simpler
>>> to me, and move semantics should mean it's just as efficient.
>>
>> A SmallVector move cannot be as efficient because it cannot avoid the
>> copy in the small case. I don't feel strongly about it though.
That's a good point about the SmallVector move, but I'm pretty sure this
case would fall under NRVO and copy elision anyway, so it probably
doesn't even come up.
> Another point to consider is that encoding the size of the SmallVector
> as part of a function signature feels a bit odd, especially in this
> case where it'd affect two functions whose return type must then agree
> on the size of the SmallVector. I'd really prefer not to make that
> change.
I don't really see why, but I don't feel too strongly about it.
> nhaehnle updated this revision to Diff 76759.
> nhaehnle added a comment.
>
> Simplify using any_of.
This version LGTM.
> https://reviews.llvm.org/D25601
>
> Files:
> lib/CodeGen/SelectionDAG/DAGCombiner.cpp
>
>
> Index: lib/CodeGen/SelectionDAG/DAGCombiner.cpp
> ===================================================================
> --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp
> +++ lib/CodeGen/SelectionDAG/DAGCombiner.cpp
> @@ -450,10 +450,11 @@
> /// This is a helper function for MergeConsecutiveStores. When the source
> /// elements of the consecutive stores are all constants or all extracted
> /// vector elements, try to merge them into one larger store.
> - /// \return True if a merged store was created.
> - bool MergeStoresOfConstantsOrVecElts(SmallVectorImpl<MemOpLink> &StoreNodes,
> - EVT MemVT, unsigned NumStores,
> - bool IsConstantSrc, bool UseVector);
> + /// \return number of stores that were merged into a merged store (always
> + /// a prefix of \p StoreNode).
> + bool MergeStoresOfConstantsOrVecElts(
> + SmallVectorImpl<MemOpLink> &StoreNodes, EVT MemVT, unsigned NumStores,
> + bool IsConstantSrc, bool UseVector);
>
> /// This is a helper function for MergeConsecutiveStores.
> /// Stores that may be merged are placed in StoreNodes.
> @@ -470,8 +471,10 @@
>
> /// Merge consecutive store operations into a wide store.
> /// This optimization uses wide integers or vectors when possible.
> - /// \return True if some memory operations were changed.
> - bool MergeConsecutiveStores(StoreSDNode *N);
> + /// \return number of stores that were merged into a merged store (the
> + /// affected nodes are stored as a prefix in \p StoreNodes).
> + bool MergeConsecutiveStores(StoreSDNode *N,
> + SmallVectorImpl<MemOpLink> &StoreNodes);
>
> /// \brief Try to transform a truncation where C is a constant:
> /// (trunc (and X, C)) -> (and (trunc X), (trunc C))
> @@ -11513,6 +11516,7 @@
> }
> }
>
> + StoreNodes.erase(StoreNodes.begin() + NumStores, StoreNodes.end());
> return true;
> }
>
> @@ -11655,7 +11659,8 @@
> return true;
> }
>
> -bool DAGCombiner::MergeConsecutiveStores(StoreSDNode* St) {
> +bool DAGCombiner::MergeConsecutiveStores(
> + StoreSDNode* St, SmallVectorImpl<MemOpLink> &StoreNodes) {
> if (OptLevel == CodeGenOpt::None)
> return false;
>
> @@ -11699,9 +11704,6 @@
> // any of the store nodes.
> SmallVector<LSBaseSDNode*, 8> AliasLoadNodes;
>
> - // Save the StoreSDNodes that we find in the chain.
> - SmallVector<MemOpLink, 8> StoreNodes;
> -
> getStoreMergeAndAliasCandidates(St, StoreNodes, AliasLoadNodes);
>
> // Check if there is anything to merge.
> @@ -12060,6 +12062,7 @@
> }
> }
>
> + StoreNodes.erase(StoreNodes.begin() + NumElem, StoreNodes.end());
> return true;
> }
>
> @@ -12305,14 +12308,19 @@
> if (!LegalTypes) {
> bool EverChanged = false;
>
> - do {
> + for (;;) {
> // There can be multiple store sequences on the same chain.
> // Keep trying to merge store sequences until we are unable to do so
> // or until we merge the last store on the chain.
> - bool Changed = MergeConsecutiveStores(ST);
> + SmallVector<MemOpLink, 8> StoreNodes;
> + bool Changed = MergeConsecutiveStores(ST, StoreNodes);
> EverChanged |= Changed;
> if (!Changed) break;
> - } while (ST->getOpcode() != ISD::DELETED_NODE);
> +
> + if (any_of(StoreNodes,
> + [ST](const MemOpLink &Link) { return Link.MemNode == ST; }))
> + break;
> + }
>
> if (EverChanged)
> return SDValue(N, 0);
More information about the llvm-commits
mailing list