mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-05 13:09:10 +00:00
Generalize BFI isel lowering a bit.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@121714 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
94c58a0906
commit
30fb13f97a
@ -4713,57 +4713,43 @@ static SDValue PerformORCombine(SDNode *N,
|
|||||||
if (VT != MVT::i32)
|
if (VT != MVT::i32)
|
||||||
return SDValue();
|
return SDValue();
|
||||||
|
|
||||||
|
SDValue N00 = N0.getOperand(0);
|
||||||
|
|
||||||
// The value and the mask need to be constants so we can verify this is
|
// The value and the mask need to be constants so we can verify this is
|
||||||
// actually a bitfield set. If the mask is 0xffff, we can do better
|
// actually a bitfield set. If the mask is 0xffff, we can do better
|
||||||
// via a movt instruction, so don't use BFI in that case.
|
// via a movt instruction, so don't use BFI in that case.
|
||||||
ConstantSDNode *C = dyn_cast<ConstantSDNode>(N0.getOperand(1));
|
SDValue MaskOp = N0.getOperand(1);
|
||||||
if (!C)
|
ConstantSDNode *MaskC = dyn_cast<ConstantSDNode>(MaskOp);
|
||||||
|
if (!MaskC)
|
||||||
return SDValue();
|
return SDValue();
|
||||||
unsigned Mask = C->getZExtValue();
|
unsigned Mask = MaskC->getZExtValue();
|
||||||
if (Mask == 0xffff)
|
if (Mask == 0xffff)
|
||||||
return SDValue();
|
return SDValue();
|
||||||
SDValue Res;
|
SDValue Res;
|
||||||
// Case (1): or (and A, mask), val => ARMbfi A, val, mask
|
// Case (1): or (and A, mask), val => ARMbfi A, val, mask
|
||||||
if ((C = dyn_cast<ConstantSDNode>(N1))) {
|
ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1);
|
||||||
unsigned Val = C->getZExtValue();
|
if (N1C) {
|
||||||
|
unsigned Val = N1C->getZExtValue();
|
||||||
if ((Val & ~Mask) != Val)
|
if ((Val & ~Mask) != Val)
|
||||||
return SDValue();
|
return SDValue();
|
||||||
|
|
||||||
if (ARM::isBitFieldInvertedMask(Mask)) {
|
if (ARM::isBitFieldInvertedMask(Mask)) {
|
||||||
Val >>= CountTrailingZeros_32(~Mask);
|
Val >>= CountTrailingZeros_32(~Mask);
|
||||||
|
|
||||||
Res = DAG.getNode(ARMISD::BFI, DL, VT, N0.getOperand(0),
|
Res = DAG.getNode(ARMISD::BFI, DL, VT, N00,
|
||||||
DAG.getConstant(Val, MVT::i32),
|
DAG.getConstant(Val, MVT::i32),
|
||||||
DAG.getConstant(Mask, MVT::i32));
|
DAG.getConstant(Mask, MVT::i32));
|
||||||
|
|
||||||
// Do not add new nodes to DAG combiner worklist.
|
// Do not add new nodes to DAG combiner worklist.
|
||||||
DCI.CombineTo(N, Res, false);
|
DCI.CombineTo(N, Res, false);
|
||||||
} else if (N0.getOperand(0).getOpcode() == ISD::SHL &&
|
|
||||||
isa<ConstantSDNode>(N0.getOperand(0).getOperand(1)) &&
|
|
||||||
ARM::isBitFieldInvertedMask(~Mask)) {
|
|
||||||
// Case (3): or (and (shl A, #shamt), mask), B => ARMbfi B, A, ~mask
|
|
||||||
// where lsb(mask) == #shamt
|
|
||||||
SDValue ShAmt = N0.getOperand(0).getOperand(1);
|
|
||||||
unsigned ShAmtC = cast<ConstantSDNode>(ShAmt)->getZExtValue();
|
|
||||||
unsigned LSB = CountTrailingZeros_32(Mask);
|
|
||||||
if (ShAmtC != LSB)
|
|
||||||
return SDValue();
|
return SDValue();
|
||||||
//unsigned Width = (32 - CountLeadingZeros_32(Mask)) - LSB;
|
|
||||||
|
|
||||||
Res = DAG.getNode(ARMISD::BFI, DL, VT, N1,
|
|
||||||
N0.getOperand(0).getOperand(0),
|
|
||||||
DAG.getConstant(~Mask, MVT::i32));
|
|
||||||
|
|
||||||
// Do not add new nodes to DAG combiner worklist.
|
|
||||||
DCI.CombineTo(N, Res, false);
|
|
||||||
}
|
}
|
||||||
} else if (N1.getOpcode() == ISD::AND) {
|
} else if (N1.getOpcode() == ISD::AND) {
|
||||||
// case (2) or (and A, mask), (and B, mask2) => ARMbfi A, (lsr B, amt), mask
|
// case (2) or (and A, mask), (and B, mask2) => ARMbfi A, (lsr B, amt), mask
|
||||||
C = dyn_cast<ConstantSDNode>(N1.getOperand(1));
|
ConstantSDNode *N11C = dyn_cast<ConstantSDNode>(N1.getOperand(1));
|
||||||
if (!C)
|
if (!N11C)
|
||||||
return SDValue();
|
return SDValue();
|
||||||
unsigned Mask2 = C->getZExtValue();
|
unsigned Mask2 = N11C->getZExtValue();
|
||||||
|
|
||||||
if (ARM::isBitFieldInvertedMask(Mask) &&
|
if (ARM::isBitFieldInvertedMask(Mask) &&
|
||||||
ARM::isBitFieldInvertedMask(~Mask2) &&
|
ARM::isBitFieldInvertedMask(~Mask2) &&
|
||||||
@ -4777,10 +4763,11 @@ static SDValue PerformORCombine(SDNode *N,
|
|||||||
unsigned lsb = CountTrailingZeros_32(Mask2);
|
unsigned lsb = CountTrailingZeros_32(Mask2);
|
||||||
Res = DAG.getNode(ISD::SRL, DL, VT, N1.getOperand(0),
|
Res = DAG.getNode(ISD::SRL, DL, VT, N1.getOperand(0),
|
||||||
DAG.getConstant(lsb, MVT::i32));
|
DAG.getConstant(lsb, MVT::i32));
|
||||||
Res = DAG.getNode(ARMISD::BFI, DL, VT, N0.getOperand(0), Res,
|
Res = DAG.getNode(ARMISD::BFI, DL, VT, N00, Res,
|
||||||
DAG.getConstant(Mask, MVT::i32));
|
DAG.getConstant(Mask, MVT::i32));
|
||||||
// Do not add new nodes to DAG combiner worklist.
|
// Do not add new nodes to DAG combiner worklist.
|
||||||
DCI.CombineTo(N, Res, false);
|
DCI.CombineTo(N, Res, false);
|
||||||
|
return SDValue();
|
||||||
} else if (ARM::isBitFieldInvertedMask(~Mask) &&
|
} else if (ARM::isBitFieldInvertedMask(~Mask) &&
|
||||||
ARM::isBitFieldInvertedMask(Mask2) &&
|
ARM::isBitFieldInvertedMask(Mask2) &&
|
||||||
(CountPopulation_32(~Mask) == CountPopulation_32(Mask2))) {
|
(CountPopulation_32(~Mask) == CountPopulation_32(Mask2))) {
|
||||||
@ -4791,15 +4778,34 @@ static SDValue PerformORCombine(SDNode *N,
|
|||||||
return SDValue();
|
return SDValue();
|
||||||
// 2b
|
// 2b
|
||||||
unsigned lsb = CountTrailingZeros_32(Mask);
|
unsigned lsb = CountTrailingZeros_32(Mask);
|
||||||
Res = DAG.getNode(ISD::SRL, DL, VT, N0.getOperand(0),
|
Res = DAG.getNode(ISD::SRL, DL, VT, N00,
|
||||||
DAG.getConstant(lsb, MVT::i32));
|
DAG.getConstant(lsb, MVT::i32));
|
||||||
Res = DAG.getNode(ARMISD::BFI, DL, VT, N1.getOperand(0), Res,
|
Res = DAG.getNode(ARMISD::BFI, DL, VT, N1.getOperand(0), Res,
|
||||||
DAG.getConstant(Mask2, MVT::i32));
|
DAG.getConstant(Mask2, MVT::i32));
|
||||||
// Do not add new nodes to DAG combiner worklist.
|
// Do not add new nodes to DAG combiner worklist.
|
||||||
DCI.CombineTo(N, Res, false);
|
DCI.CombineTo(N, Res, false);
|
||||||
|
return SDValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (DAG.MaskedValueIsZero(N1, MaskC->getAPIntValue()) &&
|
||||||
|
N00.getOpcode() == ISD::SHL && isa<ConstantSDNode>(N00.getOperand(1)) &&
|
||||||
|
ARM::isBitFieldInvertedMask(~Mask)) {
|
||||||
|
// Case (3): or (and (shl A, #shamt), mask), B => ARMbfi B, A, ~mask
|
||||||
|
// where lsb(mask) == #shamt and masked bits of B are known zero.
|
||||||
|
SDValue ShAmt = N00.getOperand(1);
|
||||||
|
unsigned ShAmtC = cast<ConstantSDNode>(ShAmt)->getZExtValue();
|
||||||
|
unsigned LSB = CountTrailingZeros_32(Mask);
|
||||||
|
if (ShAmtC != LSB)
|
||||||
|
return SDValue();
|
||||||
|
|
||||||
|
Res = DAG.getNode(ARMISD::BFI, DL, VT, N1, N00.getOperand(0),
|
||||||
|
DAG.getConstant(~Mask, MVT::i32));
|
||||||
|
|
||||||
|
// Do not add new nodes to DAG combiner worklist.
|
||||||
|
DCI.CombineTo(N, Res, false);
|
||||||
|
}
|
||||||
|
|
||||||
return SDValue();
|
return SDValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user