[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / CodeGen / Thumb2 / LowOverheadLoops / no-dec-le-simple.ll
blob78ddb35e756e3a5778ed85689df77205c677f128
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=thumbv8.1m.main %s -o - | FileCheck %s
4 define void @cbz_exit(i32* %in, i32* %res) {
5 ; CHECK-LABEL: cbz_exit:
6 ; CHECK:       @ %bb.0: @ %entry
7 ; CHECK-NEXT:    subs r2, r0, #4
8 ; CHECK-NEXT:    mov.w r0, #-1
9 ; CHECK-NEXT:  .LBB0_1: @ %loop
10 ; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
11 ; CHECK-NEXT:    ldr r3, [r2, #4]!
12 ; CHECK-NEXT:    adds r0, #1
13 ; CHECK-NEXT:    cbz r3, .LBB0_2
14 ; CHECK-NEXT:    le .LBB0_1
15 ; CHECK-NEXT:  .LBB0_2: @ %exit
16 ; CHECK-NEXT:    str r0, [r1]
17 ; CHECK-NEXT:    bx lr
18 entry:
19   br label %loop
21 loop:
22   %offset = phi i32 [ 0, %entry ], [ %next, %loop ]
23   %ptr = getelementptr i32, i32* %in, i32 %offset
24   %val = load i32, i32* %ptr
25   %next = add i32 %offset, 1
26   %cmp = icmp eq i32 %val, 0
27   br i1 %cmp, label %exit, label %loop
29 exit:
30   store i32 %offset, i32* %res
31   ret void
34 define void @cbnz_exit(i32* %in, i32* %res) {
35 ; CHECK-LABEL: cbnz_exit:
36 ; CHECK:       @ %bb.0: @ %entry
37 ; CHECK-NEXT:    subs r2, r0, #4
38 ; CHECK-NEXT:    mov.w r0, #-1
39 ; CHECK-NEXT:  .LBB1_1: @ %loop
40 ; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
41 ; CHECK-NEXT:    ldr r3, [r2, #4]!
42 ; CHECK-NEXT:    adds r0, #1
43 ; CHECK-NEXT:    cbnz r3, .LBB1_2
44 ; CHECK-NEXT:    le .LBB1_1
45 ; CHECK-NEXT:  .LBB1_2: @ %exit
46 ; CHECK-NEXT:    str r0, [r1]
47 ; CHECK-NEXT:    bx lr
48 entry:
49   br label %loop
51 loop:
52   %offset = phi i32 [ 0, %entry ], [ %next, %loop ]
53   %ptr = getelementptr i32, i32* %in, i32 %offset
54   %val = load i32, i32* %ptr
55   %next = add i32 %offset, 1
56   %cmp = icmp ne i32 %val, 0
57   br i1 %cmp, label %exit, label %loop
59 exit:
60   store i32 %offset, i32* %res
61   ret void
64 define void @cbnz_exit_too_large(i32* %in, i32* %res) {
65 ; CHECK-LABEL: cbnz_exit_too_large:
66 ; CHECK:       @ %bb.0: @ %entry
67 ; CHECK-NEXT:    subs r2, r0, #4
68 ; CHECK-NEXT:    mov.w r0, #-1
69 ; CHECK-NEXT:  .LBB2_1: @ %loop
70 ; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
71 ; CHECK-NEXT:    ldr r12, [r2, #4]!
72 ; CHECK-NEXT:    .zero 4090
73 ; CHECK-NEXT:    adds r0, #1
74 ; CHECK-NEXT:    cmp.w r12, #0
75 ; CHECK-NEXT:    beq.w .LBB2_1
76 ; CHECK-NEXT:  @ %bb.2: @ %exit
77 ; CHECK-NEXT:    str r0, [r1]
78 ; CHECK-NEXT:    bx lr
79 entry:
80   br label %loop
82 loop:
83   %offset = phi i32 [ 0, %entry ], [ %next, %loop ]
84   %ptr = getelementptr i32, i32* %in, i32 %offset
85   %val = load i32, i32* %ptr
86   %next = add i32 %offset, 1
87   %cmp = icmp ne i32 %val, 0
88   %size = call i32 @llvm.arm.space(i32 4090, i32 undef)
89   br i1 %cmp, label %exit, label %loop
91 exit:
92   store i32 %offset, i32* %res
93   ret void
96 define void @cbz_exit_minsize(i32* %in, i32* %res) #0 {
97 ; CHECK-LABEL: cbz_exit_minsize:
98 ; CHECK:       @ %bb.0: @ %entry
99 ; CHECK-NEXT:    movs r2, #0
100 ; CHECK-NEXT:  .LBB3_1: @ %loop
101 ; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
102 ; CHECK-NEXT:    ldr.w r3, [r0, r2, lsl #2]
103 ; CHECK-NEXT:    adds r2, #1
104 ; CHECK-NEXT:    cmp r3, #0
105 ; CHECK-NEXT:    bne .LBB3_1
106 ; CHECK-NEXT:  @ %bb.2: @ %exit
107 ; CHECK-NEXT:    subs r0, r2, #1
108 ; CHECK-NEXT:    str r0, [r1]
109 ; CHECK-NEXT:    bx lr
110 entry:
111   br label %loop
113 loop:
114   %offset = phi i32 [ 0, %entry ], [ %next, %loop ]
115   %ptr = getelementptr i32, i32* %in, i32 %offset
116   %val = load i32, i32* %ptr
117   %next = add i32 %offset, 1
118   %cmp = icmp eq i32 %val, 0
119   br i1 %cmp, label %exit, label %loop
121 exit:
122   store i32 %offset, i32* %res
123   ret void
126 define void @cbnz_exit_minsize(i32* %in, i32* %res) #0 {
127 ; CHECK-LABEL: cbnz_exit_minsize:
128 ; CHECK:       @ %bb.0: @ %entry
129 ; CHECK-NEXT:    movs r2, #0
130 ; CHECK-NEXT:  .LBB4_1: @ %loop
131 ; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
132 ; CHECK-NEXT:    ldr.w r3, [r0, r2, lsl #2]
133 ; CHECK-NEXT:    adds r2, #1
134 ; CHECK-NEXT:    cmp r3, #0
135 ; CHECK-NEXT:    beq .LBB4_1
136 ; CHECK-NEXT:  @ %bb.2: @ %exit
137 ; CHECK-NEXT:    subs r0, r2, #1
138 ; CHECK-NEXT:    str r0, [r1]
139 ; CHECK-NEXT:    bx lr
140 entry:
141   br label %loop
143 loop:
144   %offset = phi i32 [ 0, %entry ], [ %next, %loop ]
145   %ptr = getelementptr i32, i32* %in, i32 %offset
146   %val = load i32, i32* %ptr
147   %next = add i32 %offset, 1
148   %cmp = icmp ne i32 %val, 0
149   br i1 %cmp, label %exit, label %loop
151 exit:
152   store i32 %offset, i32* %res
153   ret void
156 attributes #0 = { minsize optsize }
158 declare i32 @llvm.arm.space(i32 immarg, i32);