From 47801092543718562306dd485cd334fb25a95d67 Mon Sep 17 00:00:00 2001 From: Richard Osborne Date: Thu, 11 Mar 2010 16:26:35 +0000 Subject: [PATCH] Add dag combine to simplify lmul(x, 0, a, b) llvm-svn: 98258 --- llvm/lib/Target/XCore/XCoreISelLowering.cpp | 27 +++++++++++++++++++++ llvm/test/CodeGen/XCore/mul64.ll | 13 ++++++++++ 2 files changed, 40 insertions(+) diff --git a/llvm/lib/Target/XCore/XCoreISelLowering.cpp b/llvm/lib/Target/XCore/XCoreISelLowering.cpp index 7cbfe3edc69e..bf1a45762795 100644 --- a/llvm/lib/Target/XCore/XCoreISelLowering.cpp +++ b/llvm/lib/Target/XCore/XCoreISelLowering.cpp @@ -1345,6 +1345,33 @@ SDValue XCoreTargetLowering::PerformDAGCombine(SDNode *N, } } break; + case XCoreISD::LMUL: { + SDValue N0 = N->getOperand(0); + SDValue N1 = N->getOperand(1); + SDValue N2 = N->getOperand(2); + SDValue N3 = N->getOperand(3); + ConstantSDNode *N0C = dyn_cast(N0); + ConstantSDNode *N1C = dyn_cast(N1); + EVT VT = N0.getValueType(); + // Canonicalize multiplicative constant to RHS. If both multiplicative + // operands are constant canonicalize smallest to RHS. + if ((N0C && !N1C) || + (N0C && N1C && N0C->getZExtValue() < N1C->getZExtValue())) + return DAG.getNode(XCoreISD::LMUL, dl, DAG.getVTList(VT, VT), N1, N0, N2, N3); + + // lmul(x, 0, a, b) + if (N1C && N1C->isNullValue()) { + // If the high result is unused fold to add(a, b) + if (N->hasNUsesOfValue(0, 0)) { + SDValue Lo = DAG.getNode(ISD::ADD, dl, VT, N2, N3); + SDValue Ops [] = { Lo, Lo }; + return DAG.getMergeValues(Ops, 2, dl); + } + // Otherwise fold to ladd(a, b, 0) + return DAG.getNode(XCoreISD::LADD, dl, DAG.getVTList(VT, VT), N2, N3, N1); + } + } + break; case ISD::ADD: { // Fold 32 bit expressions such as add(add(mul(x,y),a),b) -> // lmul(x, y, a, b). The high result of lmul will be ignored. diff --git a/llvm/test/CodeGen/XCore/mul64.ll b/llvm/test/CodeGen/XCore/mul64.ll index 329e214d1d23..1dc94712507e 100644 --- a/llvm/test/CodeGen/XCore/mul64.ll +++ b/llvm/test/CodeGen/XCore/mul64.ll @@ -37,3 +37,16 @@ entry: ; CHECK-NEXT: mul r0, r0, r3 ; CHECK-NEXT: lmul r0, r1, r1, r2, r11, r0 ; CHECK-NEXT: mov r0, r4 + +define i64 @mul64_2(i64 %a, i32 %b) { +entry: + %0 = zext i32 %b to i64 + %1 = mul i64 %a, %0 + ret i64 %1 +} +; CHECK: mul64_2: +; CHECK: ldc r3, 0 +; CHECK-NEXT: lmul r3, r0, r0, r2, r3, r3 +; CHECK-NEXT: mul r1, r1, r2 +; CHECK-NEXT: add r1, r3, r1 +; CHECK-NEXT: retsp 0