mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-07 12:28:24 +00:00
[SystemZ] Handle extensions in RxSBG optimizations
The input to an RxSBG operation can be narrower as long as the upper bits are don't care. This fixes a FIXME added in r192783. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192790 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -107,7 +107,8 @@ static uint64_t allOnes(unsigned int Count) {
|
|||||||
//
|
//
|
||||||
// (and (rotl Input, Rotate), Mask)
|
// (and (rotl Input, Rotate), Mask)
|
||||||
//
|
//
|
||||||
// otherwise. The value has BitSize bits.
|
// otherwise. The output value has BitSize bits, although Input may be
|
||||||
|
// narrower (in which case the upper bits are don't care).
|
||||||
struct RxSBGOperands {
|
struct RxSBGOperands {
|
||||||
RxSBGOperands(unsigned Op, SDValue N)
|
RxSBGOperands(unsigned Op, SDValue N)
|
||||||
: Opcode(Op), BitSize(N.getValueType().getSizeInBits()),
|
: Opcode(Op), BitSize(N.getValueType().getSizeInBits()),
|
||||||
@@ -762,7 +763,7 @@ bool SystemZDAGToDAGISel::expandRxSBG(RxSBGOperands &RxSBG) const {
|
|||||||
|
|
||||||
case ISD::ROTL: {
|
case ISD::ROTL: {
|
||||||
// Any 64-bit rotate left can be merged into the RxSBG.
|
// Any 64-bit rotate left can be merged into the RxSBG.
|
||||||
if (RxSBG.BitSize != 64)
|
if (RxSBG.BitSize != 64 || N.getValueType() != MVT::i64)
|
||||||
return false;
|
return false;
|
||||||
ConstantSDNode *CountNode
|
ConstantSDNode *CountNode
|
||||||
= dyn_cast<ConstantSDNode>(N.getOperand(1).getNode());
|
= dyn_cast<ConstantSDNode>(N.getOperand(1).getNode());
|
||||||
@@ -774,6 +775,19 @@ bool SystemZDAGToDAGISel::expandRxSBG(RxSBGOperands &RxSBG) const {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case ISD::SIGN_EXTEND:
|
||||||
|
case ISD::ZERO_EXTEND:
|
||||||
|
case ISD::ANY_EXTEND: {
|
||||||
|
// Check that the extension bits are don't-care (i.e. are masked out
|
||||||
|
// by the final mask).
|
||||||
|
unsigned InnerBitSize = N.getOperand(0).getValueType().getSizeInBits();
|
||||||
|
if (shiftedInBitsMatter(RxSBG, RxSBG.BitSize - InnerBitSize, false))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
RxSBG.Input = N.getOperand(0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
case ISD::SHL: {
|
case ISD::SHL: {
|
||||||
ConstantSDNode *CountNode =
|
ConstantSDNode *CountNode =
|
||||||
dyn_cast<ConstantSDNode>(N.getOperand(1).getNode());
|
dyn_cast<ConstantSDNode>(N.getOperand(1).getNode());
|
||||||
@@ -781,7 +795,8 @@ bool SystemZDAGToDAGISel::expandRxSBG(RxSBGOperands &RxSBG) const {
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
uint64_t Count = CountNode->getZExtValue();
|
uint64_t Count = CountNode->getZExtValue();
|
||||||
if (Count < 1 || Count >= RxSBG.BitSize)
|
unsigned BitSize = N.getValueType().getSizeInBits();
|
||||||
|
if (Count < 1 || Count >= BitSize)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (RxSBG.Opcode == SystemZ::RNSBG) {
|
if (RxSBG.Opcode == SystemZ::RNSBG) {
|
||||||
@@ -791,7 +806,7 @@ bool SystemZDAGToDAGISel::expandRxSBG(RxSBGOperands &RxSBG) const {
|
|||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
// Treat (shl X, count) as (and (rotl X, count), ~0<<count).
|
// Treat (shl X, count) as (and (rotl X, count), ~0<<count).
|
||||||
if (!refineRxSBGMask(RxSBG, allOnes(RxSBG.BitSize - Count) << Count))
|
if (!refineRxSBGMask(RxSBG, allOnes(BitSize - Count) << Count))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -808,7 +823,8 @@ bool SystemZDAGToDAGISel::expandRxSBG(RxSBGOperands &RxSBG) const {
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
uint64_t Count = CountNode->getZExtValue();
|
uint64_t Count = CountNode->getZExtValue();
|
||||||
if (Count < 1 || Count >= RxSBG.BitSize)
|
unsigned BitSize = N.getValueType().getSizeInBits();
|
||||||
|
if (Count < 1 || Count >= BitSize)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (RxSBG.Opcode == SystemZ::RNSBG || Opcode == ISD::SRA) {
|
if (RxSBG.Opcode == SystemZ::RNSBG || Opcode == ISD::SRA) {
|
||||||
@@ -819,7 +835,7 @@ bool SystemZDAGToDAGISel::expandRxSBG(RxSBGOperands &RxSBG) const {
|
|||||||
} else {
|
} else {
|
||||||
// Treat (srl X, count), mask) as (and (rotl X, size-count), ~0>>count),
|
// Treat (srl X, count), mask) as (and (rotl X, size-count), ~0>>count),
|
||||||
// which is similar to SLL above.
|
// which is similar to SLL above.
|
||||||
if (!refineRxSBGMask(RxSBG, allOnes(RxSBG.BitSize - Count)))
|
if (!refineRxSBGMask(RxSBG, allOnes(BitSize - Count)))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -852,7 +868,8 @@ SDNode *SystemZDAGToDAGISel::tryRISBGZero(SDNode *N) {
|
|||||||
RxSBGOperands RISBG(SystemZ::RISBG, SDValue(N, 0));
|
RxSBGOperands RISBG(SystemZ::RISBG, SDValue(N, 0));
|
||||||
unsigned Count = 0;
|
unsigned Count = 0;
|
||||||
while (expandRxSBG(RISBG))
|
while (expandRxSBG(RISBG))
|
||||||
Count += 1;
|
if (RISBG.Input.getOpcode() != ISD::ANY_EXTEND)
|
||||||
|
Count += 1;
|
||||||
if (Count == 0)
|
if (Count == 0)
|
||||||
return 0;
|
return 0;
|
||||||
if (Count == 1) {
|
if (Count == 1) {
|
||||||
@@ -909,7 +926,8 @@ SDNode *SystemZDAGToDAGISel::tryRxSBG(SDNode *N, unsigned Opcode) {
|
|||||||
unsigned Count[] = { 0, 0 };
|
unsigned Count[] = { 0, 0 };
|
||||||
for (unsigned I = 0; I < 2; ++I)
|
for (unsigned I = 0; I < 2; ++I)
|
||||||
while (expandRxSBG(RxSBG[I]))
|
while (expandRxSBG(RxSBG[I]))
|
||||||
Count[I] += 1;
|
if (RxSBG[I].Input.getOpcode() != ISD::ANY_EXTEND)
|
||||||
|
Count[I] += 1;
|
||||||
|
|
||||||
// Do nothing if neither operand is suitable.
|
// Do nothing if neither operand is suitable.
|
||||||
if (Count[0] == 0 && Count[1] == 0)
|
if (Count[0] == 0 && Count[1] == 0)
|
||||||
|
@@ -52,11 +52,10 @@ define i64 @f4(i32 %a) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
; Repeat the previous test in a case where all bits outside the
|
; Repeat the previous test in a case where all bits outside the
|
||||||
; bottom 3 matter. FIXME: can still use RISBG here.
|
; bottom 3 matter.
|
||||||
define i64 @f5(i32 %a) {
|
define i64 @f5(i32 %a) {
|
||||||
; CHECK-LABEL: f5:
|
; CHECK-LABEL: f5:
|
||||||
; CHECK: srl %r2, 30
|
; CHECK: risbg %r2, %r2, 29, 158, 3
|
||||||
; CHECK: sllg %r2, %r2, 33
|
|
||||||
; CHECK: lhi %r2, 7
|
; CHECK: lhi %r2, 7
|
||||||
; CHECK: br %r14
|
; CHECK: br %r14
|
||||||
%shr = lshr i32 %a, 30
|
%shr = lshr i32 %a, 30
|
||||||
|
Reference in New Issue
Block a user