This is an archive of the discontinued LLVM Phabricator instance.

[InstCombine] enhance vector bitwise select matching
ClosedPublic

Authored by spatel on Nov 2 2021, 10:58 AM.

Details

Summary

(Cond & C) | (~bitcast(Cond) & D) --> bitcast (select Cond, (bc C), (bc D))

This is part of fixing:
https://llvm.org/PR34047

That report shows a case where a bitcast is sitting between the select condition candidate and its 'not' value due to current cast canonicalization rules.
There's a restriction that might be violated in existing matching, but I still need to investigate if that is possible -
Alive2 shows we can only do this transform safely when the bitcast is from narrow to wide vector elements:
https://alive2.llvm.org/ce/z/Hf66qh

Diff Detail

Event Timeline

spatel created this revision.Nov 2 2021, 10:58 AM
spatel requested review of this revision.Nov 2 2021, 10:58 AM
Herald added a project: Restricted Project. · View Herald TranscriptNov 2 2021, 10:58 AM
spatel updated this revision to Diff 384414.Nov 3 2021, 6:18 AM

Patch updated:
No code changes, but added phase ordering tests for the motivating functions from PR34047.
I think there's still some potential for code like that (particularly 'abs') to find cracks in combining, so we want make sure it doesn't regress with changes in canonical form.

Is there test coverage for the edge-case of selecting between vectors themselves? (condition is i1)

Is there test coverage for the edge-case of selecting between vectors themselves? (condition is i1)

I'm not imagining the sequence that you are suggesting.
The condition can't be scalar i1 if the other operands are integer vectors. It has to be a vector of the same type or a bitcast from a type with at least as many bits as the other operands.

We have existing tests with bool types starting around line 367 (@bools). @vec_of_bools is at line 461 - do any of those cover it?

lebedev.ri accepted this revision.Nov 8 2021, 9:56 AM

LGMT

llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
2372

What happens for scalable vectors? I'm not seeing any check against that.

This revision is now accepted and ready to land.Nov 8 2021, 9:56 AM
spatel added a subscriber: dmgreen.Nov 8 2021, 12:16 PM
spatel added inline comments.
llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
2372

I couldn't come up with a way to get in here with a scalable vector because of the 'not' instruction requirement. But let me know if you see a way to do that (ping @dmgreen too).

I can add an assert for scalable vector type if I got that right.

dmgreen added inline comments.Nov 9 2021, 3:14 AM
llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
2372

Do you mean a Not with scalable vectors? Or some more complicated combination of instructions?

There doesn't look to be a way to generate the SVE NOT instruction at least, from the tests we have. I think it would need to be from a xor x, (shuffle (insert poison, -1, 0), zeroinit) if there was one, but I've not tried to see if m_Not detects that or not.
Like here for a predicate vector, the same thing would apply for larger vector types:
https://github.com/llvm/llvm-project/blob/32a4a883f647c314a42ebd572e36aaf60ffe9889/llvm/test/Transforms/InstCombine/select.ll#L102

If that doesn't work already, an assert sounds useful in case someone makes that work in the future.

spatel added inline comments.Nov 9 2021, 4:58 AM
llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
2372

Yes, I didn't see a way to specify/match the -1 constant in a 'not' of a scalable vector.
But looking around at similar code, I think we can future-proof this block for a scalable-vector-aware m_Not. I'll update it.
(Although there's another cast in code around here that assumes a FixedVectorType.)

spatel updated this revision to Diff 385782.Nov 9 2021, 5:03 AM

Patch updated:
Use general VectorType APIs to make the transform safe for scalable vectors. It is not possible to write a test for this currently -- and surrounding code would likely crash -- but this should work with matchers (m_Not) that are made more flexible in the future.

lebedev.ri accepted this revision.Nov 9 2021, 5:06 AM
This revision was automatically updated to reflect the committed changes.
yubing added a subscriber: yubing.Nov 9 2021, 8:35 PM
yubing added inline comments.
llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
2313

I think we should check if A is Integer vector after A = peekThroughBitcast(A);
A might be %astype = bitcast <4 x float> %c to <4 x i32>
when you peek through A, A become <4 x float> %c which can't be handled with ComputeNumSignBits.

spatel added inline comments.Nov 10 2021, 6:00 AM
llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
2313

Yes - this can crash. Thanks for catching that!
I'll add a test and update.

spatel added inline comments.Nov 10 2021, 7:08 AM
llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
2313

Updated here:
67299aa84f50