This is an archive of the discontinued LLVM Phabricator instance.

[InstCombine] Fix folding of select into phi nodes when incoming element of phi is a vector type
ClosedPublic

Authored by anna on Mar 21 2017, 8:30 AM.

Details

Summary

When the select condition operand is a phi node with an incoming value as a constant vector, we are incorrectly folding select into that phi node. This optimization is done in FoldOpIntoPhi.
Without the fix, we would incorrectly choose the true part
of the select to fold into the phi node, even if some elements in the vector are null.

With this fix, we will correctly fold the select into the phi node based on the
select vector operand (see added test cases).

Diff Detail

Repository
rL LLVM

Event Timeline

anna created this revision.Mar 21 2017, 8:30 AM
anna retitled this revision from [InstCombine] Avoid incorrect folding of select into phi nodes when incoming element is a vector type to [InstCombine] Fix folding of select into phi nodes when incoming element of phi is a vector type.Mar 21 2017, 8:42 AM
anna edited the summary of this revision. (Show Details)
majnemer added inline comments.Mar 21 2017, 8:46 AM
lib/Transforms/InstCombine/InstructionCombining.cpp
911–912 ↗(On Diff #92491)

I am surprised, what is InC if not a ConstantAggregateZero in this case?

anna added inline comments.Mar 21 2017, 8:59 AM
lib/Transforms/InstCombine/InstructionCombining.cpp
911–912 ↗(On Diff #92491)

InC is a ConstantAggregateZero is all vector elements are zero. In that case, isNullValue will return true and it is correct to fold into FalseVInPred.

However, if we have InC as a vector <0,1,1,0>, isNullValue will return false which is also correct, but we will fold into TrueVInPred which is an incorrect fold.

I think I'll have to update my comment which states always returns false. The problem is the incorrect fold when we have non-zero elements in the vector.

For example, in vec1 test case, without this change, we will incorrectly return ret <4 x i64> zeroinitializer.

anna edited the summary of this revision. (Show Details)Mar 22 2017, 6:17 AM
anna added inline comments.Mar 22 2017, 6:25 AM
lib/Transforms/InstCombine/InstructionCombining.cpp
913 ↗(On Diff #92491)

I will remove the will always return false part in the comment. That is incorrect.
Comment will be changed to:

For vector constants, we cannot use isNullValue to fold into FalseVInPred versus TrueVInPred. When we have individual nonzero elements in the vector, we will still incorrectly fold to `TrueVInPred`.
anna added a comment.Mar 23 2017, 4:47 PM

ping?
Currently, we have miscompiles when folding select into phi when phi has incoming non-zero constant vectors (both the added test cases show the problem).

sanjoy added inline comments.Mar 23 2017, 4:53 PM
lib/Transforms/InstCombine/InstructionCombining.cpp
914 ↗(On Diff #92491)

How about ConstantArray and ConstantStruct?

anna added inline comments.Mar 24 2017, 6:38 AM
lib/Transforms/InstCombine/InstructionCombining.cpp
914 ↗(On Diff #92491)

yes, good point. We are currently miscompiling for those types as well (basically all constant aggregate types : struct, array, vector). I'll update the patch and add test cases for these types.

anna added inline comments.Mar 24 2017, 8:12 AM
lib/Transforms/InstCombine/InstructionCombining.cpp
914 ↗(On Diff #92491)

Actually, I take that back. We will not fail for those types. Langref states that the condition for select can only be a i1 or <n x i1>, i.e. a boolean or a vector of booleans. Both struct and arrays are different types from vector types.

So, in effect, this miscompile will only effect vectors that are the select condition operand.

anna updated this revision to Diff 92951.Mar 24 2017, 8:22 AM

Updated the comment. NFC from previous diff.

anna marked an inline comment as done.Mar 24 2017, 8:22 AM
sanjoy accepted this revision.Mar 24 2017, 9:04 AM

Looks good!

test/Transforms/InstCombine/phi-select-constexpr.ll
1 ↗(On Diff #92951)

Should we rename this file now?

This revision is now accepted and ready to land.Mar 24 2017, 9:04 AM
sanjoy added inline comments.Mar 24 2017, 9:06 AM
lib/Transforms/InstCombine/InstructionCombining.cpp
915 ↗(On Diff #92951)

Actually, one more thing -- can we rewrite this as a positive test? That is, instead of checking what Inc cannot be, check that it is only allowed to be a ConstantInt?

(I'm fine doing that cleanup as a follow-on change.)

anna added inline comments.Mar 24 2017, 1:45 PM
lib/Transforms/InstCombine/InstructionCombining.cpp
915 ↗(On Diff #92951)

Will do.

test/Transforms/InstCombine/phi-select-constexpr.ll
1 ↗(On Diff #92951)

Maybe something like phi-select-const?

sanjoy added inline comments.Mar 24 2017, 1:49 PM
test/Transforms/InstCombine/phi-select-constexpr.ll
1 ↗(On Diff #92951)

How about phi-select-constant?

This revision was automatically updated to reflect the committed changes.
anna added inline comments.Mar 27 2017, 7:05 AM
test/Transforms/InstCombine/phi-select-constexpr.ll
1 ↗(On Diff #92951)

agreed. doing as an NFC.

anna marked 2 inline comments as done.Mar 28 2017, 2:49 AM

Both changes are done as follow up.