diff options
author | Sam Parker <sam.parker@arm.com> | 2016-07-25 09:20:20 +0000 |
---|---|---|
committer | Sam Parker <sam.parker@arm.com> | 2016-07-25 09:20:20 +0000 |
commit | 68c71cd1e4a35baabb39c7b8bc77d0fbdd4bdb15 (patch) | |
tree | e99b2d5aa9e3bad64d99040cb8b731981f34dca9 /llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp | |
parent | fa7b080218a92aaa2165669410f5ef31f2d9ad11 (diff) | |
download | bcm5719-llvm-68c71cd1e4a35baabb39c7b8bc77d0fbdd4bdb15.tar.gz bcm5719-llvm-68c71cd1e4a35baabb39c7b8bc77d0fbdd4bdb15.zip |
[ARM] Enable ISel of SMMLS for ARM and Thumb2
Use ISelDAGToDAG to recognise the SMMLS instruction pattern.
Differential Revision: https://reviews.llvm.org/D22562
llvm-svn: 276624
Diffstat (limited to 'llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp')
-rw-r--r-- | llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp b/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp index 20db3d39bca..96cb691f745 100644 --- a/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ b/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -3037,6 +3037,36 @@ void ARMDAGToDAGISel::Select(SDNode *N) { return; } } + case ARMISD::SUBE: { + if (!Subtarget->hasV6Ops()) + break; + // Look for a pattern to match SMMLS + // (sube a, (smul_loHi a, b), (subc 0, (smul_LOhi(a, b)))) + if (N->getOperand(1).getOpcode() != ISD::SMUL_LOHI || + N->getOperand(2).getOpcode() != ARMISD::SUBC) + break; + + if (Subtarget->isThumb()) + assert(Subtarget->hasThumb2() && + "This pattern should not be generated for Thumb"); + + SDValue SmulLoHi = N->getOperand(1); + SDValue Subc = N->getOperand(2); + auto *Zero = dyn_cast<ConstantSDNode>(Subc.getOperand(0)); + + if (!Zero || Zero->getZExtValue() != 0 || + Subc.getOperand(1) != SmulLoHi.getValue(0) || + N->getOperand(1) != SmulLoHi.getValue(1) || + N->getOperand(2) != Subc.getValue(1)) + break; + + unsigned Opc = Subtarget->isThumb2() ? ARM::t2SMMLS : ARM::SMMLS; + SDValue Ops[] = { SmulLoHi.getOperand(0), SmulLoHi.getOperand(1), + N->getOperand(0), getAL(CurDAG, dl), + CurDAG->getRegister(0, MVT::i32) }; + ReplaceNode(N, CurDAG->getMachineNode(Opc, dl, MVT::i32, Ops)); + return; + } case ISD::LOAD: { if (Subtarget->isThumb() && Subtarget->hasThumb2()) { if (tryT2IndexedLoad(N)) |