This is an archive of the discontinued LLVM Phabricator instance.

[InstCombine] Simplify funnel shifts based on demanded bits
AbandonedPublic

Authored by nikic on Nov 17 2018, 6:38 AM.

Details

Reviewers
spatel
RKSimon
Summary

The goal here is to simplify funnel shifts based on demanded or known bits. There are three parts to this change:

  • In InstCombineSimplifyDemanded, determine which bits in the operands are demanded based on the demanded bits of the result. Also determine which bits in the result are known based on known bits in the operands. This only works for known shift amount. This is the primary change.
  • SimplifyDemanded may replace operands of the funnel shift with undef. As such InstCombineCalls is taught to replace funnel shifts with one undef operand with either a shl or lshr. This is also limited to known shift amounts. In principle this can also be applied to variable shamt, but as this would require handling modular reduction, as well as zero shifts, it doesn't seem like a clear win.
  • Finally, the changes in InstructionSimplify are added to consistently handle all undef operands, including on shamt and on both inputs.

The background for this patch is https://github.com/rust-lang/rust/issues/56009, where a performance regression due to the switch to funnel shift intrinsics in Rust was reported. Unfortunately, this issue is not resolved by this patch (see final test cases in fsh.ll), because this would require simplifying a fsh with multiple users. There's special code in SimplifyMultipleUseDemandedBits that handles this for and/or/xor, but adding fsh to that list would require creating new shl/lshr instructions, which is not necessarily a win. Any ideas on how that case could be handled?

Diff Detail

Event Timeline

nikic created this revision.Nov 17 2018, 6:38 AM
alex added a subscriber: alex.Nov 17 2018, 6:56 AM
nagisa added a subscriber: nagisa.Nov 17 2018, 8:18 AM
nagisa added inline comments.
lib/Transforms/InstCombine/InstCombineCalls.cpp
2006

This probably could use a in-code comment about the reason why this replacing the funnel shifts with one undef operand to just a shift, so that somebody else wouldn’t replace it with a straight fshl(X, undef, C) -> undef (which would make a lot of sense in isolation) down the road.

Ditto for similar replacement just below.

test/Transforms/InstCombine/fsh.ll
276

This seems like it would be more appropriate for a bug report than a test?

Thanks for working on this! As with the saturated series, I'd prefer to split this into separate reviews/commits and have baseline tests committed ahead of any code changes. I think we can start with the instsimplify part, then instcombine, and finally demanded bits.

nikic abandoned this revision.Nov 24 2018, 7:21 AM

Abandoning in favor of finer-grained patches.