Skip to content

Commit 0786f2d

Browse files
authored
[X86] LowerAndToBT - convert to SDPatternMatch (llvm#181696)
Fixes an issue where a partial pattern (and then early-out) prevented a later match Prep work for llvm#147216
1 parent ecd25af commit 0786f2d

2 files changed

Lines changed: 37 additions & 50 deletions

File tree

llvm/lib/Target/X86/X86ISelLowering.cpp

Lines changed: 33 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -24365,55 +24365,42 @@ X86TargetLowering::BuildSDIVPow2(SDNode *N, const APInt &Divisor,
2436524365
/// Returns the BT node and the condition code needed to use it.
2436624366
static SDValue LowerAndToBT(SDValue And, ISD::CondCode CC, const SDLoc &dl,
2436724367
SelectionDAG &DAG, X86::CondCode &X86CC) {
24368+
using namespace SDPatternMatch;
2436824369
assert(And.getOpcode() == ISD::AND && "Expected AND node!");
24369-
SDValue Op0 = And.getOperand(0);
24370-
SDValue Op1 = And.getOperand(1);
24371-
if (Op0.getOpcode() == ISD::TRUNCATE)
24372-
Op0 = Op0.getOperand(0);
24373-
if (Op1.getOpcode() == ISD::TRUNCATE)
24374-
Op1 = Op1.getOperand(0);
24375-
24376-
SDValue Src, BitNo;
24377-
if (Op1.getOpcode() == ISD::SHL)
24378-
std::swap(Op0, Op1);
24379-
if (Op0.getOpcode() == ISD::SHL) {
24380-
if (isOneConstant(Op0.getOperand(0))) {
24381-
// If we looked past a truncate, check that it's only truncating away
24382-
// known zeros.
24383-
unsigned BitWidth = Op0.getValueSizeInBits();
24384-
unsigned AndBitWidth = And.getValueSizeInBits();
24385-
if (BitWidth > AndBitWidth) {
24386-
KnownBits Known = DAG.computeKnownBits(Op0);
24387-
if (Known.countMinLeadingZeros() < BitWidth - AndBitWidth)
24388-
return SDValue();
24389-
}
24390-
Src = Op1;
24391-
BitNo = Op0.getOperand(1);
24392-
}
24393-
} else if (Op1.getOpcode() == ISD::Constant) {
24394-
ConstantSDNode *AndRHS = cast<ConstantSDNode>(Op1);
24395-
uint64_t AndRHSVal = AndRHS->getZExtValue();
24396-
SDValue AndLHS = Op0;
24397-
24398-
if (AndRHSVal == 1 && AndLHS.getOpcode() == ISD::SRL) {
24399-
Src = AndLHS.getOperand(0);
24400-
BitNo = AndLHS.getOperand(1);
24401-
} else {
24402-
// Use BT if the immediate can't be encoded in a TEST instruction or we
24403-
// are optimizing for size and the immedaite won't fit in a byte.
24404-
bool OptForSize = DAG.shouldOptForSize();
24405-
if ((!isUInt<32>(AndRHSVal) || (OptForSize && !isUInt<8>(AndRHSVal))) &&
24406-
isPowerOf2_64(AndRHSVal)) {
24407-
Src = AndLHS;
24408-
BitNo = DAG.getConstant(Log2_64_Ceil(AndRHSVal), dl,
24409-
Src.getValueType());
24410-
}
24370+
assert(And.getValueType().isScalarInteger() && "Scalar type expected");
24371+
24372+
APInt AndRHSVal;
24373+
SDValue Shl, Src, BitNo;
24374+
if (sd_match(And,
24375+
m_And(m_TruncOrSelf(m_Value(Src)),
24376+
m_TruncOrSelf(m_AllOf(m_Value(Shl),
24377+
m_Shl(m_One(), m_Value(BitNo))))))) {
24378+
// If we looked past a truncate, check that it's only truncating away known
24379+
// zeros.
24380+
unsigned BitWidth = Shl.getValueSizeInBits();
24381+
unsigned AndBitWidth = And.getValueSizeInBits();
24382+
if (BitWidth > AndBitWidth) {
24383+
KnownBits Known = DAG.computeKnownBits(Shl);
24384+
if (Known.countMinLeadingZeros() < (BitWidth - AndBitWidth))
24385+
return SDValue();
2441124386
}
24412-
}
24413-
24414-
// No patterns found, give up.
24415-
if (!Src.getNode())
24387+
} else if (sd_match(And,
24388+
m_And(m_TruncOrSelf(m_Srl(m_Value(Src), m_Value(BitNo))),
24389+
m_One()))) {
24390+
// ((Src >> BitNo) & 1) ==/!= 0
24391+
} else if (sd_match(And, m_And(m_TruncOrSelf(m_Value(Src)),
24392+
m_ConstInt(AndRHSVal)))) {
24393+
// Use BT if the immediate can't be encoded in a TEST instruction or we
24394+
// are optimizing for size and the immediate won't fit in a byte.
24395+
bool OptForSize = DAG.shouldOptForSize();
24396+
if (!AndRHSVal.isPowerOf2() || AndRHSVal.isIntN(OptForSize ? 8 : 32))
24397+
return SDValue();
24398+
// (Src & ConstPow2) ==/!= 0
24399+
BitNo = DAG.getConstant(AndRHSVal.ceilLogBase2(), dl, Src.getValueType());
24400+
} else {
24401+
// No patterns found, give up.
2441624402
return SDValue();
24403+
}
2441724404

2441824405
// Remove any bit flip.
2441924406
if (isBitwiseNot(Src)) {

llvm/test/CodeGen/X86/hoist-and-by-const-from-lshr-in-eqcmp-zero.ll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -366,15 +366,15 @@ define i1 @scalar_i64_signbit_eq(i64 %x, i64 %y) nounwind {
366366
; X64-BMI1-NEXT: movq %rsi, %rcx
367367
; X64-BMI1-NEXT: # kill: def $cl killed $cl killed $rcx
368368
; X64-BMI1-NEXT: shlq %cl, %rdi
369-
; X64-BMI1-NEXT: shrq $63, %rdi
370-
; X64-BMI1-NEXT: sete %al
369+
; X64-BMI1-NEXT: btq $63, %rdi
370+
; X64-BMI1-NEXT: setae %al
371371
; X64-BMI1-NEXT: retq
372372
;
373373
; X64-BMI2-LABEL: scalar_i64_signbit_eq:
374374
; X64-BMI2: # %bb.0:
375375
; X64-BMI2-NEXT: shlxq %rsi, %rdi, %rax
376-
; X64-BMI2-NEXT: shrq $63, %rax
377-
; X64-BMI2-NEXT: sete %al
376+
; X64-BMI2-NEXT: btq $63, %rax
377+
; X64-BMI2-NEXT: setae %al
378378
; X64-BMI2-NEXT: retq
379379
%t0 = lshr i64 9223372036854775808, %y
380380
%t1 = and i64 %t0, %x

0 commit comments

Comments
 (0)