xref: /llvm-project/llvm/test/CodeGen/ARM/branch-on-zero.ll (revision bed1c7f061aa12417aa081e334afdba45767b938)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple thumbv6m-none-eabi -o - %s | FileCheck %s --check-prefix=CHECK-V6M
3; RUN: llc -mtriple thumbv7m-none-eabi -o - %s | FileCheck %s --check-prefix=CHECK-V7M
4; RUN: llc -mtriple thumbv8.1m.main-none-eabi -mattr=+mve,+lob -o - %s | FileCheck %s --check-prefix=CHECK-V81M
5; RUN: llc -mtriple armv7a-none-eabi -o - %s | FileCheck %s --check-prefix=CHECK-V7A
6
7define i32 @test_lshr(ptr nocapture %x, ptr nocapture readonly %y, i32 %n) {
8; CHECK-V6M-LABEL: test_lshr:
9; CHECK-V6M:       @ %bb.0: @ %entry
10; CHECK-V6M-NEXT:    lsrs r2, r2, #2
11; CHECK-V6M-NEXT:    beq .LBB0_2
12; CHECK-V6M-NEXT:  .LBB0_1: @ %while.body
13; CHECK-V6M-NEXT:    @ =>This Inner Loop Header: Depth=1
14; CHECK-V6M-NEXT:    ldm r1!, {r3}
15; CHECK-V6M-NEXT:    lsls r3, r3, #1
16; CHECK-V6M-NEXT:    stm r0!, {r3}
17; CHECK-V6M-NEXT:    subs r2, r2, #1
18; CHECK-V6M-NEXT:    bne .LBB0_1
19; CHECK-V6M-NEXT:  .LBB0_2: @ %while.end
20; CHECK-V6M-NEXT:    movs r0, #0
21; CHECK-V6M-NEXT:    bx lr
22;
23; CHECK-V7M-LABEL: test_lshr:
24; CHECK-V7M:       @ %bb.0: @ %entry
25; CHECK-V7M-NEXT:    lsrs r2, r2, #2
26; CHECK-V7M-NEXT:    beq .LBB0_3
27; CHECK-V7M-NEXT:  @ %bb.1: @ %while.body.preheader
28; CHECK-V7M-NEXT:    subs r1, #4
29; CHECK-V7M-NEXT:    subs r0, #4
30; CHECK-V7M-NEXT:  .LBB0_2: @ %while.body
31; CHECK-V7M-NEXT:    @ =>This Inner Loop Header: Depth=1
32; CHECK-V7M-NEXT:    ldr r3, [r1, #4]!
33; CHECK-V7M-NEXT:    subs r2, #1
34; CHECK-V7M-NEXT:    lsl.w r3, r3, #1
35; CHECK-V7M-NEXT:    str r3, [r0, #4]!
36; CHECK-V7M-NEXT:    bne .LBB0_2
37; CHECK-V7M-NEXT:  .LBB0_3: @ %while.end
38; CHECK-V7M-NEXT:    movs r0, #0
39; CHECK-V7M-NEXT:    bx lr
40;
41; CHECK-V81M-LABEL: test_lshr:
42; CHECK-V81M:       @ %bb.0: @ %entry
43; CHECK-V81M-NEXT:    .save {r7, lr}
44; CHECK-V81M-NEXT:    push {r7, lr}
45; CHECK-V81M-NEXT:    lsrs r2, r2, #2
46; CHECK-V81M-NEXT:    wls lr, r2, .LBB0_2
47; CHECK-V81M-NEXT:  .LBB0_1: @ %while.body
48; CHECK-V81M-NEXT:    @ =>This Inner Loop Header: Depth=1
49; CHECK-V81M-NEXT:    ldr r2, [r1], #4
50; CHECK-V81M-NEXT:    lsls r2, r2, #1
51; CHECK-V81M-NEXT:    str r2, [r0], #4
52; CHECK-V81M-NEXT:    le lr, .LBB0_1
53; CHECK-V81M-NEXT:  .LBB0_2: @ %while.end
54; CHECK-V81M-NEXT:    movs r0, #0
55; CHECK-V81M-NEXT:    pop {r7, pc}
56;
57; CHECK-V7A-LABEL: test_lshr:
58; CHECK-V7A:       @ %bb.0: @ %entry
59; CHECK-V7A-NEXT:    lsrs r2, r2, #2
60; CHECK-V7A-NEXT:    beq .LBB0_2
61; CHECK-V7A-NEXT:  .LBB0_1: @ %while.body
62; CHECK-V7A-NEXT:    @ =>This Inner Loop Header: Depth=1
63; CHECK-V7A-NEXT:    ldr r3, [r1], #4
64; CHECK-V7A-NEXT:    subs r2, r2, #1
65; CHECK-V7A-NEXT:    lsl r3, r3, #1
66; CHECK-V7A-NEXT:    str r3, [r0], #4
67; CHECK-V7A-NEXT:    bne .LBB0_1
68; CHECK-V7A-NEXT:  .LBB0_2: @ %while.end
69; CHECK-V7A-NEXT:    mov r0, #0
70; CHECK-V7A-NEXT:    bx lr
71entry:
72  %shr = lshr i32 %n, 2
73  %tobool.not4 = icmp eq i32 %shr, 0
74  br i1 %tobool.not4, label %while.end, label %while.body
75
76while.body:                                       ; preds = %entry, %while.body
77  %c.07 = phi i32 [ %dec, %while.body ], [ %shr, %entry ]
78  %x.addr.06 = phi ptr [ %incdec.ptr1, %while.body ], [ %x, %entry ]
79  %y.addr.05 = phi ptr [ %incdec.ptr, %while.body ], [ %y, %entry ]
80  %incdec.ptr = getelementptr inbounds i32, ptr %y.addr.05, i32 1
81  %0 = load i32, ptr %y.addr.05, align 4
82  %mul = shl nsw i32 %0, 1
83  %incdec.ptr1 = getelementptr inbounds i32, ptr %x.addr.06, i32 1
84  store i32 %mul, ptr %x.addr.06, align 4
85  %dec = add nsw i32 %c.07, -1
86  %tobool.not = icmp eq i32 %dec, 0
87  br i1 %tobool.not, label %while.end, label %while.body
88
89while.end:                                        ; preds = %while.body, %entry
90  ret i32 0
91}
92
93define i32 @test_lshr2(ptr nocapture %x, ptr nocapture readonly %y, i32 %n) {
94; CHECK-V6M-LABEL: test_lshr2:
95; CHECK-V6M:       @ %bb.0: @ %entry
96; CHECK-V6M-NEXT:    lsrs r2, r2, #2
97; CHECK-V6M-NEXT:    beq .LBB1_2
98; CHECK-V6M-NEXT:  .LBB1_1: @ %while.body
99; CHECK-V6M-NEXT:    @ =>This Inner Loop Header: Depth=1
100; CHECK-V6M-NEXT:    ldm r1!, {r3}
101; CHECK-V6M-NEXT:    lsls r3, r3, #1
102; CHECK-V6M-NEXT:    stm r0!, {r3}
103; CHECK-V6M-NEXT:    subs r2, r2, #1
104; CHECK-V6M-NEXT:    bne .LBB1_1
105; CHECK-V6M-NEXT:  .LBB1_2: @ %while.end
106; CHECK-V6M-NEXT:    movs r0, #0
107; CHECK-V6M-NEXT:    bx lr
108;
109; CHECK-V7M-LABEL: test_lshr2:
110; CHECK-V7M:       @ %bb.0: @ %entry
111; CHECK-V7M-NEXT:    lsrs r2, r2, #2
112; CHECK-V7M-NEXT:    beq .LBB1_3
113; CHECK-V7M-NEXT:  @ %bb.1: @ %while.body.preheader
114; CHECK-V7M-NEXT:    subs r1, #4
115; CHECK-V7M-NEXT:    subs r0, #4
116; CHECK-V7M-NEXT:  .LBB1_2: @ %while.body
117; CHECK-V7M-NEXT:    @ =>This Inner Loop Header: Depth=1
118; CHECK-V7M-NEXT:    ldr r3, [r1, #4]!
119; CHECK-V7M-NEXT:    subs r2, #1
120; CHECK-V7M-NEXT:    lsl.w r3, r3, #1
121; CHECK-V7M-NEXT:    str r3, [r0, #4]!
122; CHECK-V7M-NEXT:    bne .LBB1_2
123; CHECK-V7M-NEXT:  .LBB1_3: @ %while.end
124; CHECK-V7M-NEXT:    movs r0, #0
125; CHECK-V7M-NEXT:    bx lr
126;
127; CHECK-V81M-LABEL: test_lshr2:
128; CHECK-V81M:       @ %bb.0: @ %entry
129; CHECK-V81M-NEXT:    .save {r7, lr}
130; CHECK-V81M-NEXT:    push {r7, lr}
131; CHECK-V81M-NEXT:    lsrs r2, r2, #2
132; CHECK-V81M-NEXT:    wls lr, r2, .LBB1_2
133; CHECK-V81M-NEXT:  .LBB1_1: @ %while.body
134; CHECK-V81M-NEXT:    @ =>This Inner Loop Header: Depth=1
135; CHECK-V81M-NEXT:    ldr r2, [r1], #4
136; CHECK-V81M-NEXT:    lsls r2, r2, #1
137; CHECK-V81M-NEXT:    str r2, [r0], #4
138; CHECK-V81M-NEXT:    le lr, .LBB1_1
139; CHECK-V81M-NEXT:  .LBB1_2: @ %while.end
140; CHECK-V81M-NEXT:    movs r0, #0
141; CHECK-V81M-NEXT:    pop {r7, pc}
142;
143; CHECK-V7A-LABEL: test_lshr2:
144; CHECK-V7A:       @ %bb.0: @ %entry
145; CHECK-V7A-NEXT:    lsrs r2, r2, #2
146; CHECK-V7A-NEXT:    beq .LBB1_2
147; CHECK-V7A-NEXT:  .LBB1_1: @ %while.body
148; CHECK-V7A-NEXT:    @ =>This Inner Loop Header: Depth=1
149; CHECK-V7A-NEXT:    ldr r3, [r1], #4
150; CHECK-V7A-NEXT:    subs r2, r2, #1
151; CHECK-V7A-NEXT:    lsl r3, r3, #1
152; CHECK-V7A-NEXT:    str r3, [r0], #4
153; CHECK-V7A-NEXT:    bne .LBB1_1
154; CHECK-V7A-NEXT:  .LBB1_2: @ %while.end
155; CHECK-V7A-NEXT:    mov r0, #0
156; CHECK-V7A-NEXT:    bx lr
157entry:
158  %tobool.not4 = icmp ult i32 %n, 4
159  br i1 %tobool.not4, label %while.end, label %while.body.preheader
160
161while.body.preheader:                             ; preds = %entry
162  %shr = lshr i32 %n, 2
163  br label %while.body
164
165while.body:                                       ; preds = %while.body.preheader, %while.body
166  %c.07 = phi i32 [ %dec, %while.body ], [ %shr, %while.body.preheader ]
167  %x.addr.06 = phi ptr [ %incdec.ptr1, %while.body ], [ %x, %while.body.preheader ]
168  %y.addr.05 = phi ptr [ %incdec.ptr, %while.body ], [ %y, %while.body.preheader ]
169  %incdec.ptr = getelementptr inbounds i32, ptr %y.addr.05, i32 1
170  %0 = load i32, ptr %y.addr.05, align 4
171  %mul = shl nsw i32 %0, 1
172  %incdec.ptr1 = getelementptr inbounds i32, ptr %x.addr.06, i32 1
173  store i32 %mul, ptr %x.addr.06, align 4
174  %dec = add nsw i32 %c.07, -1
175  %tobool.not = icmp eq i32 %dec, 0
176  br i1 %tobool.not, label %while.end, label %while.body
177
178while.end:                                        ; preds = %while.body, %entry
179  ret i32 0
180}
181
182