[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