From 53b4d83b63148d620469d0ecc4152dfcba97fb20 Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Tue, 22 Apr 2014 07:40:34 +0000 Subject: [PATCH] [X86] Don't use BZHI for short masks (>=32 bits). Thanks to Ben Kramer for the review. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@206869 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86ISelLowering.cpp | 8 +++++--- test/CodeGen/X86/bmi.ll | 19 +++++++++---------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 47df663bcdc..8ed95d5412e 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -18507,13 +18507,15 @@ static SDValue PerformAndCombine(SDNode *N, SelectionDAG &DAG, // 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 (VT == MVT::i64 && Subtarget->hasBMI2()) { if (ConstantSDNode *C = dyn_cast(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)); + // Only use BZHI for immediates that are too large for an AND: + if (LZ > 32) + return DAG.getNode(X86ISD::BZHI, DL, VT, N0, + DAG.getConstant(LZ, MVT::i8)); } } } diff --git a/test/CodeGen/X86/bmi.ll b/test/CodeGen/X86/bmi.ll index c04fe9b5cfa..a70720926de 100644 --- a/test/CodeGen/X86/bmi.ll +++ b/test/CodeGen/X86/bmi.ll @@ -216,22 +216,21 @@ 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, %e[[ARG1:di|cx]], %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, %r[[ARG1]], %rax +; CHECK: bzhiq %rax, %r[[ARG1:di|cx]], %rax +} + +define i64 @bzhi64_small_constant_mask(i64 %x) #0 { +entry: + %and = and i64 %x, 2147483647 + ret i64 %and +; CHECK-LABEL: bzhi64_small_constant_mask: +; CHECK: andq $2147483647, %r[[ARG1]] } define i32 @blsi32(i32 %x) nounwind readnone { -- 2.34.1