diff options
author | Richard Sandiford <rsandifo@linux.vnet.ibm.com> | 2013-10-16 13:35:13 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@linux.vnet.ibm.com> | 2013-10-16 13:35:13 +0000 |
commit | d77a7669ec1a6bba7e45791b1aa1e65a603dda92 (patch) | |
tree | 13629a441c0081ea606b7a9b6e22b4667329a1fb /lib | |
parent | 648a2e6714885e9b3d2a4f380434fe44ef2c4b5b (diff) | |
download | external_llvm-d77a7669ec1a6bba7e45791b1aa1e65a603dda92.zip external_llvm-d77a7669ec1a6bba7e45791b1aa1e65a603dda92.tar.gz external_llvm-d77a7669ec1a6bba7e45791b1aa1e65a603dda92.tar.bz2 |
[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
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/SystemZ/SystemZISelDAGToDAG.cpp | 34 |
1 files changed, 26 insertions, 8 deletions
diff --git a/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp b/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp index 5145401..7febed2 100644 --- a/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp +++ b/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp @@ -107,7 +107,8 @@ static uint64_t allOnes(unsigned int Count) { // // (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 { RxSBGOperands(unsigned Op, SDValue N) : Opcode(Op), BitSize(N.getValueType().getSizeInBits()), @@ -762,7 +763,7 @@ bool SystemZDAGToDAGISel::expandRxSBG(RxSBGOperands &RxSBG) const { case ISD::ROTL: { // 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; ConstantSDNode *CountNode = dyn_cast<ConstantSDNode>(N.getOperand(1).getNode()); @@ -774,6 +775,19 @@ bool SystemZDAGToDAGISel::expandRxSBG(RxSBGOperands &RxSBG) const { 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: { ConstantSDNode *CountNode = dyn_cast<ConstantSDNode>(N.getOperand(1).getNode()); @@ -781,7 +795,8 @@ bool SystemZDAGToDAGISel::expandRxSBG(RxSBGOperands &RxSBG) const { return false; uint64_t Count = CountNode->getZExtValue(); - if (Count < 1 || Count >= RxSBG.BitSize) + unsigned BitSize = N.getValueType().getSizeInBits(); + if (Count < 1 || Count >= BitSize) return false; if (RxSBG.Opcode == SystemZ::RNSBG) { @@ -791,7 +806,7 @@ bool SystemZDAGToDAGISel::expandRxSBG(RxSBGOperands &RxSBG) const { return false; } else { // 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; } @@ -808,7 +823,8 @@ bool SystemZDAGToDAGISel::expandRxSBG(RxSBGOperands &RxSBG) const { return false; uint64_t Count = CountNode->getZExtValue(); - if (Count < 1 || Count >= RxSBG.BitSize) + unsigned BitSize = N.getValueType().getSizeInBits(); + if (Count < 1 || Count >= BitSize) return false; if (RxSBG.Opcode == SystemZ::RNSBG || Opcode == ISD::SRA) { @@ -819,7 +835,7 @@ bool SystemZDAGToDAGISel::expandRxSBG(RxSBGOperands &RxSBG) const { } else { // Treat (srl X, count), mask) as (and (rotl X, size-count), ~0>>count), // which is similar to SLL above. - if (!refineRxSBGMask(RxSBG, allOnes(RxSBG.BitSize - Count))) + if (!refineRxSBGMask(RxSBG, allOnes(BitSize - Count))) return false; } @@ -852,7 +868,8 @@ SDNode *SystemZDAGToDAGISel::tryRISBGZero(SDNode *N) { RxSBGOperands RISBG(SystemZ::RISBG, SDValue(N, 0)); unsigned Count = 0; while (expandRxSBG(RISBG)) - Count += 1; + if (RISBG.Input.getOpcode() != ISD::ANY_EXTEND) + Count += 1; if (Count == 0) return 0; if (Count == 1) { @@ -909,7 +926,8 @@ SDNode *SystemZDAGToDAGISel::tryRxSBG(SDNode *N, unsigned Opcode) { unsigned Count[] = { 0, 0 }; for (unsigned I = 0; I < 2; ++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. if (Count[0] == 0 && Count[1] == 0) |