1 ; RUN: llc < %s -march=aarch64 -mtriple=aarch64-linux-gnu | FileCheck %s
3 ; marked as external to prevent possible optimizations
4 @a = external global i32
5 @b = external global i32
6 @c = external global i32
7 @d = external global i32
9 ; (a > 10 && b == c) || (a >= 10 && b == d)
10 define i32 @combine_gt_ge_10() #0 {
11 ; CHECK-LABEL: combine_gt_ge_10
18 %0 = load i32* @a, align 4
19 %cmp = icmp sgt i32 %0, 10
20 br i1 %cmp, label %land.lhs.true, label %lor.lhs.false
22 land.lhs.true: ; preds = %entry
23 %1 = load i32* @b, align 4
24 %2 = load i32* @c, align 4
25 %cmp1 = icmp eq i32 %1, %2
26 br i1 %cmp1, label %return, label %land.lhs.true3
28 lor.lhs.false: ; preds = %entry
29 %cmp2 = icmp sgt i32 %0, 9
30 br i1 %cmp2, label %land.lhs.true3, label %if.end
32 land.lhs.true3: ; preds = %lor.lhs.false, %land.lhs.true
33 %3 = load i32* @b, align 4
34 %4 = load i32* @d, align 4
35 %cmp4 = icmp eq i32 %3, %4
36 br i1 %cmp4, label %return, label %if.end
38 if.end: ; preds = %land.lhs.true3, %lor.lhs.false
41 return: ; preds = %if.end, %land.lhs.true3, %land.lhs.true
42 %retval.0 = phi i32 [ 0, %if.end ], [ 1, %land.lhs.true3 ], [ 1, %land.lhs.true ]
46 ; (a > 5 && b == c) || (a < 5 && b == d)
47 define i32 @combine_gt_lt_5() #0 {
48 ; CHECK-LABEL: combine_gt_lt_5
55 %0 = load i32* @a, align 4
56 %cmp = icmp sgt i32 %0, 5
57 br i1 %cmp, label %land.lhs.true, label %lor.lhs.false
59 land.lhs.true: ; preds = %entry
60 %1 = load i32* @b, align 4
61 %2 = load i32* @c, align 4
62 %cmp1 = icmp eq i32 %1, %2
63 br i1 %cmp1, label %return, label %if.end
65 lor.lhs.false: ; preds = %entry
66 %cmp2 = icmp slt i32 %0, 5
67 br i1 %cmp2, label %land.lhs.true3, label %if.end
69 land.lhs.true3: ; preds = %lor.lhs.false
70 %3 = load i32* @b, align 4
71 %4 = load i32* @d, align 4
72 %cmp4 = icmp eq i32 %3, %4
73 br i1 %cmp4, label %return, label %if.end
75 if.end: ; preds = %land.lhs.true3, %lor.lhs.false, %land.lhs.true
78 return: ; preds = %if.end, %land.lhs.true3, %land.lhs.true
79 %retval.0 = phi i32 [ 0, %if.end ], [ 1, %land.lhs.true3 ], [ 1, %land.lhs.true ]
83 ; (a < 5 && b == c) || (a <= 5 && b == d)
84 define i32 @combine_lt_ge_5() #0 {
85 ; CHECK-LABEL: combine_lt_ge_5
92 %0 = load i32* @a, align 4
93 %cmp = icmp slt i32 %0, 5
94 br i1 %cmp, label %land.lhs.true, label %lor.lhs.false
96 land.lhs.true: ; preds = %entry
97 %1 = load i32* @b, align 4
98 %2 = load i32* @c, align 4
99 %cmp1 = icmp eq i32 %1, %2
100 br i1 %cmp1, label %return, label %land.lhs.true3
102 lor.lhs.false: ; preds = %entry
103 %cmp2 = icmp slt i32 %0, 6
104 br i1 %cmp2, label %land.lhs.true3, label %if.end
106 land.lhs.true3: ; preds = %lor.lhs.false, %land.lhs.true
107 %3 = load i32* @b, align 4
108 %4 = load i32* @d, align 4
109 %cmp4 = icmp eq i32 %3, %4
110 br i1 %cmp4, label %return, label %if.end
112 if.end: ; preds = %land.lhs.true3, %lor.lhs.false
115 return: ; preds = %if.end, %land.lhs.true3, %land.lhs.true
116 %retval.0 = phi i32 [ 0, %if.end ], [ 1, %land.lhs.true3 ], [ 1, %land.lhs.true ]
120 ; (a < 5 && b == c) || (a > 5 && b == d)
121 define i32 @combine_lt_gt_5() #0 {
122 ; CHECK-LABEL: combine_lt_gt_5
129 %0 = load i32* @a, align 4
130 %cmp = icmp slt i32 %0, 5
131 br i1 %cmp, label %land.lhs.true, label %lor.lhs.false
133 land.lhs.true: ; preds = %entry
134 %1 = load i32* @b, align 4
135 %2 = load i32* @c, align 4
136 %cmp1 = icmp eq i32 %1, %2
137 br i1 %cmp1, label %return, label %if.end
139 lor.lhs.false: ; preds = %entry
140 %cmp2 = icmp sgt i32 %0, 5
141 br i1 %cmp2, label %land.lhs.true3, label %if.end
143 land.lhs.true3: ; preds = %lor.lhs.false
144 %3 = load i32* @b, align 4
145 %4 = load i32* @d, align 4
146 %cmp4 = icmp eq i32 %3, %4
147 br i1 %cmp4, label %return, label %if.end
149 if.end: ; preds = %land.lhs.true3, %lor.lhs.false, %land.lhs.true
152 return: ; preds = %if.end, %land.lhs.true3, %land.lhs.true
153 %retval.0 = phi i32 [ 0, %if.end ], [ 1, %land.lhs.true3 ], [ 1, %land.lhs.true ]
157 ; (a > -5 && b == c) || (a < -5 && b == d)
158 define i32 @combine_gt_lt_n5() #0 {
159 ; CHECK-LABEL: combine_gt_lt_n5
166 %0 = load i32* @a, align 4
167 %cmp = icmp sgt i32 %0, -5
168 br i1 %cmp, label %land.lhs.true, label %lor.lhs.false
170 land.lhs.true: ; preds = %entry
171 %1 = load i32* @b, align 4
172 %2 = load i32* @c, align 4
173 %cmp1 = icmp eq i32 %1, %2
174 br i1 %cmp1, label %return, label %if.end
176 lor.lhs.false: ; preds = %entry
177 %cmp2 = icmp slt i32 %0, -5
178 br i1 %cmp2, label %land.lhs.true3, label %if.end
180 land.lhs.true3: ; preds = %lor.lhs.false
181 %3 = load i32* @b, align 4
182 %4 = load i32* @d, align 4
183 %cmp4 = icmp eq i32 %3, %4
184 br i1 %cmp4, label %return, label %if.end
186 if.end: ; preds = %land.lhs.true3, %lor.lhs.false, %land.lhs.true
189 return: ; preds = %if.end, %land.lhs.true3, %land.lhs.true
190 %retval.0 = phi i32 [ 0, %if.end ], [ 1, %land.lhs.true3 ], [ 1, %land.lhs.true ]
194 ; (a < -5 && b == c) || (a > -5 && b == d)
195 define i32 @combine_lt_gt_n5() #0 {
196 ; CHECK-LABEL: combine_lt_gt_n5
203 %0 = load i32* @a, align 4
204 %cmp = icmp slt i32 %0, -5
205 br i1 %cmp, label %land.lhs.true, label %lor.lhs.false
207 land.lhs.true: ; preds = %entry
208 %1 = load i32* @b, align 4
209 %2 = load i32* @c, align 4
210 %cmp1 = icmp eq i32 %1, %2
211 br i1 %cmp1, label %return, label %if.end
213 lor.lhs.false: ; preds = %entry
214 %cmp2 = icmp sgt i32 %0, -5
215 br i1 %cmp2, label %land.lhs.true3, label %if.end
217 land.lhs.true3: ; preds = %lor.lhs.false
218 %3 = load i32* @b, align 4
219 %4 = load i32* @d, align 4
220 %cmp4 = icmp eq i32 %3, %4
221 br i1 %cmp4, label %return, label %if.end
223 if.end: ; preds = %land.lhs.true3, %lor.lhs.false, %land.lhs.true
226 return: ; preds = %if.end, %land.lhs.true3, %land.lhs.true
227 %retval.0 = phi i32 [ 0, %if.end ], [ 1, %land.lhs.true3 ], [ 1, %land.lhs.true ]
231 %struct.Struct = type { i64, i64 }
233 @glob = internal unnamed_addr global %struct.Struct* null, align 8
235 declare %struct.Struct* @Update(%struct.Struct*) #1
237 ; no checks for this case, it just should be processed without errors
238 define void @combine_non_adjacent_cmp_br(%struct.Struct* nocapture readonly %hdCall) #0 {
240 %size = getelementptr inbounds %struct.Struct* %hdCall, i64 0, i32 0
241 %0 = load i64* %size, align 8
245 %rp.06 = phi i64 [ %0, %entry ], [ %sub, %while.body ]
246 %1 = load i64* inttoptr (i64 24 to i64*), align 8
247 %cmp2 = icmp sgt i64 %1, 0
248 br i1 %cmp2, label %while.body, label %while.end
251 %2 = load %struct.Struct** @glob, align 8
252 %call = tail call %struct.Struct* @Update(%struct.Struct* %2) #2
253 %sub = add nsw i64 %rp.06, -2
254 %cmp = icmp slt i64 %0, %rp.06
255 br i1 %cmp, label %land.rhs, label %while.end
261 ; undefined external to prevent possible optimizations
262 declare void @do_something() #1
264 define i32 @do_nothing_if_resultant_opcodes_would_differ() #0 {
265 ; CHECK-LABEL: do_nothing_if_resultant_opcodes_would_differ
271 %0 = load i32* @a, align 4
272 %cmp4 = icmp slt i32 %0, -1
273 br i1 %cmp4, label %while.body.preheader, label %while.end
275 while.body.preheader: ; preds = %entry
278 while.body: ; preds = %while.body, %while.body.preheader
279 %i.05 = phi i32 [ %inc, %while.body ], [ %0, %while.body.preheader ]
280 tail call void @do_something() #2
281 %inc = add nsw i32 %i.05, 1
282 %cmp = icmp slt i32 %i.05, 0
283 br i1 %cmp, label %while.body, label %while.cond.while.end_crit_edge
285 while.cond.while.end_crit_edge: ; preds = %while.body
286 %.pre = load i32* @a, align 4
289 while.end: ; preds = %while.cond.while.end_crit_edge, %entry
290 %1 = phi i32 [ %.pre, %while.cond.while.end_crit_edge ], [ %0, %entry ]
291 %cmp1 = icmp slt i32 %1, 2
292 br i1 %cmp1, label %land.lhs.true, label %if.end
294 land.lhs.true: ; preds = %while.end
295 %2 = load i32* @b, align 4
296 %3 = load i32* @d, align 4
297 %cmp2 = icmp eq i32 %2, %3
298 br i1 %cmp2, label %return, label %if.end
300 if.end: ; preds = %land.lhs.true, %while.end
303 return: ; preds = %if.end, %land.lhs.true
304 %retval.0 = phi i32 [ 0, %if.end ], [ 123, %land.lhs.true ]
308 define i32 @do_nothing_if_compares_can_not_be_adjusted_to_each_other() #0 {
309 ; CHECK-LABEL: do_nothing_if_compares_can_not_be_adjusted_to_each_other
315 %0 = load i32* @a, align 4
316 %cmp4 = icmp slt i32 %0, 1
317 br i1 %cmp4, label %while.body.preheader, label %while.end
319 while.body.preheader: ; preds = %entry
322 while.body: ; preds = %while.body, %while.body.preheader
323 %i.05 = phi i32 [ %inc, %while.body ], [ %0, %while.body.preheader ]
324 tail call void @do_something() #2
325 %inc = add nsw i32 %i.05, 1
326 %cmp = icmp slt i32 %i.05, 0
327 br i1 %cmp, label %while.body, label %while.end.loopexit
329 while.end.loopexit: ; preds = %while.body
332 while.end: ; preds = %while.end.loopexit, %entry
333 %1 = load i32* @c, align 4
334 %cmp1 = icmp sgt i32 %1, -3
335 br i1 %cmp1, label %land.lhs.true, label %if.end
337 land.lhs.true: ; preds = %while.end
338 %2 = load i32* @b, align 4
339 %3 = load i32* @d, align 4
340 %cmp2 = icmp eq i32 %2, %3
341 br i1 %cmp2, label %return, label %if.end
343 if.end: ; preds = %land.lhs.true, %while.end
346 return: ; preds = %if.end, %land.lhs.true
347 %retval.0 = phi i32 [ 0, %if.end ], [ 123, %land.lhs.true ]