[DAGcombiner] Fix incorrect sinking of a truncate into the operand of a shift.
authorAndrea Di Biagio <Andrea_DiBiagio@sn.scee.net>
Fri, 2 Sep 2016 11:29:09 +0000 (11:29 +0000)
committerAndrea Di Biagio <Andrea_DiBiagio@sn.scee.net>
Fri, 2 Sep 2016 11:29:09 +0000 (11:29 +0000)
commitfd503e5af306b6aad3dd3d7005ff86e008aad2dd
tree3ddd2a0829f4cb2d1e78e3afb67801f501b6718d
parent7454145785ba90b414ab31bb8b73c86d14a062d8
[DAGcombiner] Fix incorrect sinking of a truncate into the operand of a shift.

This fixes a regression introduced by revision 268094.
Revision 268094 added the following dag combine rule:
// trunc (shl x, K) -> shl (trunc x), K => K < vt.size / 2

That rule converts a truncate of a shift-by-constant into a shift of a truncated
value. We do this only if the shift count is less than half the size in bits of
the truncated value (K < vt.size / 2).

The problem is that the constraint on the shift count is incorrect, so the rule
doesn't work well in some cases involving vector types. The combine rule should
have been written instead like this:
// trunc (shl x, K) -> shl (trunc x), K => K < vt.getScalarSizeInBits()

Basically, if K is smaller than the "scalar size in bits" of the truncated value
then we know that by "sinking" the truncate into the operand of the shift we
would never accidentally make the shift undefined.

This patch fixes the check on the shift count, and adds test cases to make sure
that we don't regress the behavior.

Differential Revision: https://reviews.llvm.org/D24154

llvm-svn: 280482
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
llvm/test/CodeGen/X86/reduce-trunc-shl.ll