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