[PATCH] D25601: DAGCombiner: fix use-after-free when merging consecutive stores

Nicolai Hähnle via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 2 11:44:46 PDT 2016


On 02.11.2016 19:38, Nicolai Hähnle wrote:
> On 02.11.2016 18:54, Justin Bogner wrote:
>> Nicolai Hähnle <nhaehnle at gmail.com> writes:
>>> nhaehnle updated this revision to Diff 76719.
>>> nhaehnle added a comment.
>>>
>>> Keep returning a boolean.
>>>
>>> Since not all nodes are necessarily merged, the success-path now
>>> needs to
>>> truncate the StoreNodes vector to just those nodes that were actually
>>> removed.
>>
>> Looks pretty close. A couple of comments below.
>
> Thanks for taking a look!
>
> [snip]
>>> -    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.

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.

Cheers,
Nicolai

>
>
>>>        EverChanged |= Changed;
>>>        if (!Changed) break;
>>> -    } while (ST->getOpcode() != ISD::DELETED_NODE);
>>> +
>>> +      bool ChangedST = false;
>>> +      for (const auto &Link : StoreNodes) {
>>> +        if (Link.MemNode == ST) {
>>> +          ChangedST = true;
>>> +          break;
>>> +        }
>>> +      }
>>> +      if (ChangedST)
>>> +        break;
>>
>> I think this can be simplified with any_of. Something like this:
>>
>>       if (any_of(StoreNodes,
>>                  [&ST](const MemOpLink &Link) { return Link.MemNode ==
>> ST; }))
>>         return;
>
> Will do.
>
> Cheers,
> Nicolai
>
>>
>>> +    }
>>>
>>>      if (EverChanged)
>>>        return SDValue(N, 0);


More information about the llvm-commits mailing list