Index: llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp =================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -2992,7 +2992,8 @@ case ARMISD::UMLAL:{ // UMAAL is similar to UMLAL but it adds two 32-bit values to the // 64-bit multiplication result. - if (Subtarget->hasV6Ops() && N->getOperand(2).getOpcode() == ARMISD::ADDC && + if (Subtarget->hasV6Ops() && Subtarget->hasDSP() && + N->getOperand(2).getOpcode() == ARMISD::ADDC && N->getOperand(3).getOpcode() == ARMISD::ADDE) { SDValue Addc = N->getOperand(2); Index: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp =================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp @@ -9354,7 +9354,7 @@ // be combined into a UMLAL. The other pattern is AddcNode being combined // into an UMLAL and then using another addc is handled in ISelDAGToDAG. - if (!Subtarget->hasV6Ops() || + if (!Subtarget->hasV6Ops() || !Subtarget->hasDSP() || (Subtarget->isThumb() && !Subtarget->hasThumb2())) return AddCombineTo64bitMLAL(AddcNode, DCI, Subtarget); Index: llvm/trunk/test/CodeGen/ARM/longMAC.ll =================================================================== --- llvm/trunk/test/CodeGen/ARM/longMAC.ll +++ llvm/trunk/test/CodeGen/ARM/longMAC.ll @@ -6,6 +6,9 @@ ; RUN: llc -mtriple=thumbv6t2-eabi %s -o - | FileCheck %s -check-prefix=CHECK-V6-THUMB2 ; RUN: llc -mtriple=thumbv7-eabi %s -o - | FileCheck %s -check-prefix=CHECK-V7-THUMB ; RUN: llc -mtriple=thumbebv7-eabi %s -o - | FileCheck %s -check-prefix=CHECK-V7-THUMB-BE +; RUN: llc -mtriple=thumbv6m-eabi %s -o - | FileCheck %s -check-prefix=CHECK-V6M-THUMB +; RUN: llc -mtriple=thumbv7m-eabi %s -o - | FileCheck %s -check-prefix=CHECK-V7M-THUMB +; RUN: llc -mtriple=thumbv7em-eabi %s -o - | FileCheck %s -check-prefix=CHECK-V7EM-THUMB ; Check generated signed and unsigned multiply accumulate long. define i64 @MACLongTest1(i32 %a, i32 %b, i64 %c) { @@ -20,12 +23,12 @@ ;CHECK-V6-THUMB2: umlal [[RDLO:r[0-9]+]], [[RDHI:r[0-9]+]], [[LHS:r[0-9]+]], [[RHS:r[0-9]+]] ;CHECK-V6-THUMB2: mov r0, [[RDLO]] ;CHECK-V6-THUMB2: mov r1, [[RDHI]] -;CHECK-V7-THUMB2: umlal [[RDLO:r[0-9]+]], [[RDHI:r[0-9]+]], [[LHS:r[0-9]+]], [[RHS:r[0-9]+]] -;CHECK-V7-THUMB2: mov r0, [[RDLO]] -;CHECK-V7-THUMB2: mov r1, [[RDHI]] -;CHECK-V7-THUMB2-BE: umlal [[RDLO:r[0-9]+]], [[RDHI:r[0-9]+]], [[LHS:r[0-9]+]], [[RHS:r[0-9]+]] -;CHECK-V7-THUMB2-BE: mov r0, [[RDHI]] -;CHECK-V7-THUMB2-BE: mov r1, [[RDLO]] +;CHECK-V7-THUMB: umlal [[RDLO:r[0-9]+]], [[RDHI:r[0-9]+]], [[LHS:r[0-9]+]], [[RHS:r[0-9]+]] +;CHECK-V7-THUMB: mov r0, [[RDLO]] +;CHECK-V7-THUMB: mov r1, [[RDHI]] +;CHECK-V7-THUMB-BE: umlal [[RDLO:r[0-9]+]], [[RDHI:r[0-9]+]], [[LHS:r[0-9]+]], [[RHS:r[0-9]+]] +;CHECK-V7-THUMB-BE: mov r0, [[RDHI]] +;CHECK-V7-THUMB-BE: mov r1, [[RDLO]] %conv = zext i32 %a to i64 %conv1 = zext i32 %b to i64 %mul = mul i64 %conv1, %conv @@ -44,12 +47,12 @@ ;CHECK-V6-THUMB2: smlal [[RDLO:r[0-9]+]], [[RDHI:r[0-9]+]], [[LHS:r[0-9]+]], [[RHS:r[0-9]+]] ;CHECK-V6-THUMB2: mov r0, [[RDLO]] ;CHECK-V6-THUMB2: mov r1, [[RDHI]] -;CHECK-V7-THUMB2: smlal [[RDLO:r[0-9]+]], [[RDHI:r[0-9]+]], [[LHS:r[0-9]+]], [[RHS:r[0-9]+]] -;CHECK-V7-THUMB2: mov r0, [[RDLO]] -;CHECK-V7-THUMB2: mov r1, [[RDHI]] -;CHECK-V7-THUMB2-BE: smlal [[RDLO:r[0-9]+]], [[RDHI:r[0-9]+]], [[LHS:r[0-9]+]], [[RHS:r[0-9]+]] -;CHECK-V7-THUMB2-BE: mov r0, [[RDHI]] -;CHECK-V7-THUMB2-BE: mov r1, [[RDLO]] +;CHECK-V7-THUMB: smlal [[RDLO:r[0-9]+]], [[RDHI:r[0-9]+]], [[LHS:r[0-9]+]], [[RHS:r[0-9]+]] +;CHECK-V7-THUMB: mov r0, [[RDLO]] +;CHECK-V7-THUMB: mov r1, [[RDHI]] +;CHECK-V7-THUMB-BE: smlal [[RDLO:r[0-9]+]], [[RDHI:r[0-9]+]], [[LHS:r[0-9]+]], [[RHS:r[0-9]+]] +;CHECK-V7-THUMB-BE: mov r0, [[RDHI]] +;CHECK-V7-THUMB-BE: mov r1, [[RDLO]] %conv = sext i32 %a to i64 %conv1 = sext i32 %b to i64 %mul = mul nsw i64 %conv1, %conv @@ -178,8 +181,13 @@ ;CHECK-V7-THUMB-BE: umaal [[RDLO:r[0-9]+]], [[RDHI:r[0-9]+]], [[LHS:r[0-9]+]], [[RHS:r[0-9]+]] ;CHECK-V7-THUMB-BE: mov r0, [[RDHI]] ;CHECK-V7-THUMB-BE: mov r1, [[RDLO]] +;CHECK-V7EM-THUMB: umaal [[RDLO:r[0-9]+]], [[RDHI:r[0-9]+]], [[LHS:r[0-9]+]], [[RHS:r[0-9]+]] +;CHECK-V7EM-THUMB: mov r0, [[RDLO]] +;CHECK-V7EM-THUMB: mov r1, [[RDHI]] ;CHECK-NOT:umaal ;CHECK-V6-THUMB-NOT: umaal +;CHECK-V6M-THUMB-NOT: umaal +;CHECK-V7M-THUMB-NOT: umaal %conv = zext i32 %lhs to i64 %conv1 = zext i32 %rhs to i64 %mul = mul nuw i64 %conv1, %conv @@ -207,12 +215,16 @@ ;CHECK-V7-THUMB-BE: umaal [[RDLO:r[0-9]+]], [[RDHI:r[0-9]+]], [[LHS:r[0-9]+]], [[RHS:r[0-9]+]] ;CHECK-V7-THUMB-BE: mov r0, [[RDHI]] ;CHECK-V7-THUMB-BE: mov r1, [[RDLO]] +;CHECK-V7EM-THUMB: umaal [[RDLO:r[0-9]+]], [[RDHI:r[0-9]+]], [[LHS:r[0-9]+]], [[RHS:r[0-9]+]] +;CHECK-V7EM-THUMB: mov r0, [[RDLO]] +;CHECK-V7EM-THUMB: mov r1, [[RDHI]] ;CHECK-NOT:umaal ;CHECK-V6-THUMB-NOT:umaal +;CHECK-V6M-THUMB-NOT: umaal +;CHECK-V7M-THUMB-NOT: umaal %conv = zext i32 %lhs to i64 %conv1 = zext i32 %rhs to i64 - %mul = mul nuw i64 %conv1, %conv - %conv2 = zext i32 %lo to i64 + %mul = mul nuw i64 %conv1, %conv %conv2 = zext i32 %lo to i64 %conv3 = zext i32 %hi to i64 %add = add i64 %conv2, %conv3 %add2 = add i64 %add, %mul