In cases where the carry / borrow unused converted ladd / lsub
authorRichard Osborne <richard@xmos.com>
Tue, 9 Mar 2010 16:34:25 +0000 (16:34 +0000)
committerRichard Osborne <richard@xmos.com>
Tue, 9 Mar 2010 16:34:25 +0000 (16:34 +0000)
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
test/CodeGen/XCore/ladd_lsub_combine.ll

index d8cbd037cb2de4a175deeddce0dfddd63959bf72..7ecd15135a9c99be014130aa9b571c5aa6cbfad2 100644 (file)
@@ -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: {
index ea9a3b78f2ffca5e86540ccd2688dc0b49ffedee..a693ee22291a23ed8acfc4f6b9f17e6a23754964 100644 (file)
@@ -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         ; <i64> [#uses=1]
+       %1 = add i64 %x, %0             ; <i64> [#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         ; <i64> [#uses=1]
+       %1 = add i64 %0, %y             ; <i64> [#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         ; <i64> [#uses=1]
+       %1 = sub i64 %x, %0             ; <i64> [#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