summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Osborne <richard@xmos.com>2010-03-10 16:19:31 +0000
committerRichard Osborne <richard@xmos.com>2010-03-10 16:19:31 +0000
commit1a396d53eda04b059b7602787ae736bf2106211b (patch)
tree361034236104a6dcccbd1c0fa9d967f1cb380f0f
parent74ca599a736fd73336aee00a3262bcee257057a7 (diff)
downloadbcm5719-llvm-1a396d53eda04b059b7602787ae736bf2106211b.tar.gz
bcm5719-llvm-1a396d53eda04b059b7602787ae736bf2106211b.zip
Fold add(add(mul(x,y),a),b) -> lmul(x,y,a,b) if the intermediate
results are unused elsewhere. llvm-svn: 98157
-rw-r--r--llvm/lib/Target/XCore/XCoreISelLowering.cpp56
-rw-r--r--llvm/test/CodeGen/XCore/mul64.ll12
2 files changed, 68 insertions, 0 deletions
diff --git a/llvm/lib/Target/XCore/XCoreISelLowering.cpp b/llvm/lib/Target/XCore/XCoreISelLowering.cpp
index d27adf40f6c..ad4dcfc67f2 100644
--- a/llvm/lib/Target/XCore/XCoreISelLowering.cpp
+++ b/llvm/lib/Target/XCore/XCoreISelLowering.cpp
@@ -154,6 +154,7 @@ XCoreTargetLowering::XCoreTargetLowering(XCoreTargetMachine &XTM)
// We have target-specific dag combine patterns for the following nodes:
setTargetDAGCombine(ISD::STORE);
+ setTargetDAGCombine(ISD::ADD);
}
SDValue XCoreTargetLowering::
@@ -1279,6 +1280,61 @@ SDValue XCoreTargetLowering::PerformDAGCombine(SDNode *N,
}
}
break;
+ case ISD::ADD: {
+ // Fold expressions such as add(add(mul(x,y),a),b) -> lmul(x, y, a, b).
+ // This is only profitable if the intermediate results are unused
+ // elsewhere.
+ SDValue N0 = N->getOperand(0);
+ SDValue N1 = N->getOperand(1);
+ SDValue AddOp;
+ SDValue OtherOp;
+ if (N0.getOpcode() == ISD::ADD) {
+ AddOp = N0;
+ OtherOp = N1;
+ } else if (N1.getOpcode() == ISD::ADD) {
+ AddOp = N1;
+ OtherOp = N0;
+ } else {
+ break;
+ }
+ SDValue Addend0, Addend1;
+ SDValue Mul0;
+ SDValue Mul1;
+ if (OtherOp.getOpcode() == ISD::MUL) {
+ // add(add(a,b),mul(x,y))
+ if (!OtherOp.hasOneUse() || !AddOp.hasOneUse())
+ break;
+ Mul0 = OtherOp.getOperand(0);
+ Mul1 = OtherOp.getOperand(1);
+ Addend0 = AddOp.getOperand(0);
+ Addend1 = AddOp.getOperand(1);
+ } else if (AddOp.getOperand(0).getOpcode() == ISD::MUL) {
+ // add(add(mul(x,y),a),b)
+ if (!AddOp.getOperand(0).hasOneUse())
+ break;
+ Mul0 = AddOp.getOperand(0).getOperand(0);
+ Mul1 = AddOp.getOperand(0).getOperand(1);
+ Addend0 = AddOp.getOperand(1);
+ Addend1 = OtherOp;
+ } else if (AddOp.getOperand(1).getOpcode() == ISD::MUL) {
+ // add(add(a,mul(x,y)),b)
+ if (!AddOp.getOperand(1).hasOneUse())
+ break;
+ Mul0 = AddOp.getOperand(1).getOperand(0);
+ Mul1 = AddOp.getOperand(1).getOperand(1);
+ Addend0 = AddOp.getOperand(0);
+ Addend1 = OtherOp;
+ } else {
+ break;
+ }
+ SDValue Zero = DAG.getConstant(0, MVT::i32);
+ SDValue Ignored = DAG.getNode(XCoreISD::LMUL, dl,
+ DAG.getVTList(MVT::i32, MVT::i32), Mul0,
+ Mul1, Addend0, Addend1);
+ SDValue Result(Ignored.getNode(), 1);
+ return Result;
+ }
+ break;
case ISD::STORE: {
// Replace unaligned store of unaligned load with memmove.
StoreSDNode *ST = cast<StoreSDNode>(N);
diff --git a/llvm/test/CodeGen/XCore/mul64.ll b/llvm/test/CodeGen/XCore/mul64.ll
index c06fe5a20b3..329e214d1d2 100644
--- a/llvm/test/CodeGen/XCore/mul64.ll
+++ b/llvm/test/CodeGen/XCore/mul64.ll
@@ -25,3 +25,15 @@ entry:
; CHECK-NEXT: mov r0, r3
; CHECK-NEXT: mov r1, r2
; CHECK-NEXT: retsp 0
+
+define i64 @mul64(i64 %a, i64 %b) {
+entry:
+ %0 = mul i64 %a, %b
+ ret i64 %0
+}
+; CHECK: mul64:
+; CHECK: ldc r11, 0
+; CHECK-NEXT: lmul r11, r4, r0, r2, r11, r11
+; CHECK-NEXT: mul r0, r0, r3
+; CHECK-NEXT: lmul r0, r1, r1, r2, r11, r0
+; CHECK-NEXT: mov r0, r4
OpenPOWER on IntegriCloud