mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-06 23:32:27 +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)
|
||||
return SDValue();
|
||||
|
||||
SDValue N00 = N0.getOperand(0);
|
||||
|
||||
// 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
|
||||
// via a movt instruction, so don't use BFI in that case.
|
||||
ConstantSDNode *C = dyn_cast<ConstantSDNode>(N0.getOperand(1));
|
||||
if (!C)
|
||||
SDValue MaskOp = N0.getOperand(1);
|
||||
ConstantSDNode *MaskC = dyn_cast<ConstantSDNode>(MaskOp);
|
||||
if (!MaskC)
|
||||
return SDValue();
|
||||
unsigned Mask = C->getZExtValue();
|
||||
unsigned Mask = MaskC->getZExtValue();
|
||||
if (Mask == 0xffff)
|
||||
return SDValue();
|
||||
SDValue Res;
|
||||
// Case (1): or (and A, mask), val => ARMbfi A, val, mask
|
||||
if ((C = dyn_cast<ConstantSDNode>(N1))) {
|
||||
unsigned Val = C->getZExtValue();
|
||||
ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1);
|
||||
if (N1C) {
|
||||
unsigned Val = N1C->getZExtValue();
|
||||
if ((Val & ~Mask) != Val)
|
||||
return SDValue();
|
||||
|
||||
if (ARM::isBitFieldInvertedMask(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(Mask, MVT::i32));
|
||||
|
||||
// Do not add new nodes to DAG combiner worklist.
|
||||
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();
|
||||
//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);
|
||||
return SDValue();
|
||||
}
|
||||
} else if (N1.getOpcode() == ISD::AND) {
|
||||
// case (2) or (and A, mask), (and B, mask2) => ARMbfi A, (lsr B, amt), mask
|
||||
C = dyn_cast<ConstantSDNode>(N1.getOperand(1));
|
||||
if (!C)
|
||||
ConstantSDNode *N11C = dyn_cast<ConstantSDNode>(N1.getOperand(1));
|
||||
if (!N11C)
|
||||
return SDValue();
|
||||
unsigned Mask2 = C->getZExtValue();
|
||||
unsigned Mask2 = N11C->getZExtValue();
|
||||
|
||||
if (ARM::isBitFieldInvertedMask(Mask) &&
|
||||
ARM::isBitFieldInvertedMask(~Mask2) &&
|
||||
@ -4777,10 +4763,11 @@ static SDValue PerformORCombine(SDNode *N,
|
||||
unsigned lsb = CountTrailingZeros_32(Mask2);
|
||||
Res = DAG.getNode(ISD::SRL, DL, VT, N1.getOperand(0),
|
||||
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));
|
||||
// Do not add new nodes to DAG combiner worklist.
|
||||
DCI.CombineTo(N, Res, false);
|
||||
return SDValue();
|
||||
} else if (ARM::isBitFieldInvertedMask(~Mask) &&
|
||||
ARM::isBitFieldInvertedMask(Mask2) &&
|
||||
(CountPopulation_32(~Mask) == CountPopulation_32(Mask2))) {
|
||||
@ -4791,15 +4778,34 @@ static SDValue PerformORCombine(SDNode *N,
|
||||
return SDValue();
|
||||
// 2b
|
||||
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));
|
||||
Res = DAG.getNode(ARMISD::BFI, DL, VT, N1.getOperand(0), Res,
|
||||
DAG.getConstant(Mask2, MVT::i32));
|
||||
// Do not add new nodes to DAG combiner worklist.
|
||||
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();
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user