llvm.org GIT mirror llvm / f69bb5e
[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> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@206738 91177308-0d34-0410-b5e6-96231b3b80d8 Lang Hames 6 years ago
2 changed file(s) with 32 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
1850218502 }
1850318503 } // BEXTR
1850418504
18505 // Check for BZHI with contiguous mask: (and X, 0x0..0f..f)
18506 // This should be checked after BEXTR - when X is a shift, a BEXTR is
18507 // preferrable.
18508 if (Subtarget->hasBMI2()) {
18509 if (ConstantSDNode *C = dyn_cast(N1)) {
18510 uint64_t Mask = C->getZExtValue();
18511 if (isMask_64(Mask)) {
18512 unsigned LZ = CountTrailingOnes_64(Mask);
18513 return DAG.getNode(X86ISD::BZHI, DL, VT, N0,
18514 DAG.getConstant(LZ, MVT::i8));
18515 }
18516 }
18517 }
18518
1850518519 return SDValue();
1850618520 }
1850718521
215215 ; CHECK: bzhiq
216216 }
217217
218 define i32 @bzhi32_constant_mask(i32 %x) #0 {
219 entry:
220 %and = and i32 %x, 1073741823
221 ret i32 %and
222 ; CHECK-LABEL: bzhi32_constant_mask:
223 ; CHECK: movb $30, %al
224 ; CHECK: bzhil %eax, %edi, %eax
225 }
226
227 define i64 @bzhi64_constant_mask(i64 %x) #0 {
228 entry:
229 %and = and i64 %x, 4611686018427387903
230 ret i64 %and
231 ; CHECK-LABEL: bzhi64_constant_mask:
232 ; CHECK: movb $62, %al
233 ; CHECK: bzhiq %rax, %rdi, %rax
234 }
235
218236 define i32 @blsi32(i32 %x) nounwind readnone {
219237 %tmp = sub i32 0, %x
220238 %tmp2 = and i32 %x, %tmp