Merging r231563 from adibiagio:
[DAGCombiner] Fix wrong folding of AND dag nodes.
This patch fixes the logic in the DAGCombiner that folds an AND node according
to rule: (and (X (load V)), C) > (X (load V))
An AND between a vector load 'X' and a constant build_vector 'C' can be folded
into the load itself only if we can prove that the AND operation is redundant.
The algorithm implemented by 'visitAND' firstly computes the splat value 'S'
from C, and then checks if S has the lower 'B' bits set (where B is the size in
bits of the vector element type). The algorithm takes into account also the
'undef' bits in the splat mask.
Unfortunately, the algorithm only worked under the assumption that the size of S
is a multiple of the vector element type. With this patch, we conservatively
avoid folding the AND if the splat bits are not compatible with the vector
element type.
Added X86 test andloadfold.ll
Differential Revision: http://reviews.llvm.org/D8085
gitsvnid: https://llvm.org/svn/llvmproject/llvm/branches/release_36@231702 911773080d340410b5e696231b3b80d8
Joerg Sonnenberger
5 years ago
2787  2787 
SplatBitSize = SplatBitSize * 2)

2788  2788 
SplatValue = SplatValue.shl(SplatBitSize);

2789  2789 

2790  
Constant = APInt::getAllOnesValue(BitWidth);

2791  
for (unsigned i = 0, n = SplatBitSize/BitWidth; i < n; ++i)

2792  
Constant &= SplatValue.lshr(i*BitWidth).zextOrTrunc(BitWidth);⏎

 2790 
// Make sure that variable 'Constant' is only set if 'SplatBitSize' is a⏎

 2791 
// multiple of 'BitWidth'. Otherwise, we could propagate a wrong value.

 2792 
if (SplatBitSize % BitWidth == 0) {

 2793 
Constant = APInt::getAllOnesValue(BitWidth);

 2794 
for (unsigned i = 0, n = SplatBitSize/BitWidth; i < n; ++i)

 2795 
Constant &= SplatValue.lshr(i*BitWidth).zextOrTrunc(BitWidth);

 2796 
}

2793  2797 
}

2794  2798 
}

2795  2799 

 0 
; RUN: llc mtriple=x86_64unknownunknown mcpu=generic < %s  FileCheck %s

 1 

 2 
; Verify that the DAGCombiner doesn't wrongly remove the 'and' from the dag.

 3 

 4 
define i8 @foo(<4 x i8>* %V) {

 5 
; CHECKLABEL: foo:

 6 
; CHECK: pand

 7 
; CHECK: ret

 8 
entry:

 9 
%Vp = bitcast <4 x i8>* %V to <3 x i8>*

 10 
%V3i8 = load <3 x i8>* %Vp, align 4

 11 
%0 = and <3 x i8> %V3i8,

 12 
%1 = extractelement <3 x i8> %0, i64 2

 13 
ret i8 %1

 14 
}
