diff options
| author | Zhan Jun Liau <zhanjunl@ca.ibm.com> | 2016-06-22 16:16:27 +0000 |
|---|---|---|
| committer | Zhan Jun Liau <zhanjunl@ca.ibm.com> | 2016-06-22 16:16:27 +0000 |
| commit | 0df350589f6481c42514a4e0d02c8ac362ca4c49 (patch) | |
| tree | 916c1b1f8d03b618f3ea65913161945e45c2f79b /llvm/lib/Target | |
| parent | f228c95f872fd229b551ebaf194313935d0e8bda (diff) | |
| download | bcm5719-llvm-0df350589f6481c42514a4e0d02c8ac362ca4c49.tar.gz bcm5719-llvm-0df350589f6481c42514a4e0d02c8ac362ca4c49.zip | |
[SystemZ] Recognize RISBG opportunities involving a truncate
Summary:
Recognize RISBG opportunities where the end result is narrower than the
original input - where a truncate separates the shift/and operations.
The motivating case is some code in postgres which looks like:
srlg %r2, %r0, 11
nilh %r2, 255
Reviewers: uweigand
Author: RolandF
Differential Revision: http://reviews.llvm.org/D21452
llvm-svn: 273433
Diffstat (limited to 'llvm/lib/Target')
| -rw-r--r-- | llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp b/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp index 726bc28b6db..cd7fcc3070a 100644 --- a/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp +++ b/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp @@ -113,7 +113,8 @@ static uint64_t allOnes(unsigned int Count) { // (and (rotl Input, Rotate), Mask) // // otherwise. The output value has BitSize bits, although Input may be -// narrower (in which case the upper bits are don't care). +// narrower (in which case the upper bits are don't care), or wider (in which +// case the result will be truncated as part of the operation). struct RxSBGOperands { RxSBGOperands(unsigned Op, SDValue N) : Opcode(Op), BitSize(N.getValueType().getSizeInBits()), @@ -745,6 +746,16 @@ bool SystemZDAGToDAGISel::expandRxSBG(RxSBGOperands &RxSBG) const { SDValue N = RxSBG.Input; unsigned Opcode = N.getOpcode(); switch (Opcode) { + case ISD::TRUNCATE: { + if (RxSBG.Opcode == SystemZ::RNSBG) + return false; + uint64_t BitSize = N.getValueType().getSizeInBits(); + uint64_t Mask = allOnes(BitSize); + if (!refineRxSBGMask(RxSBG, Mask)) + return false; + RxSBG.Input = N.getOperand(0); + return true; + } case ISD::AND: { if (RxSBG.Opcode == SystemZ::RNSBG) return false; @@ -916,7 +927,11 @@ bool SystemZDAGToDAGISel::tryRISBGZero(SDNode *N) { RxSBGOperands RISBG(SystemZ::RISBG, SDValue(N, 0)); unsigned Count = 0; while (expandRxSBG(RISBG)) - if (RISBG.Input.getOpcode() != ISD::ANY_EXTEND) + // The widening or narrowing is expected to be free. + // Counting widening or narrowing as a saved operation will result in + // preferring an R*SBG over a simple shift/logical instruction. + if (RISBG.Input.getOpcode() != ISD::ANY_EXTEND && + RISBG.Input.getOpcode() != ISD::TRUNCATE) Count += 1; if (Count == 0) return false; @@ -1004,7 +1019,11 @@ bool SystemZDAGToDAGISel::tryRxSBG(SDNode *N, unsigned Opcode) { unsigned Count[] = { 0, 0 }; for (unsigned I = 0; I < 2; ++I) while (expandRxSBG(RxSBG[I])) - if (RxSBG[I].Input.getOpcode() != ISD::ANY_EXTEND) + // The widening or narrowing is expected to be free. + // Counting widening or narrowing as a saved operation will result in + // preferring an R*SBG over a simple shift/logical instruction. + if (RxSBG[I].Input.getOpcode() != ISD::ANY_EXTEND && + RxSBG[I].Input.getOpcode() != ISD::TRUNCATE) Count[I] += 1; // Do nothing if neither operand is suitable. |

