summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp
diff options
context:
space:
mode:
authorSam Parker <sam.parker@arm.com>2016-07-25 09:20:20 +0000
committerSam Parker <sam.parker@arm.com>2016-07-25 09:20:20 +0000
commit68c71cd1e4a35baabb39c7b8bc77d0fbdd4bdb15 (patch)
treee99b2d5aa9e3bad64d99040cb8b731981f34dca9 /llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp
parentfa7b080218a92aaa2165669410f5ef31f2d9ad11 (diff)
downloadbcm5719-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.cpp30
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))
OpenPOWER on IntegriCloud