1; RUN: llc < %s -march=arm | FileCheck %s 2; RUN: llc < %s -mtriple=armv7 | FileCheck %s --check-prefix=CHECK-V7 3; Check generated signed and unsigned multiply accumulate long. 4 5define i64 @MACLongTest1(i32 %a, i32 %b, i64 %c) { 6;CHECK-LABEL: MACLongTest1: 7;CHECK: umlal 8 %conv = zext i32 %a to i64 9 %conv1 = zext i32 %b to i64 10 %mul = mul i64 %conv1, %conv 11 %add = add i64 %mul, %c 12 ret i64 %add 13} 14 15define i64 @MACLongTest2(i32 %a, i32 %b, i64 %c) { 16;CHECK-LABEL: MACLongTest2: 17;CHECK: smlal 18 %conv = sext i32 %a to i64 19 %conv1 = sext i32 %b to i64 20 %mul = mul nsw i64 %conv1, %conv 21 %add = add nsw i64 %mul, %c 22 ret i64 %add 23} 24 25define i64 @MACLongTest3(i32 %a, i32 %b, i32 %c) { 26;CHECK-LABEL: MACLongTest3: 27;CHECK: umlal 28 %conv = zext i32 %b to i64 29 %conv1 = zext i32 %a to i64 30 %mul = mul i64 %conv, %conv1 31 %conv2 = zext i32 %c to i64 32 %add = add i64 %mul, %conv2 33 ret i64 %add 34} 35 36define i64 @MACLongTest4(i32 %a, i32 %b, i32 %c) { 37;CHECK-LABEL: MACLongTest4: 38;CHECK: smlal 39 %conv = sext i32 %b to i64 40 %conv1 = sext i32 %a to i64 41 %mul = mul nsw i64 %conv, %conv1 42 %conv2 = sext i32 %c to i64 43 %add = add nsw i64 %mul, %conv2 44 ret i64 %add 45} 46 47; Two things to check here: the @earlyclobber constraint (on <= v5) and the "$Rd = $R" ones. 48; + Without @earlyclobber the v7 code is natural. With it, the first two 49; registers must be distinct from the third. 50; + Without "$Rd = $R", this can be satisfied without a mov before the umlal 51; by trying to use 6 different registers in the MachineInstr. The natural 52; evolution of this attempt currently leaves only two movs in the final 53; function, both after the umlal. With it, *some* move has to happen 54; before the umlal. 55define i64 @MACLongTest5(i64 %c, i32 %a, i32 %b) { 56; CHECK-V7-LABEL: MACLongTest5: 57; CHECK-V7-LABEL: umlal r0, r1, r0, r0 58 59; CHECK-LABEL: MACLongTest5: 60; CHECK: mov [[RDLO:r[0-9]+]], r0 61; CHECK: umlal [[RDLO]], r1, r0, r0 62; CHECK: mov r0, [[RDLO]] 63 64 %conv.trunc = trunc i64 %c to i32 65 %conv = zext i32 %conv.trunc to i64 66 %conv1 = zext i32 %b to i64 67 %mul = mul i64 %conv, %conv 68 %add = add i64 %mul, %c 69 ret i64 %add 70} 71