xref: /llvm-project/llvm/test/CodeGen/Thumb2/thumb2-ifcvt1.ll (revision b5b663aac17415625340eb29c8010832bfc4c21c)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=thumbv7-apple-darwin | FileCheck %s --check-prefixes=ALL,V01
3; RUN: llc < %s -mtriple=thumbv7-apple-darwin -arm-default-it | FileCheck %s --check-prefixes=ALL,V01
4; RUN: llc < %s -mtriple=thumbv8 | FileCheck %s --check-prefixes=ALL,V23,V2
5; RUN: llc < %s -mtriple=thumbv8 -enable-tail-merge=0 | FileCheck %s --check-prefixes=ALL,V23,V3
6
7define i32 @t1(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
8; ALL-LABEL: t1:
9; ALL:       @ %bb.0:
10; ALL-NEXT:    cmp r2, #1
11; ALL-NEXT:    ittee ne
12; ALL-NEXT:    cmpne r2, #7
13; ALL-NEXT:    addne r0, r1
14; ALL-NEXT:    addeq r0, r1
15; ALL-NEXT:    addeq r0, #1
16; ALL-NEXT:    bx lr
17	switch i32 %c, label %cond_next [
18		 i32 1, label %cond_true
19		 i32 7, label %cond_true
20	]
21
22cond_true:
23	%tmp12 = add i32 %a, 1
24	%tmp1518 = add i32 %tmp12, %b
25	ret i32 %tmp1518
26
27cond_next:
28	%tmp15 = add i32 %b, %a
29	ret i32 %tmp15
30}
31
32define i32 @t2(i32 %a, i32 %b) nounwind {
33; V01-LABEL: t2:
34; V01:       @ %bb.0: @ %entry
35; V01-NEXT:    cmp r0, r1
36; V01-NEXT:    it eq
37; V01-NEXT:    bxeq lr
38; V01-NEXT:  LBB1_1: @ %bb
39; V01-NEXT:    @ =>This Inner Loop Header: Depth=1
40; V01-NEXT:    cmp r0, r1
41; V01-NEXT:    ite gt
42; V01-NEXT:    subgt r0, r0, r1
43; V01-NEXT:    suble r1, r1, r0
44; V01-NEXT:    cmp r1, r0
45; V01-NEXT:    bne LBB1_1
46; V01-NEXT:  @ %bb.2: @ %bb17
47; V01-NEXT:    bx lr
48;
49; V2-LABEL: t2:
50; V2:       @ %bb.0: @ %entry
51; V2-NEXT:    cmp r0, r1
52; V2-NEXT:    it eq
53; V2-NEXT:    bxeq lr
54; V2-NEXT:  .LBB1_1: @ %bb
55; V2-NEXT:    @ =>This Inner Loop Header: Depth=1
56; V2-NEXT:    cmp r0, r1
57; V2-NEXT:    ite gt
58; V2-NEXT:    subgt r0, r0, r1
59; V2-NEXT:    suble r1, r1, r0
60; V2-NEXT:    cmp r1, r0
61; V2-NEXT:    bne .LBB1_1
62; V2-NEXT:  @ %bb.2: @ %bb17
63; V2-NEXT:    bx lr
64;
65; V3-LABEL: t2:
66; V3:       @ %bb.0: @ %entry
67; V3-NEXT:    cmp r0, r1
68; V3-NEXT:    it eq
69; V3-NEXT:    bxeq lr
70; V3-NEXT:  .LBB1_1: @ %bb
71; V3-NEXT:    @ =>This Inner Loop Header: Depth=1
72; V3-NEXT:    cmp r0, r1
73; V3-NEXT:    ite le
74; V3-NEXT:    suble r1, r1, r0
75; V3-NEXT:    subgt r0, r0, r1
76; V3-NEXT:    cmp r1, r0
77; V3-NEXT:    bne .LBB1_1
78; V3-NEXT:  @ %bb.2: @ %bb17
79; V3-NEXT:    bx lr
80entry:
81	%tmp1434 = icmp eq i32 %a, %b		; <i1> [#uses=1]
82	br i1 %tmp1434, label %bb17, label %bb.outer
83
84bb.outer:		; preds = %cond_false, %entry
85	%b_addr.021.0.ph = phi i32 [ %b, %entry ], [ %tmp10, %cond_false ]		; <i32> [#uses=5]
86	%a_addr.026.0.ph = phi i32 [ %a, %entry ], [ %a_addr.026.0, %cond_false ]		; <i32> [#uses=1]
87	br label %bb
88
89bb:		; preds = %cond_true, %bb.outer
90	%indvar = phi i32 [ 0, %bb.outer ], [ %indvar.next, %cond_true ]		; <i32> [#uses=2]
91	%tmp. = sub i32 0, %b_addr.021.0.ph		; <i32> [#uses=1]
92	%tmp.40 = mul i32 %indvar, %tmp.		; <i32> [#uses=1]
93	%a_addr.026.0 = add i32 %tmp.40, %a_addr.026.0.ph		; <i32> [#uses=6]
94	%tmp3 = icmp sgt i32 %a_addr.026.0, %b_addr.021.0.ph		; <i1> [#uses=1]
95	br i1 %tmp3, label %cond_true, label %cond_false
96
97cond_true:		; preds = %bb
98	%tmp7 = sub i32 %a_addr.026.0, %b_addr.021.0.ph		; <i32> [#uses=2]
99	%tmp1437 = icmp eq i32 %tmp7, %b_addr.021.0.ph		; <i1> [#uses=1]
100	%indvar.next = add i32 %indvar, 1		; <i32> [#uses=1]
101	br i1 %tmp1437, label %bb17, label %bb
102
103cond_false:		; preds = %bb
104	%tmp10 = sub i32 %b_addr.021.0.ph, %a_addr.026.0		; <i32> [#uses=2]
105	%tmp14 = icmp eq i32 %a_addr.026.0, %tmp10		; <i1> [#uses=1]
106	br i1 %tmp14, label %bb17, label %bb.outer
107
108bb17:		; preds = %cond_false, %cond_true, %entry
109	%a_addr.026.1 = phi i32 [ %a, %entry ], [ %tmp7, %cond_true ], [ %a_addr.026.0, %cond_false ]		; <i32> [#uses=1]
110	ret i32 %a_addr.026.1
111}
112
113define i32 @t2_nomerge(i32 %a, i32 %b) nounwind {
114; V01-LABEL: t2_nomerge:
115; V01:       @ %bb.0: @ %entry
116; V01-NEXT:    cmp r0, r1
117; V01-NEXT:    it eq
118; V01-NEXT:    bxeq lr
119; V01-NEXT:  LBB2_1: @ %bb
120; V01-NEXT:    @ =>This Inner Loop Header: Depth=1
121; V01-NEXT:    cmp r0, r1
122; V01-NEXT:    ble LBB2_3
123; V01-NEXT:  @ %bb.2: @ %cond_true
124; V01-NEXT:    @ in Loop: Header=BB2_1 Depth=1
125; V01-NEXT:    subs r0, r0, r1
126; V01-NEXT:    cmp r1, r0
127; V01-NEXT:    bne LBB2_1
128; V01-NEXT:    b LBB2_4
129; V01-NEXT:  LBB2_3: @ %cond_false
130; V01-NEXT:    @ in Loop: Header=BB2_1 Depth=1
131; V01-NEXT:    subs r1, r1, r0
132; V01-NEXT:    cmp r0, #0
133; V01-NEXT:    bne LBB2_1
134; V01-NEXT:  LBB2_4: @ %bb17
135; V01-NEXT:    bx lr
136;
137; V2-LABEL: t2_nomerge:
138; V2:       @ %bb.0: @ %entry
139; V2-NEXT:    cmp r0, r1
140; V2-NEXT:    it eq
141; V2-NEXT:    bxeq lr
142; V2-NEXT:  .LBB2_1: @ %bb
143; V2-NEXT:    @ =>This Inner Loop Header: Depth=1
144; V2-NEXT:    cmp r0, r1
145; V2-NEXT:    ble .LBB2_3
146; V2-NEXT:  @ %bb.2: @ %cond_true
147; V2-NEXT:    @ in Loop: Header=BB2_1 Depth=1
148; V2-NEXT:    subs r0, r0, r1
149; V2-NEXT:    cmp r1, r0
150; V2-NEXT:    bne .LBB2_1
151; V2-NEXT:    b .LBB2_4
152; V2-NEXT:  .LBB2_3: @ %cond_false
153; V2-NEXT:    @ in Loop: Header=BB2_1 Depth=1
154; V2-NEXT:    subs r1, r1, r0
155; V2-NEXT:    cmp r0, #0
156; V2-NEXT:    bne .LBB2_1
157; V2-NEXT:  .LBB2_4: @ %bb17
158; V2-NEXT:    bx lr
159;
160; V3-LABEL: t2_nomerge:
161; V3:       @ %bb.0: @ %entry
162; V3-NEXT:    cmp r0, r1
163; V3-NEXT:    beq .LBB2_4
164; V3-NEXT:    b .LBB2_2
165; V3-NEXT:  .LBB2_1: @ %cond_true
166; V3-NEXT:    @ in Loop: Header=BB2_2 Depth=1
167; V3-NEXT:    subs r0, r0, r1
168; V3-NEXT:    cmp r1, r0
169; V3-NEXT:    it eq
170; V3-NEXT:    bxeq lr
171; V3-NEXT:  .LBB2_2: @ %bb
172; V3-NEXT:    @ =>This Inner Loop Header: Depth=1
173; V3-NEXT:    cmp r0, r1
174; V3-NEXT:    bgt .LBB2_1
175; V3-NEXT:  @ %bb.3: @ %cond_false
176; V3-NEXT:    @ in Loop: Header=BB2_2 Depth=1
177; V3-NEXT:    subs r1, r1, r0
178; V3-NEXT:    cmp r0, #0
179; V3-NEXT:    bne .LBB2_2
180; V3-NEXT:  .LBB2_4: @ %bb17
181; V3-NEXT:    bx lr
182entry:
183	%tmp1434 = icmp eq i32 %a, %b		; <i1> [#uses=1]
184	br i1 %tmp1434, label %bb17, label %bb.outer
185
186bb.outer:		; preds = %cond_false, %entry
187	%b_addr.021.0.ph = phi i32 [ %b, %entry ], [ %tmp10, %cond_false ]		; <i32> [#uses=5]
188	%a_addr.026.0.ph = phi i32 [ %a, %entry ], [ %a_addr.026.0, %cond_false ]		; <i32> [#uses=1]
189	br label %bb
190
191bb:		; preds = %cond_true, %bb.outer
192	%indvar = phi i32 [ 0, %bb.outer ], [ %indvar.next, %cond_true ]		; <i32> [#uses=2]
193	%tmp. = sub i32 0, %b_addr.021.0.ph		; <i32> [#uses=1]
194	%tmp.40 = mul i32 %indvar, %tmp.		; <i32> [#uses=1]
195	%a_addr.026.0 = add i32 %tmp.40, %a_addr.026.0.ph		; <i32> [#uses=6]
196	%tmp3 = icmp sgt i32 %a_addr.026.0, %b_addr.021.0.ph		; <i1> [#uses=1]
197	br i1 %tmp3, label %cond_true, label %cond_false
198
199cond_true:		; preds = %bb
200	%tmp7 = sub i32 %a_addr.026.0, %b_addr.021.0.ph		; <i32> [#uses=2]
201	%tmp1437 = icmp eq i32 %tmp7, %b_addr.021.0.ph		; <i1> [#uses=1]
202	%indvar.next = add i32 %indvar, 1		; <i32> [#uses=1]
203	br i1 %tmp1437, label %bb17, label %bb
204
205cond_false:		; preds = %bb
206	%tmp10 = sub i32 %b_addr.021.0.ph, %a_addr.026.0		; <i32> [#uses=2]
207	%tmp14 = icmp eq i32 %b_addr.021.0.ph, %tmp10		; <i1> [#uses=1]
208	br i1 %tmp14, label %bb17, label %bb.outer
209
210bb17:		; preds = %cond_false, %cond_true, %entry
211	%a_addr.026.1 = phi i32 [ %a, %entry ], [ %tmp7, %cond_true ], [ %a_addr.026.0, %cond_false ]		; <i32> [#uses=1]
212	ret i32 %a_addr.026.1
213}
214
215@x = external global ptr		; <ptr> [#uses=1]
216
217define void @foo(i32 %a) nounwind {
218; V01-LABEL: foo:
219; V01:       @ %bb.0: @ %entry
220; V01-NEXT:    movw r1, :lower16:(L_x$non_lazy_ptr-(LPC3_0+4))
221; V01-NEXT:    movt r1, :upper16:(L_x$non_lazy_ptr-(LPC3_0+4))
222; V01-NEXT:  LPC3_0:
223; V01-NEXT:    add r1, pc
224; V01-NEXT:    ldr r1, [r1]
225; V01-NEXT:    ldr r1, [r1]
226; V01-NEXT:    str r0, [r1]
227; V01-NEXT:    bx lr
228;
229; V23-LABEL: foo:
230; V23:       @ %bb.0: @ %entry
231; V23-NEXT:    movw r1, :lower16:x
232; V23-NEXT:    movt r1, :upper16:x
233; V23-NEXT:    ldr r1, [r1]
234; V23-NEXT:    str r0, [r1]
235; V23-NEXT:    bx lr
236entry:
237	%tmp = load ptr, ptr @x		; <ptr> [#uses=1]
238	store i32 %a, ptr %tmp
239	ret void
240}
241
242define void @t3(i32 %a, i32 %b) nounwind {
243; V01-LABEL: t3:
244; V01:       @ %bb.0: @ %entry
245; V01-NEXT:    cmp r0, #10
246; V01-NEXT:    it le
247; V01-NEXT:    bxle lr
248; V01-NEXT:  LBB4_1: @ %cond_true
249; V01-NEXT:    str lr, [sp, #-4]!
250; V01-NEXT:    mov r0, r1
251; V01-NEXT:    bl _foo
252; V01-NEXT:    ldr lr, [sp], #4
253; V01-NEXT:    bx lr
254;
255; V23-LABEL: t3:
256; V23:       @ %bb.0: @ %entry
257; V23-NEXT:    cmp r0, #10
258; V23-NEXT:    it le
259; V23-NEXT:    bxle lr
260; V23-NEXT:  .LBB4_1: @ %cond_true
261; V23-NEXT:    push {r7, lr}
262; V23-NEXT:    mov r0, r1
263; V23-NEXT:    bl foo
264; V23-NEXT:    pop.w {r7, lr}
265; V23-NEXT:    bx lr
266entry:
267	%tmp1 = icmp sgt i32 %a, 10		; <i1> [#uses=1]
268	br i1 %tmp1, label %cond_true, label %UnifiedReturnBlock
269
270cond_true:		; preds = %entry
271	call void @foo( i32 %b )
272	ret void
273
274UnifiedReturnBlock:		; preds = %entry
275	ret void
276}
277