xref: /llvm-project/llvm/test/CodeGen/ARM/smml.ll (revision 9c4c2f24725e9f98b96fb360894276d342c3ba50)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=arm-eabi %s -o - | FileCheck %s --check-prefixes=CHECK-V4
3; RUN: llc -mtriple=armv6-eabi %s -o - | FileCheck %s --check-prefixes=CHECK-V6V7,CHECK-ARM-V6V7,CHECK-V6
4; RUN: llc -mtriple=armv7-eabi %s -o - | FileCheck %s --check-prefixes=CHECK-V6V7,CHECK-ARM-V6V7,CHECK-V7
5; RUN: llc -mtriple=thumb-eabi %s -o - | FileCheck %s --check-prefixes=CHECK-THUMB
6; RUN: llc -mtriple=thumbv6-eabi %s -o - | FileCheck %s --check-prefixes=CHECK-THUMBV6
7; RUN: llc -mtriple=thumbv6t2-eabi %s -o - | FileCheck %s --check-prefixes=CHECK-V6V7,CHECK-THUMB-V6V7,CHECK-THUMBV6T2
8; RUN: llc -mtriple=thumbv7-eabi %s -o - | FileCheck %s --check-prefixes=CHECK-V6V7,CHECK-THUMB-V6V7,CHECK-THUMBV7
9; RUN: llc -mtriple=thumbv7m-eabi %s -o - | FileCheck %s --check-prefixes=CHECK-THUMBV7M
10; RUN: llc -mtriple=thumbv7em-eabi %s -o - | FileCheck %s --check-prefixes=CHECK-V6V7,CHECK-THUMB-V6V7,CHECK-THUMBV7EM
11
12; Next test would previously trigger an assertion responsible for verification of
13; call site info state.
14; RUN: llc -stop-after=if-converter -debug-entry-values -mtriple=thumbv6t2-eabi %s -o -| FileCheck %s -check-prefix=CHECK-CALLSITE
15; CHECK-CALLSITE: name:  test_used_flags
16; CHECK-CALLSITE: callSites:
17
18define i32 @Test0(i32 %a, i32 %b, i32 %c) nounwind readnone ssp {
19; CHECK-V4-LABEL: Test0:
20; CHECK-V4:       @ %bb.0: @ %entry
21; CHECK-V4-NEXT:    smull r3, r12, r2, r1
22; CHECK-V4-NEXT:    sub r0, r0, r12
23; CHECK-V4-NEXT:    mov pc, lr
24;
25; CHECK-ARM-V6V7-LABEL: Test0:
26; CHECK-ARM-V6V7:       @ %bb.0: @ %entry
27; CHECK-ARM-V6V7-NEXT:    smmul r1, r2, r1
28; CHECK-ARM-V6V7-NEXT:    sub r0, r0, r1
29; CHECK-ARM-V6V7-NEXT:    bx lr
30;
31; CHECK-THUMB-LABEL: Test0:
32; CHECK-THUMB:       @ %bb.0: @ %entry
33; CHECK-THUMB-NEXT:    .save {r4, r5, r7, lr}
34; CHECK-THUMB-NEXT:    push {r4, r5, r7, lr}
35; CHECK-THUMB-NEXT:    movs r5, r1
36; CHECK-THUMB-NEXT:    movs r4, r0
37; CHECK-THUMB-NEXT:    asrs r1, r2, #31
38; CHECK-THUMB-NEXT:    asrs r3, r5, #31
39; CHECK-THUMB-NEXT:    movs r0, r2
40; CHECK-THUMB-NEXT:    movs r2, r5
41; CHECK-THUMB-NEXT:    bl __aeabi_lmul
42; CHECK-THUMB-NEXT:    subs r0, r4, r1
43; CHECK-THUMB-NEXT:    pop {r4, r5, r7}
44; CHECK-THUMB-NEXT:    pop {r1}
45; CHECK-THUMB-NEXT:    bx r1
46;
47; CHECK-THUMBV6-LABEL: Test0:
48; CHECK-THUMBV6:       @ %bb.0: @ %entry
49; CHECK-THUMBV6-NEXT:    .save {r4, r5, r7, lr}
50; CHECK-THUMBV6-NEXT:    push {r4, r5, r7, lr}
51; CHECK-THUMBV6-NEXT:    mov r5, r1
52; CHECK-THUMBV6-NEXT:    mov r4, r0
53; CHECK-THUMBV6-NEXT:    asrs r1, r2, #31
54; CHECK-THUMBV6-NEXT:    asrs r3, r5, #31
55; CHECK-THUMBV6-NEXT:    mov r0, r2
56; CHECK-THUMBV6-NEXT:    mov r2, r5
57; CHECK-THUMBV6-NEXT:    bl __aeabi_lmul
58; CHECK-THUMBV6-NEXT:    subs r0, r4, r1
59; CHECK-THUMBV6-NEXT:    pop {r4, r5, r7, pc}
60;
61; CHECK-THUMB-V6V7-LABEL: Test0:
62; CHECK-THUMB-V6V7:       @ %bb.0: @ %entry
63; CHECK-THUMB-V6V7-NEXT:    smmul r1, r2, r1
64; CHECK-THUMB-V6V7-NEXT:    subs r0, r0, r1
65; CHECK-THUMB-V6V7-NEXT:    bx lr
66;
67; CHECK-THUMBV7M-LABEL: Test0:
68; CHECK-THUMBV7M:       @ %bb.0: @ %entry
69; CHECK-THUMBV7M-NEXT:    smull r1, r2, r2, r1
70; CHECK-THUMBV7M-NEXT:    subs r0, r0, r2
71; CHECK-THUMBV7M-NEXT:    bx lr
72entry:
73  %conv4 = zext i32 %a to i64
74  %conv1 = sext i32 %b to i64
75  %conv2 = sext i32 %c to i64
76  %mul = mul nsw i64 %conv2, %conv1
77  %shr5 = lshr i64 %mul, 32
78  %sub = sub nsw i64 %conv4, %shr5
79  %conv3 = trunc i64 %sub to i32
80  ret i32 %conv3
81}
82
83define i32 @Test1(i32 %a, i32 %b, i32 %c) {
84; CHECK-V4-LABEL: Test1:
85; CHECK-V4:       @ %bb.0: @ %entry
86; CHECK-V4-NEXT:    smull r3, r12, r2, r1
87; CHECK-V4-NEXT:    rsbs r1, r3, #0
88; CHECK-V4-NEXT:    sbc r0, r0, r12
89; CHECK-V4-NEXT:    mov pc, lr
90;
91; CHECK-V6V7-LABEL: Test1:
92; CHECK-V6V7:       @ %bb.0: @ %entry
93; CHECK-V6V7-NEXT:    smmls r0, r2, r1, r0
94; CHECK-V6V7-NEXT:    bx lr
95;
96; CHECK-THUMB-LABEL: Test1:
97; CHECK-THUMB:       @ %bb.0: @ %entry
98; CHECK-THUMB-NEXT:    .save {r4, r5, r7, lr}
99; CHECK-THUMB-NEXT:    push {r4, r5, r7, lr}
100; CHECK-THUMB-NEXT:    movs r5, r1
101; CHECK-THUMB-NEXT:    movs r4, r0
102; CHECK-THUMB-NEXT:    asrs r1, r2, #31
103; CHECK-THUMB-NEXT:    asrs r3, r5, #31
104; CHECK-THUMB-NEXT:    movs r0, r2
105; CHECK-THUMB-NEXT:    movs r2, r5
106; CHECK-THUMB-NEXT:    bl __aeabi_lmul
107; CHECK-THUMB-NEXT:    rsbs r0, r0, #0
108; CHECK-THUMB-NEXT:    sbcs r4, r1
109; CHECK-THUMB-NEXT:    movs r0, r4
110; CHECK-THUMB-NEXT:    pop {r4, r5, r7}
111; CHECK-THUMB-NEXT:    pop {r1}
112; CHECK-THUMB-NEXT:    bx r1
113;
114; CHECK-THUMBV6-LABEL: Test1:
115; CHECK-THUMBV6:       @ %bb.0: @ %entry
116; CHECK-THUMBV6-NEXT:    .save {r4, r5, r7, lr}
117; CHECK-THUMBV6-NEXT:    push {r4, r5, r7, lr}
118; CHECK-THUMBV6-NEXT:    mov r5, r1
119; CHECK-THUMBV6-NEXT:    mov r4, r0
120; CHECK-THUMBV6-NEXT:    asrs r1, r2, #31
121; CHECK-THUMBV6-NEXT:    asrs r3, r5, #31
122; CHECK-THUMBV6-NEXT:    mov r0, r2
123; CHECK-THUMBV6-NEXT:    mov r2, r5
124; CHECK-THUMBV6-NEXT:    bl __aeabi_lmul
125; CHECK-THUMBV6-NEXT:    rsbs r0, r0, #0
126; CHECK-THUMBV6-NEXT:    sbcs r4, r1
127; CHECK-THUMBV6-NEXT:    mov r0, r4
128; CHECK-THUMBV6-NEXT:    pop {r4, r5, r7, pc}
129;
130; CHECK-THUMBV7M-LABEL: Test1:
131; CHECK-THUMBV7M:       @ %bb.0: @ %entry
132; CHECK-THUMBV7M-NEXT:    smull r1, r2, r2, r1
133; CHECK-THUMBV7M-NEXT:    rsbs r1, r1, #0
134; CHECK-THUMBV7M-NEXT:    sbcs r0, r2
135; CHECK-THUMBV7M-NEXT:    bx lr
136entry:
137  %conv = sext i32 %b to i64
138  %conv1 = sext i32 %c to i64
139  %mul = mul nsw i64 %conv1, %conv
140  %conv26 = zext i32 %a to i64
141  %shl = shl nuw i64 %conv26, 32
142  %sub = sub nsw i64 %shl, %mul
143  %shr7 = lshr i64 %sub, 32
144  %conv3 = trunc i64 %shr7 to i32
145  ret i32 %conv3
146}
147
148declare void @opaque(i32)
149define void @test_used_flags(i32 %in1, i32 %in2) {
150; CHECK-V4-LABEL: test_used_flags:
151; CHECK-V4:       @ %bb.0:
152; CHECK-V4-NEXT:    .save {r11, lr}
153; CHECK-V4-NEXT:    push {r11, lr}
154; CHECK-V4-NEXT:    smull r2, r3, r0, r1
155; CHECK-V4-NEXT:    rsbs r0, r2, #0
156; CHECK-V4-NEXT:    rscs r0, r3, #0
157; CHECK-V4-NEXT:    movge r0, #42
158; CHECK-V4-NEXT:    movlt r0, #56
159; CHECK-V4-NEXT:    bl opaque
160; CHECK-V4-NEXT:    pop {r11, lr}
161; CHECK-V4-NEXT:    mov pc, lr
162;
163; CHECK-V6-LABEL: test_used_flags:
164; CHECK-V6:       @ %bb.0: @ %common.ret
165; CHECK-V6-NEXT:    .save {r11, lr}
166; CHECK-V6-NEXT:    push {r11, lr}
167; CHECK-V6-NEXT:    smull r1, r2, r0, r1
168; CHECK-V6-NEXT:    mov r0, #56
169; CHECK-V6-NEXT:    subs r1, r1, #1
170; CHECK-V6-NEXT:    sbcs r1, r2, #0
171; CHECK-V6-NEXT:    movlt r0, #42
172; CHECK-V6-NEXT:    bl opaque
173; CHECK-V6-NEXT:    pop {r11, pc}
174;
175; CHECK-V7-LABEL: test_used_flags:
176; CHECK-V7:       @ %bb.0: @ %common.ret
177; CHECK-V7-NEXT:    .save {r11, lr}
178; CHECK-V7-NEXT:    push {r11, lr}
179; CHECK-V7-NEXT:    smull r1, r2, r0, r1
180; CHECK-V7-NEXT:    mov r0, #56
181; CHECK-V7-NEXT:    subs r1, r1, #1
182; CHECK-V7-NEXT:    sbcs r1, r2, #0
183; CHECK-V7-NEXT:    movwlt r0, #42
184; CHECK-V7-NEXT:    bl opaque
185; CHECK-V7-NEXT:    pop {r11, pc}
186;
187; CHECK-THUMB-LABEL: test_used_flags:
188; CHECK-THUMB:       @ %bb.0:
189; CHECK-THUMB-NEXT:    .save {r7, lr}
190; CHECK-THUMB-NEXT:    push {r7, lr}
191; CHECK-THUMB-NEXT:    movs r2, r1
192; CHECK-THUMB-NEXT:    asrs r1, r0, #31
193; CHECK-THUMB-NEXT:    asrs r3, r2, #31
194; CHECK-THUMB-NEXT:    bl __aeabi_lmul
195; CHECK-THUMB-NEXT:    movs r2, #0
196; CHECK-THUMB-NEXT:    rsbs r0, r0, #0
197; CHECK-THUMB-NEXT:    sbcs r2, r1
198; CHECK-THUMB-NEXT:    bge .LBB2_2
199; CHECK-THUMB-NEXT:  @ %bb.1: @ %false
200; CHECK-THUMB-NEXT:    movs r0, #56
201; CHECK-THUMB-NEXT:    b .LBB2_3
202; CHECK-THUMB-NEXT:  .LBB2_2: @ %true
203; CHECK-THUMB-NEXT:    movs r0, #42
204; CHECK-THUMB-NEXT:  .LBB2_3: @ %true
205; CHECK-THUMB-NEXT:    bl opaque
206; CHECK-THUMB-NEXT:    pop {r7}
207; CHECK-THUMB-NEXT:    pop {r0}
208; CHECK-THUMB-NEXT:    bx r0
209;
210; CHECK-THUMBV6-LABEL: test_used_flags:
211; CHECK-THUMBV6:       @ %bb.0:
212; CHECK-THUMBV6-NEXT:    .save {r7, lr}
213; CHECK-THUMBV6-NEXT:    push {r7, lr}
214; CHECK-THUMBV6-NEXT:    mov r2, r1
215; CHECK-THUMBV6-NEXT:    asrs r1, r0, #31
216; CHECK-THUMBV6-NEXT:    asrs r3, r2, #31
217; CHECK-THUMBV6-NEXT:    bl __aeabi_lmul
218; CHECK-THUMBV6-NEXT:    movs r2, #0
219; CHECK-THUMBV6-NEXT:    rsbs r0, r0, #0
220; CHECK-THUMBV6-NEXT:    sbcs r2, r1
221; CHECK-THUMBV6-NEXT:    bge .LBB2_2
222; CHECK-THUMBV6-NEXT:  @ %bb.1: @ %false
223; CHECK-THUMBV6-NEXT:    movs r0, #56
224; CHECK-THUMBV6-NEXT:    bl opaque
225; CHECK-THUMBV6-NEXT:    pop {r7, pc}
226; CHECK-THUMBV6-NEXT:  .LBB2_2: @ %true
227; CHECK-THUMBV6-NEXT:    movs r0, #42
228; CHECK-THUMBV6-NEXT:    bl opaque
229; CHECK-THUMBV6-NEXT:    pop {r7, pc}
230;
231; CHECK-THUMBV6T2-LABEL: test_used_flags:
232; CHECK-THUMBV6T2:       @ %bb.0:
233; CHECK-THUMBV6T2-NEXT:    .save {r7, lr}
234; CHECK-THUMBV6T2-NEXT:    push {r7, lr}
235; CHECK-THUMBV6T2-NEXT:    smull r0, r1, r0, r1
236; CHECK-THUMBV6T2-NEXT:    movs r2, #0
237; CHECK-THUMBV6T2-NEXT:    rsbs r0, r0, #0
238; CHECK-THUMBV6T2-NEXT:    sbcs.w r0, r2, r1
239; CHECK-THUMBV6T2-NEXT:    ite lt
240; CHECK-THUMBV6T2-NEXT:    movlt r0, #56
241; CHECK-THUMBV6T2-NEXT:    movge r0, #42
242; CHECK-THUMBV6T2-NEXT:    bl opaque
243; CHECK-THUMBV6T2-NEXT:    pop {r7, pc}
244;
245; CHECK-THUMBV7-LABEL: test_used_flags:
246; CHECK-THUMBV7:       @ %bb.0: @ %common.ret
247; CHECK-THUMBV7-NEXT:    .save {r7, lr}
248; CHECK-THUMBV7-NEXT:    push {r7, lr}
249; CHECK-THUMBV7-NEXT:    smull r1, r2, r0, r1
250; CHECK-THUMBV7-NEXT:    movs r0, #56
251; CHECK-THUMBV7-NEXT:    subs r1, #1
252; CHECK-THUMBV7-NEXT:    sbcs r1, r2, #0
253; CHECK-THUMBV7-NEXT:    it lt
254; CHECK-THUMBV7-NEXT:    movlt r0, #42
255; CHECK-THUMBV7-NEXT:    bl opaque
256; CHECK-THUMBV7-NEXT:    pop {r7, pc}
257;
258; CHECK-THUMBV7M-LABEL: test_used_flags:
259; CHECK-THUMBV7M:       @ %bb.0: @ %common.ret
260; CHECK-THUMBV7M-NEXT:    .save {r7, lr}
261; CHECK-THUMBV7M-NEXT:    push {r7, lr}
262; CHECK-THUMBV7M-NEXT:    smull r1, r2, r0, r1
263; CHECK-THUMBV7M-NEXT:    movs r0, #56
264; CHECK-THUMBV7M-NEXT:    subs r1, #1
265; CHECK-THUMBV7M-NEXT:    sbcs r1, r2, #0
266; CHECK-THUMBV7M-NEXT:    it lt
267; CHECK-THUMBV7M-NEXT:    movlt r0, #42
268; CHECK-THUMBV7M-NEXT:    bl opaque
269; CHECK-THUMBV7M-NEXT:    pop {r7, pc}
270;
271; CHECK-THUMBV7EM-LABEL: test_used_flags:
272; CHECK-THUMBV7EM:       @ %bb.0: @ %common.ret
273; CHECK-THUMBV7EM-NEXT:    .save {r7, lr}
274; CHECK-THUMBV7EM-NEXT:    push {r7, lr}
275; CHECK-THUMBV7EM-NEXT:    smull r1, r2, r0, r1
276; CHECK-THUMBV7EM-NEXT:    movs r0, #56
277; CHECK-THUMBV7EM-NEXT:    subs r1, #1
278; CHECK-THUMBV7EM-NEXT:    sbcs r1, r2, #0
279; CHECK-THUMBV7EM-NEXT:    it lt
280; CHECK-THUMBV7EM-NEXT:    movlt r0, #42
281; CHECK-THUMBV7EM-NEXT:    bl opaque
282; CHECK-THUMBV7EM-NEXT:    pop {r7, pc}
283  %in1.64 = sext i32 %in1 to i64
284  %in2.64 = sext i32 %in2 to i64
285  %mul = mul nsw i64 %in1.64, %in2.64
286  %tst = icmp slt i64 %mul, 1
287  br i1 %tst, label %true, label %false
288
289true:
290  call void @opaque(i32 42)
291  ret void
292
293false:
294  call void @opaque(i32 56)
295  ret void
296}
297