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.
Details
Diff Detail
- Repository
- rL LLVM
Event Timeline
Some thoughts.
lib/CodeGen/SelectionDAG/DAGCombiner.cpp | ||
---|---|---|
7119 | What should be done if N2 is 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. |
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 | This would also be consistent with InstCombine: https://github.com/llvm-mirror/llvm/blob/master/lib/Transforms/InstCombine/InstCombineCalls.cpp#L1996 |
lib/CodeGen/SelectionDAG/DAGCombiner.cpp | ||
---|---|---|
7158–7159 | By modulo meant that funnel shift implicitly urem's the shift amount by the bitwidth. %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 |
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.
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)? |
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. |
lib/CodeGen/SelectionDAG/DAGCombiner.cpp | ||
---|---|---|
7163 | Nice catch! |
What should be done if N2 is undef?
Pretend that it is 0, or replace the entire op with undef?