This is an archive of the discontinued LLVM Phabricator instance.

[X86] Don't use known bits to simplify shuffles.
ClosedPublic

Authored by efriedma on Jul 17 2021, 11:29 AM.

Details

Summary

This reverts commit 2a419a0b9957ebac9e11e4b43bc9fbe42a9207df.

The result of a shufflevector must not propagate poison from any element other than the one noted in the shuffle mask.

The regressions outside of fptoui-may-overflow.ll can probably be recovered some other way.

See https://reviews.llvm.org/D106053 for more background.

Diff Detail

Event Timeline

efriedma created this revision.Jul 17 2021, 11:29 AM
efriedma requested review of this revision.Jul 17 2021, 11:29 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 17 2021, 11:29 AM
efriedma updated this revision to Diff 359577.Jul 17 2021, 12:23 PM

The result of a shufflevector must not propagate poison from any element other than the one noted in the shuffle mask.
However, this means the 2a419a0b transform isn't safe: if a lane in the result of a shufflevector is supposed to be zero, it has to actually be zero, not zero-or-poison.

Sorry, I still not much understand, where we got the poison value in following transformation.
computeKnownBits will only meet "AssertZext %f i8", how does it know there will be poison value ?

%f = fptoui <4 x float> %arg to <4 x i8> -->   fptosi <4 x float> %1 to <4 x i16> + AssertZext  %f,  i8

The result of a shufflevector must not propagate poison from any element other than the one noted in the shuffle mask.
However, this means the 2a419a0b transform isn't safe: if a lane in the result of a shufflevector is supposed to be zero, it has to actually be zero, not zero-or-poison.

Sorry, I still not much understand, where we got the poison value in following transformation.
computeKnownBits will only meet "AssertZext %f i8", how does it know there will be poison value ?

%f = fptoui <4 x float> %arg to <4 x i8> -->   fptosi <4 x float> %1 to <4 x i16> + AssertZext  %f,  i8

It doesn't know there will be poison, it just knows that there COULD be poison.

Unless there's a way to prove that the source float data is 0.0f<x<256.0f then we have to fail safe and assume it could contain poison under some circumstances.

I think we're going to have to add something to the SelectionDAG::computeKnownBits/ComputeNumSignBits doxygen comments explaining that the value could have the determined known/signbits BUT it could be a poison value (or if a vector any demanded element could be poison value).

I think we're going to have to add something to the SelectionDAG::computeKnownBits/ComputeNumSignBits doxygen comments explaining that the value could have the determined known/signbits BUT it could be a poison value (or if a vector any demanded element could be poison value).

Sure, probably all these functions could use a comment like that: computeKnownBits, ComputeNumSignBits, haveNoCommonBitsSet, isKnownToBeAPowerOfTwo, computeOverflowKind, MaskedValueIsAllOnes, MaskedValueIsZero, SignBitIsZero, isKnownNeverNaN, isSplatValue, etc. And probably the ValueTracking equivalents, too. (Some of the ValueTracking functions already have comments which subtly indicate this, e.g. "exactly one bit set when defined.")

OK, I'll put together a patch updating the comments.

I think this patch gets to the real problem (although there might be other similar issues) and helps us avoid the avoidable nasty regressions from D106053 - does anyone else have any thoughts?

I think we're going to have to add something to the SelectionDAG::computeKnownBits/ComputeNumSignBits doxygen comments explaining that the value could have the determined known/signbits BUT it could be a poison value (or if a vector any demanded element could be poison value).

Sure, probably all these functions could use a comment like that: computeKnownBits, ComputeNumSignBits, haveNoCommonBitsSet, isKnownToBeAPowerOfTwo, computeOverflowKind, MaskedValueIsAllOnes, MaskedValueIsZero, SignBitIsZero, isKnownNeverNaN, isSplatValue, etc. And probably the ValueTracking equivalents, too. (Some of the ValueTracking functions already have comments which subtly indicate this, e.g. "exactly one bit set when defined.")

+1, this clarification looks great to me.

I wish we can first commit this patch to solve our urgent project fail.

@RKSimon, Or Maybe we can replace the AssertZext with a new node AssertZextOrPoison in "May Be Poison" case ? (If it is much easier to change all the existed optimizations. )

xiangzhangllvm accepted this revision.Jul 18 2021, 6:07 PM
This revision is now accepted and ready to land.Jul 18 2021, 6:07 PM
This revision was landed with ongoing or failed builds.Jul 18 2021, 6:15 PM
This revision was automatically updated to reflect the committed changes.

Thank you very much!