This is an archive of the discontinued LLVM Phabricator instance.

[DAGCombine] Simplify funnel shifts with undef/zero args to bitshifts
ClosedPublic

Authored by RKSimon on Feb 9 2019, 2:39 PM.

Details

Summary

Now that we have SimplifyDemandedBits support for funnel shifts (rL353539), we need to simplify funnel shifts back to bitshifts in cases where either argument has been folded to undef/zero.

Diff Detail

Repository
rL LLVM

Event Timeline

RKSimon created this revision.Feb 9 2019, 2:39 PM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 9 2019, 2:39 PM

Some thoughts.

lib/CodeGen/SelectionDAG/DAGCombiner.cpp
7119

What should be done if N2 is undef?
Pretend that it is 0, or replace the entire op with undef?

7148

Since we can replace undef with something, e.g. 0, we should do the same if it's 0 too.

7152

Same

7158–7159

Do ISD::SRL / ISD::SHL implicitly take the modulo of the shift amount?

7161

Same remark re 0.

7163

Same remark re 0.

nikic added a subscriber: nikic.Feb 10 2019, 1:13 AM
nikic added inline comments.
lib/CodeGen/SelectionDAG/DAGCombiner.cpp
7119

Pretending it is zero would be consistent with InstSimplify: https://github.com/llvm-mirror/llvm/blob/master/lib/Analysis/InstructionSimplify.cpp#L5129

Replacing with undef is not legal (consider for example N0=0, N1=0, which has zero as the only possible result, regardless of N2).

7148
RKSimon marked 2 inline comments as done.Feb 10 2019, 3:34 AM
RKSimon added inline comments.
lib/CodeGen/SelectionDAG/DAGCombiner.cpp
7148

Sure, I can add support for zero as well.

7158–7159

Ah good point! Will limit this to PowerOf2 cases that have passed the maskediszero above

lebedev.ri added inline comments.Feb 10 2019, 4:40 AM
lib/CodeGen/SelectionDAG/DAGCombiner.cpp
7158–7159

By modulo meant that funnel shift implicitly urem's the shift amount by the bitwidth.
So

%r = fshl %a, 0, %c
  =>
%r = shl %a, %c

is a miscompile.

I.e. this should be folded to

%r = fshl i32 %a, 0, %c
  =>
%cmodwidth = and i32 %c, 31 ; <- !!!
%r = shl i32 %a, %cmodwidth
RKSimon updated this revision to Diff 186153.Feb 10 2019, 8:07 AM
RKSimon retitled this revision from [DAGCombine] Simplify funnel shifts with undef args to bitshifts to [DAGCombine] Simplify funnel shifts with undef/zero args to bitshifts.
RKSimon edited the summary of this revision. (Show Details)

Add support for folding cases with zero arguments.

Limited the variable cases to where we know the shift is in range

I'd prefer to deal with the undef shift amounts in a separate patch as that's mostly separate from this fold logic.

lebedev.ri accepted this revision.Feb 10 2019, 8:19 AM

Looks ok to me.

lib/CodeGen/SelectionDAG/DAGCombiner.cpp
7161

Hmm, if FeatureSlowSHLD is set, or we have BMI2 (and thus sh[lr]x, not depending on %cl reg)?
Also, to be noted sub 32, n should get folded to neg n, IIRC.

This revision is now accepted and ready to land.Feb 10 2019, 8:19 AM
nikic added inline comments.Feb 10 2019, 8:26 AM
lib/CodeGen/SelectionDAG/DAGCombiner.cpp
7132

Maybe pass AllowUndefs=true, as we want to deal with both undef/zero anyway?

7147

Should be s/lshr/shl in the two latter comments.

7163

Shouldn't this be either setting the BitWidth - Log2_32(BitWidth) high bits, or maybe use getBitsSetFrom() instead? I think right now this is checking too few bits.

RKSimon marked an inline comment as done.Feb 10 2019, 8:54 AM
RKSimon added inline comments.
lib/CodeGen/SelectionDAG/DAGCombiner.cpp
7163

Nice catch!

This revision was automatically updated to reflect the committed changes.