[SLP] fix miscompile on min/max reductions with extra uses (PR43948) (2nd try)
authorSanjay Patel <spatel@rotateright.com>
Tue, 19 Nov 2019 17:24:55 +0000 (12:24 -0500)
committerSanjay Patel <spatel@rotateright.com>
Tue, 19 Nov 2019 19:57:35 +0000 (14:57 -0500)
commit0a8e7ca402eb3470eb5faf4982581771cb849130
tree35faaf67616672c4138ea7c2af9e5ef36c022bf0
parenta84b48d01e3e77b754a6d4d7326e4a0c4faa10ab
[SLP] fix miscompile on min/max reductions with extra uses (PR43948) (2nd try)

The 1st attempt was reverted because it revealed an existing
bug where we could produce invalid IR (use of value before
definition). That should be fixed with:
rG39de82ecc9c2

The bug manifests as replacing a reduction operand with an undef
value.

The problem appears to be limited to cases where a min/max reduction
has extra uses of the compare operand to the select.

In the general case, we are tracking "ExternallyUsedValues" and
an "IgnoreList" of the reduction operations, but those may not apply
to the final compare+select in a min/max reduction.

For that, we use replaceAllUsesWith (RAUW) to ensure that the new
vectorized reduction values are transferred to all subsequent users.

Differential Revision: https://reviews.llvm.org/D70148
llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
llvm/test/Transforms/SLPVectorizer/X86/reduction.ll
llvm/test/Transforms/SLPVectorizer/X86/used-reduced-op.ll