summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
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
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')
-rw-r--r--llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp30
-rw-r--r--llvm/lib/Target/ARM/ARMInstrThumb2.td9
2 files changed, 34 insertions, 5 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))
diff --git a/llvm/lib/Target/ARM/ARMInstrThumb2.td b/llvm/lib/Target/ARM/ARMInstrThumb2.td
index ccf4b29b345..ff6c46ed84f 100644
--- a/llvm/lib/Target/ARM/ARMInstrThumb2.td
+++ b/llvm/lib/Target/ARM/ARMInstrThumb2.td
@@ -2604,12 +2604,11 @@ class T2FourRegSMMLA<bits<3> op22_20, bits<4> op7_4, string opc,
let Inst{7-4} = op7_4;
}
-def t2SMMLA : T2FourRegSMMLA<0b101, 0b0000, "smmla",
+def t2SMMLA : T2FourRegSMMLA<0b101, 0b0000, "smmla",
[(set rGPR:$Rd, (add (mulhs rGPR:$Rm, rGPR:$Rn), rGPR:$Ra))]>;
-def t2SMMLAR: T2FourRegSMMLA<0b101, 0b0001, "smmlar", []>;
-def t2SMMLS: T2FourRegSMMLA<0b110, 0b0000, "smmls",
- [(set rGPR:$Rd, (sub rGPR:$Ra, (mulhs rGPR:$Rn, rGPR:$Rm)))]>;
-def t2SMMLSR:T2FourRegSMMLA<0b110, 0b0001, "smmlsr", []>;
+def t2SMMLAR: T2FourRegSMMLA<0b101, 0b0001, "smmlar", []>;
+def t2SMMLS: T2FourRegSMMLA<0b110, 0b0000, "smmls", []>;
+def t2SMMLSR: T2FourRegSMMLA<0b110, 0b0001, "smmlsr", []>;
class T2ThreeRegSMUL<bits<3> op22_20, bits<2> op5_4, string opc,
list<dag> pattern>
OpenPOWER on IntegriCloud