[llvm-commits] [llvm] r98150 - in /llvm/trunk: lib/Target/XCore/XCoreISelDAGToDAG.cpp lib/Target/XCore/XCoreISelLowering.cpp lib/Target/XCore/XCoreISelLowering.h test/CodeGen/XCore/addsub64.ll
Richard Osborne
richard at xmos.com
Wed Mar 10 03:41:08 PST 2010
Author: friedgold
Date: Wed Mar 10 05:41:08 2010
New Revision: 98150
URL: http://llvm.org/viewvc/llvm-project?rev=98150&view=rev
Log:
Lower add (mul a, b), c into MACCU / MACCS nodes which translate
directly to the maccu / maccs instructions. We handle this in
ExpandADDSUB since after type legalisation it is messy to
recognise these operations.
Modified:
llvm/trunk/lib/Target/XCore/XCoreISelDAGToDAG.cpp
llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp
llvm/trunk/lib/Target/XCore/XCoreISelLowering.h
llvm/trunk/test/CodeGen/XCore/addsub64.ll
Modified: llvm/trunk/lib/Target/XCore/XCoreISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/XCoreISelDAGToDAG.cpp?rev=98150&r1=98149&r2=98150&view=diff
==============================================================================
--- llvm/trunk/lib/Target/XCore/XCoreISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/XCore/XCoreISelDAGToDAG.cpp Wed Mar 10 05:41:08 2010
@@ -208,6 +208,18 @@
return CurDAG->getMachineNode(XCore::LSUB_l5r, dl, MVT::i32, MVT::i32,
Ops, 3);
}
+ case XCoreISD::MACCU: {
+ SDValue Ops[] = { N->getOperand(0), N->getOperand(1),
+ N->getOperand(2), N->getOperand(3) };
+ return CurDAG->getMachineNode(XCore::MACCU_l4r, dl, MVT::i32, MVT::i32,
+ Ops, 4);
+ }
+ case XCoreISD::MACCS: {
+ SDValue Ops[] = { N->getOperand(0), N->getOperand(1),
+ N->getOperand(2), N->getOperand(3) };
+ return CurDAG->getMachineNode(XCore::MACCS_l4r, dl, MVT::i32, MVT::i32,
+ Ops, 4);
+ }
// Other cases are autogenerated.
}
}
Modified: llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp?rev=98150&r1=98149&r2=98150&view=diff
==============================================================================
--- llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp Wed Mar 10 05:41:08 2010
@@ -54,6 +54,8 @@
case XCoreISD::RETSP : return "XCoreISD::RETSP";
case XCoreISD::LADD : return "XCoreISD::LADD";
case XCoreISD::LSUB : return "XCoreISD::LSUB";
+ case XCoreISD::MACCU : return "XCoreISD::MACCU";
+ case XCoreISD::MACCS : return "XCoreISD::MACCS";
case XCoreISD::BR_JT : return "XCoreISD::BR_JT";
case XCoreISD::BR_JT32 : return "XCoreISD::BR_JT32";
default : return NULL;
@@ -542,11 +544,76 @@
}
SDValue XCoreTargetLowering::
+TryExpandADDSUBWithMul(SDNode *N, SelectionDAG &DAG)
+{
+ SDValue Mul;
+ SDValue Other;
+ if (N->getOperand(0).getOpcode() == ISD::MUL) {
+ Mul = N->getOperand(0);
+ Other = N->getOperand(1);
+ } else if (N->getOperand(1).getOpcode() == ISD::MUL) {
+ Mul = N->getOperand(1);
+ Other = N->getOperand(0);
+ } else {
+ return SDValue();
+ }
+ DebugLoc dl = N->getDebugLoc();
+ SDValue LL, RL, AddendL, AddendH;
+ LL = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32,
+ Mul.getOperand(0), DAG.getConstant(0, MVT::i32));
+ RL = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32,
+ Mul.getOperand(1), DAG.getConstant(0, MVT::i32));
+ AddendL = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32,
+ Other, DAG.getConstant(0, MVT::i32));
+ AddendH = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32,
+ Other, DAG.getConstant(1, MVT::i32));
+ APInt HighMask = APInt::getHighBitsSet(64, 32);
+ unsigned LHSSB = DAG.ComputeNumSignBits(Mul.getOperand(0));
+ unsigned RHSSB = DAG.ComputeNumSignBits(Mul.getOperand(1));
+ if (DAG.MaskedValueIsZero(Mul.getOperand(0), HighMask) &&
+ DAG.MaskedValueIsZero(Mul.getOperand(1), HighMask)) {
+ // The inputs are both zero-extended.
+ SDValue Hi = DAG.getNode(XCoreISD::MACCU, dl,
+ DAG.getVTList(MVT::i32, MVT::i32), AddendH,
+ AddendL, LL, RL);
+ SDValue Lo(Hi.getNode(), 1);
+ return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lo, Hi);
+ }
+ if (LHSSB > 32 && RHSSB > 32) {
+ // The inputs are both sign-extended.
+ SDValue Hi = DAG.getNode(XCoreISD::MACCS, dl,
+ DAG.getVTList(MVT::i32, MVT::i32), AddendH,
+ AddendL, LL, RL);
+ SDValue Lo(Hi.getNode(), 1);
+ return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lo, Hi);
+ }
+ SDValue LH, RH;
+ LH = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32,
+ Mul.getOperand(0), DAG.getConstant(1, MVT::i32));
+ RH = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32,
+ Mul.getOperand(1), DAG.getConstant(1, MVT::i32));
+ SDValue Hi = DAG.getNode(XCoreISD::MACCU, dl,
+ DAG.getVTList(MVT::i32, MVT::i32), AddendH,
+ AddendL, LL, RL);
+ SDValue Lo(Hi.getNode(), 1);
+ RH = DAG.getNode(ISD::MUL, dl, MVT::i32, LL, RH);
+ LH = DAG.getNode(ISD::MUL, dl, MVT::i32, LH, RL);
+ Hi = DAG.getNode(ISD::ADD, dl, MVT::i32, Hi, RH);
+ Hi = DAG.getNode(ISD::ADD, dl, MVT::i32, Hi, LH);
+ return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lo, Hi);
+}
+
+SDValue XCoreTargetLowering::
ExpandADDSUB(SDNode *N, SelectionDAG &DAG)
{
assert(N->getValueType(0) == MVT::i64 &&
(N->getOpcode() == ISD::ADD || N->getOpcode() == ISD::SUB) &&
"Unknown operand to lower!");
+
+ SDValue Result = TryExpandADDSUBWithMul(N, DAG);
+ if (Result.getNode() != 0)
+ return Result;
+
DebugLoc dl = N->getDebugLoc();
// Extract components
Modified: llvm/trunk/lib/Target/XCore/XCoreISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/XCoreISelLowering.h?rev=98150&r1=98149&r2=98150&view=diff
==============================================================================
--- llvm/trunk/lib/Target/XCore/XCoreISelLowering.h (original)
+++ llvm/trunk/lib/Target/XCore/XCoreISelLowering.h Wed Mar 10 05:41:08 2010
@@ -54,6 +54,12 @@
// Corresponds to LSUB instruction
LSUB,
+ // Corresponds to MACCU instruction
+ MACCU,
+
+ // Corresponds to MACCS instruction
+ MACCS,
+
// Jumptable branch.
BR_JT,
@@ -140,6 +146,7 @@
EVT VT) const;
// Expand specifics
+ SDValue TryExpandADDSUBWithMul(SDNode *Op, SelectionDAG &DAG);
SDValue ExpandADDSUB(SDNode *Op, SelectionDAG &DAG);
virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const;
Modified: llvm/trunk/test/CodeGen/XCore/addsub64.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/addsub64.ll?rev=98150&r1=98149&r2=98150&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/XCore/addsub64.ll (original)
+++ llvm/trunk/test/CodeGen/XCore/addsub64.ll Wed Mar 10 05:41:08 2010
@@ -18,3 +18,27 @@
; CHECK-NEXT: lsub r2, r0, r0, r2, r11
; CHECK-NEXT: lsub r2, r1, r1, r3, r2
; CHECK-NEXT: retsp 0
+
+define i64 @maccu(i64 %a, i32 %b, i32 %c) {
+entry:
+ %0 = zext i32 %b to i64
+ %1 = zext i32 %c to i64
+ %2 = mul i64 %1, %0
+ %3 = add i64 %2, %a
+ ret i64 %3
+}
+; CHECK: maccu:
+; CHECK: maccu r1, r0, r3, r2
+; CHECK-NEXT: retsp 0
+
+define i64 @maccs(i64 %a, i32 %b, i32 %c) {
+entry:
+ %0 = sext i32 %b to i64
+ %1 = sext i32 %c to i64
+ %2 = mul i64 %1, %0
+ %3 = add i64 %2, %a
+ ret i64 %3
+}
+; CHECK: maccs:
+; CHECK: maccs r1, r0, r3, r2
+; CHECK-NEXT: retsp 0
More information about the llvm-commits
mailing list