1; RUN: llc -mtriple=arm-eabi %s -o - | FileCheck %s
2; RUN: llc -mtriple=armv6-eabi %s -o - | FileCheck %s -check-prefix=CHECK-V6
3; RUN: llc -mtriple=armv7-eabi %s -o - | FileCheck %s -check-prefix=CHECK-V7
4; RUN: llc -mtriple=thumb-eabi %s -o - | FileCheck %s -check-prefix=CHECK-THUMB
5; RUN: llc -mtriple=thumbv6-eabi %s -o - | FileCheck %s -check-prefix=CHECK-THUMB
6; RUN: llc -mtriple=thumbv6t2-eabi %s -o - | FileCheck %s -check-prefix=CHECK-THUMBV6T2
7; RUN: llc -mtriple=thumbv7-eabi %s -o - | FileCheck %s -check-prefix=CHECK-THUMBV7
8
9define i32 @Test0(i32 %a, i32 %b, i32 %c) nounwind readnone ssp {
10entry:
11; CHECK-LABEL: Test0
12; CHECK-NOT: smmls
13; CHECK-V6-NOT: smmls
14; CHECK-V7-NOT: smmls
15; CHECK_THUMB-NOT: smmls
16; CHECK-THUMBV6T2-NOT: smmls
17; CHECK-THUMBV7-NOT: smmls
18  %conv4 = zext i32 %a to i64
19  %conv1 = sext i32 %b to i64
20  %conv2 = sext i32 %c to i64
21  %mul = mul nsw i64 %conv2, %conv1
22  %shr5 = lshr i64 %mul, 32
23  %sub = sub nsw i64 %conv4, %shr5
24  %conv3 = trunc i64 %sub to i32
25  ret i32 %conv3
26}
27
28define i32 @Test1(i32 %a, i32 %b, i32 %c) {
29;CHECK-LABEL: Test1
30;CHECK-NOT: smmls
31;CHECK-THUMB-NOT: smmls
32;CHECK-V6: smmls r0, [[Rn:r[1-2]]], [[Rm:r[1-2]]], r0
33;CHECK-V7: smmls r0, [[Rn:r[1-2]]], [[Rm:r[1-2]]], r0
34;CHECK-THUMBV6T2: smmls r0, [[Rn:r[1-2]]], [[Rm:r[1-2]]], r0
35;CHECK-THUMBV7: smmls r0, [[Rn:r[1-2]]], [[Rm:r[1-2]]], r0
36entry:
37  %conv = sext i32 %b to i64
38  %conv1 = sext i32 %c to i64
39  %mul = mul nsw i64 %conv1, %conv
40  %conv26 = zext i32 %a to i64
41  %shl = shl nuw i64 %conv26, 32
42  %sub = sub nsw i64 %shl, %mul
43  %shr7 = lshr i64 %sub, 32
44  %conv3 = trunc i64 %shr7 to i32
45  ret i32 %conv3
46}
47
48declare void @opaque(i32)
49define void @test_used_flags(i32 %in1, i32 %in2) {
50; CHECK-V7-LABEL: test_used_flags:
51; CHECK-V7: smull [[PROD_LO:r[0-9]+]], [[PROD_HI:r[0-9]+]], r0, r1
52; CHECK-V7: rsbs {{.*}}, [[PROD_LO]], #0
53; CHECK-V7: rscs {{.*}}, [[PROD_HI]], #0
54  %in1.64 = sext i32 %in1 to i64
55  %in2.64 = sext i32 %in2 to i64
56  %mul = mul nsw i64 %in1.64, %in2.64
57  %tst = icmp slt i64 %mul, 1
58  br i1 %tst, label %true, label %false
59
60true:
61  call void @opaque(i32 42)
62  ret void
63
64false:
65  call void @opaque(i32 56)
66  ret void
67}
68