This patch fixes issue with lowering below mentioned pattern :-
authorJyoti Allur <jyoti.allur@samsung.com>
Fri, 23 Jan 2015 09:10:03 +0000 (09:10 +0000)
committerJyoti Allur <jyoti.allur@samsung.com>
Fri, 23 Jan 2015 09:10:03 +0000 (09:10 +0000)
_foo:
        smull  r0, r1, r1, r0
smull  r2, r3, r3, r2
adds r0, r2, r0
adc r1, r3, r1
bx lr

to

_foo:
        smull  r0, r1, r1, r0
smlal  r0, r1, r3, r2
bx lr

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@226904 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMISelLowering.cpp
test/CodeGen/ARM/longMAC.ll

index f92f257cd7eb69a4570652e049aedcf1d6e2ed0c..eab513e1d358009225d433dfc7d2b29a05bd5719 100644 (file)
@@ -8058,29 +8058,35 @@ static SDValue AddCombineTo64bitMLAL(SDNode *AddcNode,
   else
     IsLeftOperandMUL = true;
   if (MULOp == SDValue())
-     return SDValue();
+    return SDValue();
 
   // Figure out the right opcode.
   unsigned Opc = MULOp->getOpcode();
   unsigned FinalOpc = (Opc == ISD::SMUL_LOHI) ? ARMISD::SMLAL : ARMISD::UMLAL;
 
   // Figure out the high and low input values to the MLAL node.
-  SDValue* HiMul = &MULOp;
   SDValue* HiAdd = nullptr;
   SDValue* LoMul = nullptr;
   SDValue* LowAdd = nullptr;
 
+  // Ensure that ADDE is from high result of ISD::SMUL_LOHI.
+  if ((AddeOp0 != MULOp.getValue(1)) && (AddeOp1 != MULOp.getValue(1)))
+    return SDValue();
+
   if (IsLeftOperandMUL)
     HiAdd = &AddeOp1;
   else
     HiAdd = &AddeOp0;
 
 
-  if (AddcOp0->getOpcode() == Opc) {
+  // Ensure that LoMul and LowAdd are taken from correct ISD::SMUL_LOHI node
+  // whose low result is fed to the ADDC we are checking.
+
+  if (AddcOp0 == MULOp.getValue(0)) {
     LoMul = &AddcOp0;
     LowAdd = &AddcOp1;
   }
-  if (AddcOp1->getOpcode() == Opc) {
+  if (AddcOp1 == MULOp.getValue(0)) {
     LoMul = &AddcOp1;
     LowAdd = &AddcOp0;
   }
@@ -8088,9 +8094,6 @@ static SDValue AddCombineTo64bitMLAL(SDNode *AddcNode,
   if (!LoMul)
     return SDValue();
 
-  if (LoMul->getNode() != HiMul->getNode())
-    return SDValue();
-
   // Create the merged node.
   SelectionDAG &DAG = DCI.DAG;
 
index fed6ec02f32d9018d0e51cc7807b9dc813b4c114..3f30fd40b7e786a0b1a667bf47ace4ef4c4b66b8 100644 (file)
@@ -75,3 +75,44 @@ define i64 @MACLongTest5(i64 %c, i32 %a, i32 %b) {
   %add = add i64 %mul, %c
   ret i64 %add
 }
+
+define i64 @MACLongTest6(i32 %a, i32 %b, i32 %c, i32 %d) {
+;CHECK-LABEL: MACLongTest6:
+;CHECK: smull   r12, lr, r1, r0
+;CHECK: smlal   r12, lr, r3, r2
+  %conv = sext i32 %a to i64
+  %conv1 = sext i32 %b to i64
+  %mul = mul nsw i64 %conv1, %conv
+  %conv2 = sext i32 %c to i64
+  %conv3 = sext i32 %d to i64
+  %mul4 = mul nsw i64 %conv3, %conv2
+  %add = add nsw i64 %mul4, %mul
+  ret i64 %add
+}
+
+define i64 @MACLongTest7(i64 %acc, i32 %lhs, i32 %rhs) {
+;CHECK-LABEL: MACLongTest7:
+;CHECK-NOT: smlal
+  %conv = sext i32 %lhs to i64
+  %conv1 = sext i32 %rhs to i64
+  %mul = mul nsw i64 %conv1, %conv
+  %shl = shl i64 %mul, 32
+  %shr = lshr i64 %mul, 32
+  %or = or i64 %shl, %shr
+  %add = add i64 %or, %acc
+  ret i64 %add
+}
+
+define i64 @MACLongTest8(i64 %acc, i32 %lhs, i32 %rhs) {
+;CHECK-LABEL: MACLongTest8:
+;CHECK-NOT: smlal
+  %conv = zext i32 %lhs to i64
+  %conv1 = zext i32 %rhs to i64
+  %mul = mul nuw i64 %conv1, %conv
+  %and = and i64 %mul, 4294967295
+  %shl = shl i64 %mul, 32
+  %or = or i64 %and, %shl
+  %add = add i64 %or, %acc
+  ret i64 %add
+}
+