[WinEH] Add some test cases I forgot to add to previous commits
[oota-llvm.git] / test / CodeGen / AArch64 / arm64-ccmp.ll
1 ; RUN: llc < %s -mcpu=cyclone -verify-machineinstrs -aarch64-ccmp -aarch64-stress-ccmp | FileCheck %s
2 target triple = "arm64-apple-ios"
3
4 ; CHECK: single_same
5 ; CHECK: cmp w0, #5
6 ; CHECK-NEXT: ccmp w1, #17, #4, ne
7 ; CHECK-NEXT: b.ne
8 ; CHECK: %if.then
9 ; CHECK: bl _foo
10 ; CHECK: %if.end
11 define i32 @single_same(i32 %a, i32 %b) nounwind ssp {
12 entry:
13   %cmp = icmp eq i32 %a, 5
14   %cmp1 = icmp eq i32 %b, 17
15   %or.cond = or i1 %cmp, %cmp1
16   br i1 %or.cond, label %if.then, label %if.end
17
18 if.then:
19   %call = tail call i32 @foo() nounwind
20   br label %if.end
21
22 if.end:
23   ret i32 7
24 }
25
26 ; Different condition codes for the two compares.
27 ; CHECK: single_different
28 ; CHECK: cmp w0, #6
29 ; CHECK-NEXT: ccmp w1, #17, #0, ge
30 ; CHECK-NEXT: b.eq
31 ; CHECK: %if.then
32 ; CHECK: bl _foo
33 ; CHECK: %if.end
34 define i32 @single_different(i32 %a, i32 %b) nounwind ssp {
35 entry:
36   %cmp = icmp sle i32 %a, 5
37   %cmp1 = icmp ne i32 %b, 17
38   %or.cond = or i1 %cmp, %cmp1
39   br i1 %or.cond, label %if.then, label %if.end
40
41 if.then:
42   %call = tail call i32 @foo() nounwind
43   br label %if.end
44
45 if.end:
46   ret i32 7
47 }
48
49 ; Second block clobbers the flags, can't convert (easily).
50 ; CHECK: single_flagclobber
51 ; CHECK: cmp
52 ; CHECK: b.eq
53 ; CHECK: cmp
54 ; CHECK: b.gt
55 define i32 @single_flagclobber(i32 %a, i32 %b) nounwind ssp {
56 entry:
57   %cmp = icmp eq i32 %a, 5
58   br i1 %cmp, label %if.then, label %lor.lhs.false
59
60 lor.lhs.false:                                    ; preds = %entry
61   %cmp1 = icmp slt i32 %b, 7
62   %mul = shl nsw i32 %b, 1
63   %add = add nsw i32 %b, 1
64   %cond = select i1 %cmp1, i32 %mul, i32 %add
65   %cmp2 = icmp slt i32 %cond, 17
66   br i1 %cmp2, label %if.then, label %if.end
67
68 if.then:                                          ; preds = %lor.lhs.false, %entry
69   %call = tail call i32 @foo() nounwind
70   br label %if.end
71
72 if.end:                                           ; preds = %if.then, %lor.lhs.false
73   ret i32 7
74 }
75
76 ; Second block clobbers the flags and ends with a tbz terminator.
77 ; CHECK: single_flagclobber_tbz
78 ; CHECK: cmp
79 ; CHECK: b.eq
80 ; CHECK: cmp
81 ; CHECK: tbz
82 define i32 @single_flagclobber_tbz(i32 %a, i32 %b) nounwind ssp {
83 entry:
84   %cmp = icmp eq i32 %a, 5
85   br i1 %cmp, label %if.then, label %lor.lhs.false
86
87 lor.lhs.false:                                    ; preds = %entry
88   %cmp1 = icmp slt i32 %b, 7
89   %mul = shl nsw i32 %b, 1
90   %add = add nsw i32 %b, 1
91   %cond = select i1 %cmp1, i32 %mul, i32 %add
92   %and = and i32 %cond, 8
93   %cmp2 = icmp ne i32 %and, 0
94   br i1 %cmp2, label %if.then, label %if.end
95
96 if.then:                                          ; preds = %lor.lhs.false, %entry
97   %call = tail call i32 @foo() nounwind
98   br label %if.end
99
100 if.end:                                           ; preds = %if.then, %lor.lhs.false
101   ret i32 7
102 }
103
104 ; Speculatively execute division by zero.
105 ; The sdiv/udiv instructions do not trap when the divisor is zero, so they are
106 ; safe to speculate.
107 ; CHECK: speculate_division
108 ; CHECK-NOT: cmp
109 ; CHECK: sdiv
110 ; CHECK: cmp
111 ; CHECK-NEXT: ccmp
112 define i32 @speculate_division(i32 %a, i32 %b) nounwind ssp {
113 entry:
114   %cmp = icmp sgt i32 %a, 0
115   br i1 %cmp, label %land.lhs.true, label %if.end
116
117 land.lhs.true:
118   %div = sdiv i32 %b, %a
119   %cmp1 = icmp slt i32 %div, 17
120   br i1 %cmp1, label %if.then, label %if.end
121
122 if.then:
123   %call = tail call i32 @foo() nounwind
124   br label %if.end
125
126 if.end:
127   ret i32 7
128 }
129
130 ; Floating point compare.
131 ; CHECK: single_fcmp
132 ; CHECK: cmp
133 ; CHECK-NOT: b.
134 ; CHECK: fccmp {{.*}}, #8, ge
135 ; CHECK: b.lt
136 define i32 @single_fcmp(i32 %a, float %b) nounwind ssp {
137 entry:
138   %cmp = icmp sgt i32 %a, 0
139   br i1 %cmp, label %land.lhs.true, label %if.end
140
141 land.lhs.true:
142   %conv = sitofp i32 %a to float
143   %div = fdiv float %b, %conv
144   %cmp1 = fcmp oge float %div, 1.700000e+01
145   br i1 %cmp1, label %if.then, label %if.end
146
147 if.then:
148   %call = tail call i32 @foo() nounwind
149   br label %if.end
150
151 if.end:
152   ret i32 7
153 }
154
155 ; Chain multiple compares.
156 ; CHECK: multi_different
157 ; CHECK: cmp
158 ; CHECK: ccmp
159 ; CHECK: ccmp
160 ; CHECK: b.
161 define void @multi_different(i32 %a, i32 %b, i32 %c) nounwind ssp {
162 entry:
163   %cmp = icmp sgt i32 %a, %b
164   br i1 %cmp, label %land.lhs.true, label %if.end
165
166 land.lhs.true:
167   %div = sdiv i32 %b, %a
168   %cmp1 = icmp eq i32 %div, 5
169   %cmp4 = icmp sgt i32 %div, %c
170   %or.cond = and i1 %cmp1, %cmp4
171   br i1 %or.cond, label %if.then, label %if.end
172
173 if.then:
174   %call = tail call i32 @foo() nounwind
175   br label %if.end
176
177 if.end:
178   ret void
179 }
180
181 ; Convert a cbz in the head block.
182 ; CHECK: cbz_head
183 ; CHECK: cmp w0, #0
184 ; CHECK: ccmp
185 define i32 @cbz_head(i32 %a, i32 %b) nounwind ssp {
186 entry:
187   %cmp = icmp eq i32 %a, 0
188   %cmp1 = icmp ne i32 %b, 17
189   %or.cond = or i1 %cmp, %cmp1
190   br i1 %or.cond, label %if.then, label %if.end
191
192 if.then:
193   %call = tail call i32 @foo() nounwind
194   br label %if.end
195
196 if.end:
197   ret i32 7
198 }
199
200 ; Check that the immediate operand is in range. The ccmp instruction encodes a
201 ; smaller range of immediates than subs/adds.
202 ; The ccmp immediates must be in the range 0-31.
203 ; CHECK: immediate_range
204 ; CHECK-NOT: ccmp
205 define i32 @immediate_range(i32 %a, i32 %b) nounwind ssp {
206 entry:
207   %cmp = icmp eq i32 %a, 5
208   %cmp1 = icmp eq i32 %b, 32
209   %or.cond = or i1 %cmp, %cmp1
210   br i1 %or.cond, label %if.then, label %if.end
211
212 if.then:
213   %call = tail call i32 @foo() nounwind
214   br label %if.end
215
216 if.end:
217   ret i32 7
218 }
219
220 ; Convert a cbz in the second block.
221 ; CHECK: cbz_second
222 ; CHECK: cmp w0, #0
223 ; CHECK: ccmp w1, #0, #0, ne
224 ; CHECK: b.eq
225 define i32 @cbz_second(i32 %a, i32 %b) nounwind ssp {
226 entry:
227   %cmp = icmp eq i32 %a, 0
228   %cmp1 = icmp ne i32 %b, 0
229   %or.cond = or i1 %cmp, %cmp1
230   br i1 %or.cond, label %if.then, label %if.end
231
232 if.then:
233   %call = tail call i32 @foo() nounwind
234   br label %if.end
235
236 if.end:
237   ret i32 7
238 }
239
240 ; Convert a cbnz in the second block.
241 ; CHECK: cbnz_second
242 ; CHECK: cmp w0, #0
243 ; CHECK: ccmp w1, #0, #4, ne
244 ; CHECK: b.ne
245 define i32 @cbnz_second(i32 %a, i32 %b) nounwind ssp {
246 entry:
247   %cmp = icmp eq i32 %a, 0
248   %cmp1 = icmp eq i32 %b, 0
249   %or.cond = or i1 %cmp, %cmp1
250   br i1 %or.cond, label %if.then, label %if.end
251
252 if.then:
253   %call = tail call i32 @foo() nounwind
254   br label %if.end
255
256 if.end:
257   ret i32 7
258 }
259 declare i32 @foo()
260
261 %str1 = type { %str2 }
262 %str2 = type { [24 x i8], i8*, i32, %str1*, i32, [4 x i8], %str1*, %str1*, %str1*, %str1*, %str1*, %str1*, %str1*, %str1*, %str1*, i8*, i8, i8*, %str1*, i8* }
263
264 ; Test case distilled from 126.gcc.
265 ; The phi in sw.bb.i.i gets multiple operands for the %entry predecessor.
266 ; CHECK: build_modify_expr
267 define void @build_modify_expr() nounwind ssp {
268 entry:
269   switch i32 undef, label %sw.bb.i.i [
270     i32 69, label %if.end85
271     i32 70, label %if.end85
272     i32 71, label %if.end85
273     i32 72, label %if.end85
274     i32 73, label %if.end85
275     i32 105, label %if.end85
276     i32 106, label %if.end85
277   ]
278
279 if.end85:
280   ret void
281
282 sw.bb.i.i:
283   %ref.tr.i.i = phi %str1* [ %0, %sw.bb.i.i ], [ undef, %entry ]
284   %operands.i.i = getelementptr inbounds %str1, %str1* %ref.tr.i.i, i64 0, i32 0, i32 2
285   %arrayidx.i.i = bitcast i32* %operands.i.i to %str1**
286   %0 = load %str1*, %str1** %arrayidx.i.i, align 8
287   %code1.i.i.phi.trans.insert = getelementptr inbounds %str1, %str1* %0, i64 0, i32 0, i32 0, i64 16
288   br label %sw.bb.i.i
289 }