mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-04-11 16:37:42 +00:00
[X86] Use tablegen instead of DAG combines to match BZHI instructions, as
suggested by Ben Kramer in review of r206738. Thanks again Ben! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@206879 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
59d57db258
commit
390592d968
@ -14367,7 +14367,6 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const {
|
||||
case X86ISD::OR: return "X86ISD::OR";
|
||||
case X86ISD::XOR: return "X86ISD::XOR";
|
||||
case X86ISD::AND: return "X86ISD::AND";
|
||||
case X86ISD::BZHI: return "X86ISD::BZHI";
|
||||
case X86ISD::BEXTR: return "X86ISD::BEXTR";
|
||||
case X86ISD::MUL_IMM: return "X86ISD::MUL_IMM";
|
||||
case X86ISD::PTEST: return "X86ISD::PTEST";
|
||||
@ -18453,40 +18452,13 @@ static SDValue PerformAndCombine(SDNode *N, SelectionDAG &DAG,
|
||||
if (R.getNode())
|
||||
return R;
|
||||
|
||||
// Create BEXTR and BZHI instructions
|
||||
// BZHI is X & ((1 << Y) - 1)
|
||||
// Create BEXTR instructions
|
||||
// BEXTR is ((X >> imm) & (2**size-1))
|
||||
if (VT == MVT::i32 || VT == MVT::i64) {
|
||||
SDValue N0 = N->getOperand(0);
|
||||
SDValue N1 = N->getOperand(1);
|
||||
SDLoc DL(N);
|
||||
|
||||
if (Subtarget->hasBMI2()) {
|
||||
// Check for (and (add (shl 1, Y), -1), X)
|
||||
if (N0.getOpcode() == ISD::ADD && isAllOnes(N0.getOperand(1))) {
|
||||
SDValue N00 = N0.getOperand(0);
|
||||
if (N00.getOpcode() == ISD::SHL) {
|
||||
SDValue N001 = N00.getOperand(1);
|
||||
assert(N001.getValueType() == MVT::i8 && "unexpected type");
|
||||
ConstantSDNode *C = dyn_cast<ConstantSDNode>(N00.getOperand(0));
|
||||
if (C && C->getZExtValue() == 1)
|
||||
return DAG.getNode(X86ISD::BZHI, DL, VT, N1, N001);
|
||||
}
|
||||
}
|
||||
|
||||
// Check for (and X, (add (shl 1, Y), -1))
|
||||
if (N1.getOpcode() == ISD::ADD && isAllOnes(N1.getOperand(1))) {
|
||||
SDValue N10 = N1.getOperand(0);
|
||||
if (N10.getOpcode() == ISD::SHL) {
|
||||
SDValue N101 = N10.getOperand(1);
|
||||
assert(N101.getValueType() == MVT::i8 && "unexpected type");
|
||||
ConstantSDNode *C = dyn_cast<ConstantSDNode>(N10.getOperand(0));
|
||||
if (C && C->getZExtValue() == 1)
|
||||
return DAG.getNode(X86ISD::BZHI, DL, VT, N0, N101);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check for BEXTR.
|
||||
if ((Subtarget->hasBMI() || Subtarget->hasTBM()) &&
|
||||
(N0.getOpcode() == ISD::SRA || N0.getOpcode() == ISD::SRL)) {
|
||||
@ -18504,22 +18476,6 @@ 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 (VT == MVT::i64 && Subtarget->hasBMI2()) {
|
||||
if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N1)) {
|
||||
uint64_t Mask = C->getZExtValue();
|
||||
if (isMask_64(Mask)) {
|
||||
unsigned LZ = CountTrailingOnes_64(Mask);
|
||||
// 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return SDValue();
|
||||
}
|
||||
|
||||
|
@ -291,7 +291,6 @@ namespace llvm {
|
||||
ADD, SUB, ADC, SBB, SMUL,
|
||||
INC, DEC, OR, XOR, AND,
|
||||
|
||||
BZHI, // BZHI - Zero high bits
|
||||
BEXTR, // BEXTR - Bit field extract
|
||||
|
||||
UMUL, // LOW, HI, FLAGS = umul LHS, RHS
|
||||
|
@ -2104,18 +2104,36 @@ let Predicates = [HasBMI2], Defs = [EFLAGS] in {
|
||||
int_x86_bmi_bzhi_64, loadi64>, VEX_W;
|
||||
}
|
||||
|
||||
def : Pat<(X86bzhi GR32:$src1, GR8:$src2),
|
||||
(BZHI32rr GR32:$src1,
|
||||
(INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
|
||||
def : Pat<(X86bzhi (loadi32 addr:$src1), GR8:$src2),
|
||||
(BZHI32rm addr:$src1,
|
||||
(INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
|
||||
def : Pat<(X86bzhi GR64:$src1, GR8:$src2),
|
||||
(BZHI64rr GR64:$src1,
|
||||
(INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
|
||||
def : Pat<(X86bzhi (loadi64 addr:$src1), GR8:$src2),
|
||||
(BZHI64rm addr:$src1,
|
||||
(INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
|
||||
|
||||
def CountTrailingOnes : SDNodeXForm<imm, [{
|
||||
// Count the trailing ones in the immediate.
|
||||
return getI8Imm(CountTrailingOnes_64(N->getZExtValue()));
|
||||
}]>;
|
||||
|
||||
def BZHIMask : ImmLeaf<i64, [{
|
||||
return isMask_64(Imm) && (CountTrailingOnes_64(Imm) > 32);
|
||||
}]>;
|
||||
|
||||
def : Pat<(and GR64:$src, BZHIMask:$mask),
|
||||
(BZHI64rr GR64:$src,
|
||||
(INSERT_SUBREG (i64 (IMPLICIT_DEF)),
|
||||
(MOV8ri (CountTrailingOnes imm:$mask)), sub_8bit))>;
|
||||
|
||||
def : Pat<(and GR32:$src, (add (shl 1, GR8:$lz), -1)),
|
||||
(BZHI32rr GR32:$src,
|
||||
(INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
|
||||
|
||||
def : Pat<(and (loadi32 addr:$src), (add (shl 1, GR8:$lz), -1)),
|
||||
(BZHI32rm addr:$src,
|
||||
(INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
|
||||
|
||||
def : Pat<(and GR64:$src, (add (shl 1, GR8:$lz), -1)),
|
||||
(BZHI64rr GR64:$src,
|
||||
(INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
|
||||
|
||||
def : Pat<(and (loadi64 addr:$src), (add (shl 1, GR8:$lz), -1)),
|
||||
(BZHI64rm addr:$src,
|
||||
(INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
|
||||
|
||||
let Predicates = [HasBMI] in {
|
||||
def : Pat<(X86bextr GR32:$src1, GR32:$src2),
|
||||
|
Loading…
x
Reference in New Issue
Block a user