forked from OSchip/llvm-project
[X86] ISEL (and X, <constant mask>) to BZHI when BMI2 is available.
Generating BZHI in the variable mask case, i.e. (and X, (sub (shl 1, N), 1)), was already supported, but we were missing the constant-mask case. This patch fixes that. <rdar://problem/15480077> llvm-svn: 206738
This commit is contained in:
parent
589441820e
commit
5aa6ee80b6
|
@ -18503,6 +18503,20 @@ static SDValue PerformAndCombine(SDNode *N, SelectionDAG &DAG,
|
|||
}
|
||||
} // BEXTR
|
||||
|
||||
// Check for BZHI with contiguous mask: (and X, 0x0..0f..f)
|
||||
// This should be checked after BEXTR - when X is a shift, a BEXTR is
|
||||
// preferrable.
|
||||
if (Subtarget->hasBMI2()) {
|
||||
if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N1)) {
|
||||
uint64_t Mask = C->getZExtValue();
|
||||
if (isMask_64(Mask)) {
|
||||
unsigned LZ = CountTrailingOnes_64(Mask);
|
||||
return DAG.getNode(X86ISD::BZHI, DL, VT, N0,
|
||||
DAG.getConstant(LZ, MVT::i8));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return SDValue();
|
||||
}
|
||||
|
||||
|
|
|
@ -216,6 +216,24 @@ entry:
|
|||
; CHECK: bzhiq
|
||||
}
|
||||
|
||||
define i32 @bzhi32_constant_mask(i32 %x) #0 {
|
||||
entry:
|
||||
%and = and i32 %x, 1073741823
|
||||
ret i32 %and
|
||||
; CHECK-LABEL: bzhi32_constant_mask:
|
||||
; CHECK: movb $30, %al
|
||||
; CHECK: bzhil %eax, %edi, %eax
|
||||
}
|
||||
|
||||
define i64 @bzhi64_constant_mask(i64 %x) #0 {
|
||||
entry:
|
||||
%and = and i64 %x, 4611686018427387903
|
||||
ret i64 %and
|
||||
; CHECK-LABEL: bzhi64_constant_mask:
|
||||
; CHECK: movb $62, %al
|
||||
; CHECK: bzhiq %rax, %rdi, %rax
|
||||
}
|
||||
|
||||
define i32 @blsi32(i32 %x) nounwind readnone {
|
||||
%tmp = sub i32 0, %x
|
||||
%tmp2 = and i32 %x, %tmp
|
||||
|
|
Loading…
Reference in New Issue