From ad4f66c76fc7537e05b6bfb71f420c614875fb48 Mon Sep 17 00:00:00 2001 From: Richard Osborne Date: Tue, 9 Mar 2010 16:34:25 +0000 Subject: [PATCH] In cases where the carry / borrow unused converted ladd / lsub to an add or a sub. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@98059 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/XCore/XCoreISelLowering.cpp | 30 +++++++++++++++++++ test/CodeGen/XCore/ladd_lsub_combine.ll | 39 +++++++++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/lib/Target/XCore/XCoreISelLowering.cpp b/lib/Target/XCore/XCoreISelLowering.cpp index d8cbd037cb2..7ecd15135a9 100644 --- a/lib/Target/XCore/XCoreISelLowering.cpp +++ b/lib/Target/XCore/XCoreISelLowering.cpp @@ -1117,6 +1117,21 @@ SDValue XCoreTargetLowering::PerformDAGCombine(SDNode *N, SDValue Ops [] = { Carry, Result }; return DAG.getMergeValues(Ops, 2, dl); } + + // fold (ladd x, 0, y) -> 0, add x, y iff carry is unused and y has only the + // low bit set + if (N1C && N1C->isNullValue() && N->hasNUsesOfValue(0, 0)) { + APInt KnownZero, KnownOne; + APInt Mask = APInt::getHighBitsSet(VT.getSizeInBits(), + VT.getSizeInBits() - 1); + DAG.ComputeMaskedBits(N2, Mask, KnownZero, KnownOne); + if (KnownZero == Mask) { + SDValue Carry = DAG.getConstant(0, VT); + SDValue Result = DAG.getNode(ISD::ADD, dl, VT, N0, N2); + SDValue Ops [] = { Carry, Result }; + return DAG.getMergeValues(Ops, 2, dl); + } + } } break; case XCoreISD::LSUB: { @@ -1141,6 +1156,21 @@ SDValue XCoreTargetLowering::PerformDAGCombine(SDNode *N, return DAG.getMergeValues(Ops, 2, dl); } } + + // fold (lsub x, 0, y) -> 0, sub x, y iff borrow is unused and y has only the + // low bit set + if (N1C && N1C->isNullValue() && N->hasNUsesOfValue(0, 0)) { + APInt KnownZero, KnownOne; + APInt Mask = APInt::getHighBitsSet(VT.getSizeInBits(), + VT.getSizeInBits() - 1); + DAG.ComputeMaskedBits(N2, Mask, KnownZero, KnownOne); + if (KnownZero == Mask) { + SDValue Borrow = DAG.getConstant(0, VT); + SDValue Result = DAG.getNode(ISD::SUB, dl, VT, N0, N2); + SDValue Ops [] = { Borrow, Result }; + return DAG.getMergeValues(Ops, 2, dl); + } + } } break; case ISD::STORE: { diff --git a/test/CodeGen/XCore/ladd_lsub_combine.ll b/test/CodeGen/XCore/ladd_lsub_combine.ll index ea9a3b78f2f..a693ee22291 100644 --- a/test/CodeGen/XCore/ladd_lsub_combine.ll +++ b/test/CodeGen/XCore/ladd_lsub_combine.ll @@ -26,3 +26,42 @@ entry: ; CHECK-NEXT: lsub r1, r0, r1, r0, r2 ; CHECK-NEXT: neg r1, r1 ; CHECK-NEXT: retsp 0 + +; Should compile to one ladd and one add +define i64 @f3(i64 %x, i32 %y) nounwind { +entry: + %0 = zext i32 %y to i64 ; [#uses=1] + %1 = add i64 %x, %0 ; [#uses=1] + ret i64 %1 +} +; CHECK: f3: +; CHECK: ldc r3, 0 +; CHECK-NEXT: ladd r2, r0, r0, r2, r3 +; CHECK-NEXT: add r1, r1, r2 +; CHECK-NEXT: retsp 0 + +; Should compile to one ladd and one add +define i64 @f4(i32 %x, i64 %y) nounwind { +entry: + %0 = zext i32 %x to i64 ; [#uses=1] + %1 = add i64 %0, %y ; [#uses=1] + ret i64 %1 +} +; CHECK: f4: +; CHECK: ldc r3, 0 +; CHECK-NEXT: ladd r1, r0, r0, r1, r3 +; CHECK-NEXT: add r1, r2, r1 +; CHECK-NEXT: retsp 0 + +; Should compile to one lsub and one sub +define i64 @f5(i64 %x, i32 %y) nounwind { +entry: + %0 = zext i32 %y to i64 ; [#uses=1] + %1 = sub i64 %x, %0 ; [#uses=1] + ret i64 %1 +} +; CHECK: f5: +; CHECK: ldc r3, 0 +; CHECK-NEXT: lsub r2, r0, r0, r2, r3 +; CHECK-NEXT: sub r1, r1, r2 +; CHECK-NEXT: retsp 0 -- 2.34.1