[NFC][RemoveDIs] Prefer iterators over inst-pointers in InstCombine
[llvm-project.git] / llvm / test / CodeGen / AArch64 / rm_redundant_cmp.ll
blob9e3bb8ce8efc03b0687e61799d68c62a16b8190e
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=aarch64-linux-gnuabi -O2 | FileCheck %s
4 ; The following cases are for i16
6 %struct.s_signed_i16 = type { i16, i16, i16 }
7 %struct.s_unsigned_i16 = type { i16, i16, i16 }
9 @cost_s_i8_i16 = common global %struct.s_signed_i16 zeroinitializer, align 2
10 @cost_u_i16 = common global %struct.s_unsigned_i16 zeroinitializer, align 2
12 define void @test_i16_2cmp_signed_1() {
13 ; CHECK-LABEL: test_i16_2cmp_signed_1:
14 ; CHECK:       // %bb.0: // %entry
15 ; CHECK-NEXT:    adrp x8, :got:cost_s_i8_i16
16 ; CHECK-NEXT:    ldr x8, [x8, :got_lo12:cost_s_i8_i16]
17 ; CHECK-NEXT:    ldrsh w9, [x8, #2]
18 ; CHECK-NEXT:    ldrsh w10, [x8, #4]
19 ; CHECK-NEXT:    cmp w9, w10
20 ; CHECK-NEXT:    b.lt .LBB0_2
21 ; CHECK-NEXT:  // %bb.1: // %if.end8.sink.split
22 ; CHECK-NEXT:    strh w9, [x8]
23 ; CHECK-NEXT:  .LBB0_2: // %if.end8
24 ; CHECK-NEXT:    ret
25 entry:
26   %0 = load i16, ptr getelementptr inbounds (%struct.s_signed_i16, ptr @cost_s_i8_i16, i64 0, i32 1), align 2
27   %1 = load i16, ptr getelementptr inbounds (%struct.s_signed_i16, ptr @cost_s_i8_i16, i64 0, i32 2), align 2
28   %cmp = icmp sgt i16 %0, %1
29   br i1 %cmp, label %if.then, label %if.else
31 if.then:                                          ; preds = %entry
32   store i16 %0, ptr @cost_s_i8_i16, align 2
33   br label %if.end8
35 if.else:                                          ; preds = %entry
36   %cmp5 = icmp eq i16 %0, %1
37   br i1 %cmp5, label %if.then7, label %if.end8
39 if.then7:                                         ; preds = %if.else
40   store i16 %0, ptr @cost_s_i8_i16, align 2
41   br label %if.end8
43 if.end8:                                          ; preds = %if.else, %if.then7, %if.then
44   ret void
47 define void @test_i16_2cmp_signed_2() {
48 ; CHECK-LABEL: test_i16_2cmp_signed_2:
49 ; CHECK:       // %bb.0: // %entry
50 ; CHECK-NEXT:    adrp x8, :got:cost_s_i8_i16
51 ; CHECK-NEXT:    ldr x8, [x8, :got_lo12:cost_s_i8_i16]
52 ; CHECK-NEXT:    ldrsh w9, [x8, #2]
53 ; CHECK-NEXT:    ldrsh w10, [x8, #4]
54 ; CHECK-NEXT:    cmp w9, w10
55 ; CHECK-NEXT:    b.gt .LBB1_2
56 ; CHECK-NEXT:  // %bb.1: // %if.else
57 ; CHECK-NEXT:    mov w9, w10
58 ; CHECK-NEXT:    b.ge .LBB1_3
59 ; CHECK-NEXT:  .LBB1_2: // %if.end8.sink.split
60 ; CHECK-NEXT:    strh w9, [x8]
61 ; CHECK-NEXT:  .LBB1_3: // %if.end8
62 ; CHECK-NEXT:    ret
63 entry:
64   %0 = load i16, ptr getelementptr inbounds (%struct.s_signed_i16, ptr @cost_s_i8_i16, i64 0, i32 1), align 2
65   %1 = load i16, ptr getelementptr inbounds (%struct.s_signed_i16, ptr @cost_s_i8_i16, i64 0, i32 2), align 2
66   %cmp = icmp sgt i16 %0, %1
67   br i1 %cmp, label %if.then, label %if.else
69 if.then:                                          ; preds = %entry
70   store i16 %0, ptr @cost_s_i8_i16, align 2
71   br label %if.end8
73 if.else:                                          ; preds = %entry
74   %cmp5 = icmp slt i16 %0, %1
75   br i1 %cmp5, label %if.then7, label %if.end8
77 if.then7:                                         ; preds = %if.else
78   store i16 %1, ptr @cost_s_i8_i16, align 2
79   br label %if.end8
81 if.end8:                                          ; preds = %if.else, %if.then7, %if.then
82   ret void
85 define void @test_i16_2cmp_unsigned_1() {
86 ; CHECK-LABEL: test_i16_2cmp_unsigned_1:
87 ; CHECK:       // %bb.0: // %entry
88 ; CHECK-NEXT:    adrp x8, :got:cost_u_i16
89 ; CHECK-NEXT:    ldr x8, [x8, :got_lo12:cost_u_i16]
90 ; CHECK-NEXT:    ldrh w9, [x8, #2]
91 ; CHECK-NEXT:    ldrh w10, [x8, #4]
92 ; CHECK-NEXT:    cmp w9, w10
93 ; CHECK-NEXT:    b.lo .LBB2_2
94 ; CHECK-NEXT:  // %bb.1: // %if.end8.sink.split
95 ; CHECK-NEXT:    strh w9, [x8]
96 ; CHECK-NEXT:  .LBB2_2: // %if.end8
97 ; CHECK-NEXT:    ret
98 entry:
99   %0 = load i16, ptr getelementptr inbounds (%struct.s_unsigned_i16, ptr @cost_u_i16, i64 0, i32 1), align 2
100   %1 = load i16, ptr getelementptr inbounds (%struct.s_unsigned_i16, ptr @cost_u_i16, i64 0, i32 2), align 2
101   %cmp = icmp ugt i16 %0, %1
102   br i1 %cmp, label %if.then, label %if.else
104 if.then:                                          ; preds = %entry
105   store i16 %0, ptr @cost_u_i16, align 2
106   br label %if.end8
108 if.else:                                          ; preds = %entry
109   %cmp5 = icmp eq i16 %0, %1
110   br i1 %cmp5, label %if.then7, label %if.end8
112 if.then7:                                         ; preds = %if.else
113   store i16 %0, ptr @cost_u_i16, align 2
114   br label %if.end8
116 if.end8:                                          ; preds = %if.else, %if.then7, %if.then
117   ret void
120 define void @test_i16_2cmp_unsigned_2() {
121 ; CHECK-LABEL: test_i16_2cmp_unsigned_2:
122 ; CHECK:       // %bb.0: // %entry
123 ; CHECK-NEXT:    adrp x8, :got:cost_u_i16
124 ; CHECK-NEXT:    ldr x8, [x8, :got_lo12:cost_u_i16]
125 ; CHECK-NEXT:    ldrh w9, [x8, #2]
126 ; CHECK-NEXT:    ldrh w10, [x8, #4]
127 ; CHECK-NEXT:    cmp w9, w10
128 ; CHECK-NEXT:    b.hi .LBB3_2
129 ; CHECK-NEXT:  // %bb.1: // %if.else
130 ; CHECK-NEXT:    mov w9, w10
131 ; CHECK-NEXT:    b.hs .LBB3_3
132 ; CHECK-NEXT:  .LBB3_2: // %if.end8.sink.split
133 ; CHECK-NEXT:    strh w9, [x8]
134 ; CHECK-NEXT:  .LBB3_3: // %if.end8
135 ; CHECK-NEXT:    ret
136 entry:
137   %0 = load i16, ptr getelementptr inbounds (%struct.s_unsigned_i16, ptr @cost_u_i16, i64 0, i32 1), align 2
138   %1 = load i16, ptr getelementptr inbounds (%struct.s_unsigned_i16, ptr @cost_u_i16, i64 0, i32 2), align 2
139   %cmp = icmp ugt i16 %0, %1
140   br i1 %cmp, label %if.then, label %if.else
142 if.then:                                          ; preds = %entry
143   store i16 %0, ptr @cost_u_i16, align 2
144   br label %if.end8
146 if.else:                                          ; preds = %entry
147   %cmp5 = icmp ult i16 %0, %1
148   br i1 %cmp5, label %if.then7, label %if.end8
150 if.then7:                                         ; preds = %if.else
151   store i16 %1, ptr @cost_u_i16, align 2
152   br label %if.end8
154 if.end8:                                          ; preds = %if.else, %if.then7, %if.then
155   ret void
158 ; The following cases are for i8
160 %struct.s_signed_i8 = type { i8, i8, i8 }
161 %struct.s_unsigned_i8 = type { i8, i8, i8 }
163 @cost_s = common global %struct.s_signed_i8 zeroinitializer, align 2
164 @cost_u_i8 = common global %struct.s_unsigned_i8 zeroinitializer, align 2
167 define void @test_i8_2cmp_signed_1() {
168 ; CHECK-LABEL: test_i8_2cmp_signed_1:
169 ; CHECK:       // %bb.0: // %entry
170 ; CHECK-NEXT:    adrp x8, :got:cost_s
171 ; CHECK-NEXT:    ldr x8, [x8, :got_lo12:cost_s]
172 ; CHECK-NEXT:    ldrsb w9, [x8, #1]
173 ; CHECK-NEXT:    ldrsb w10, [x8, #2]
174 ; CHECK-NEXT:    cmp w9, w10
175 ; CHECK-NEXT:    b.lt .LBB4_2
176 ; CHECK-NEXT:  // %bb.1: // %if.end8.sink.split
177 ; CHECK-NEXT:    strb w9, [x8]
178 ; CHECK-NEXT:  .LBB4_2: // %if.end8
179 ; CHECK-NEXT:    ret
180 entry:
181   %0 = load i8, ptr getelementptr inbounds (%struct.s_signed_i8, ptr @cost_s, i64 0, i32 1), align 2
182   %1 = load i8, ptr getelementptr inbounds (%struct.s_signed_i8, ptr @cost_s, i64 0, i32 2), align 2
183   %cmp = icmp sgt i8 %0, %1
184   br i1 %cmp, label %if.then, label %if.else
186 if.then:                                          ; preds = %entry
187   store i8 %0, ptr @cost_s, align 2
188   br label %if.end8
190 if.else:                                          ; preds = %entry
191   %cmp5 = icmp eq i8 %0, %1
192   br i1 %cmp5, label %if.then7, label %if.end8
194 if.then7:                                         ; preds = %if.else
195   store i8 %0, ptr @cost_s, align 2
196   br label %if.end8
198 if.end8:                                          ; preds = %if.else, %if.then7, %if.then
199   ret void
202 define void @test_i8_2cmp_signed_2() {
203 ; CHECK-LABEL: test_i8_2cmp_signed_2:
204 ; CHECK:       // %bb.0: // %entry
205 ; CHECK-NEXT:    adrp x8, :got:cost_s
206 ; CHECK-NEXT:    ldr x8, [x8, :got_lo12:cost_s]
207 ; CHECK-NEXT:    ldrsb w9, [x8, #1]
208 ; CHECK-NEXT:    ldrsb w10, [x8, #2]
209 ; CHECK-NEXT:    cmp w9, w10
210 ; CHECK-NEXT:    b.gt .LBB5_2
211 ; CHECK-NEXT:  // %bb.1: // %if.else
212 ; CHECK-NEXT:    mov w9, w10
213 ; CHECK-NEXT:    b.ge .LBB5_3
214 ; CHECK-NEXT:  .LBB5_2: // %if.end8.sink.split
215 ; CHECK-NEXT:    strb w9, [x8]
216 ; CHECK-NEXT:  .LBB5_3: // %if.end8
217 ; CHECK-NEXT:    ret
218 entry:
219   %0 = load i8, ptr getelementptr inbounds (%struct.s_signed_i8, ptr @cost_s, i64 0, i32 1), align 2
220   %1 = load i8, ptr getelementptr inbounds (%struct.s_signed_i8, ptr @cost_s, i64 0, i32 2), align 2
221   %cmp = icmp sgt i8 %0, %1
222   br i1 %cmp, label %if.then, label %if.else
224 if.then:                                          ; preds = %entry
225   store i8 %0, ptr @cost_s, align 2
226   br label %if.end8
228 if.else:                                          ; preds = %entry
229   %cmp5 = icmp slt i8 %0, %1
230   br i1 %cmp5, label %if.then7, label %if.end8
232 if.then7:                                         ; preds = %if.else
233   store i8 %1, ptr @cost_s, align 2
234   br label %if.end8
236 if.end8:                                          ; preds = %if.else, %if.then7, %if.then
237   ret void
240 define void @test_i8_2cmp_unsigned_1() {
241 ; CHECK-LABEL: test_i8_2cmp_unsigned_1:
242 ; CHECK:       // %bb.0: // %entry
243 ; CHECK-NEXT:    adrp x8, :got:cost_u_i8
244 ; CHECK-NEXT:    ldr x8, [x8, :got_lo12:cost_u_i8]
245 ; CHECK-NEXT:    ldrb w9, [x8, #1]
246 ; CHECK-NEXT:    ldrb w10, [x8, #2]
247 ; CHECK-NEXT:    cmp w9, w10
248 ; CHECK-NEXT:    b.lo .LBB6_2
249 ; CHECK-NEXT:  // %bb.1: // %if.end8.sink.split
250 ; CHECK-NEXT:    strb w9, [x8]
251 ; CHECK-NEXT:  .LBB6_2: // %if.end8
252 ; CHECK-NEXT:    ret
253 entry:
254   %0 = load i8, ptr getelementptr inbounds (%struct.s_unsigned_i8, ptr @cost_u_i8, i64 0, i32 1), align 2
255   %1 = load i8, ptr getelementptr inbounds (%struct.s_unsigned_i8, ptr @cost_u_i8, i64 0, i32 2), align 2
256   %cmp = icmp ugt i8 %0, %1
257   br i1 %cmp, label %if.then, label %if.else
259 if.then:                                          ; preds = %entry
260   store i8 %0, ptr @cost_u_i8, align 2
261   br label %if.end8
263 if.else:                                          ; preds = %entry
264   %cmp5 = icmp eq i8 %0, %1
265   br i1 %cmp5, label %if.then7, label %if.end8
267 if.then7:                                         ; preds = %if.else
268   store i8 %0, ptr @cost_u_i8, align 2
269   br label %if.end8
271 if.end8:                                          ; preds = %if.else, %if.then7, %if.then
272   ret void
275 define void @test_i8_2cmp_unsigned_2() {
276 ; CHECK-LABEL: test_i8_2cmp_unsigned_2:
277 ; CHECK:       // %bb.0: // %entry
278 ; CHECK-NEXT:    adrp x8, :got:cost_u_i8
279 ; CHECK-NEXT:    ldr x8, [x8, :got_lo12:cost_u_i8]
280 ; CHECK-NEXT:    ldrb w9, [x8, #1]
281 ; CHECK-NEXT:    ldrb w10, [x8, #2]
282 ; CHECK-NEXT:    cmp w9, w10
283 ; CHECK-NEXT:    b.hi .LBB7_2
284 ; CHECK-NEXT:  // %bb.1: // %if.else
285 ; CHECK-NEXT:    mov w9, w10
286 ; CHECK-NEXT:    b.hs .LBB7_3
287 ; CHECK-NEXT:  .LBB7_2: // %if.end8.sink.split
288 ; CHECK-NEXT:    strb w9, [x8]
289 ; CHECK-NEXT:  .LBB7_3: // %if.end8
290 ; CHECK-NEXT:    ret
291 entry:
292   %0 = load i8, ptr getelementptr inbounds (%struct.s_unsigned_i8, ptr @cost_u_i8, i64 0, i32 1), align 2
293   %1 = load i8, ptr getelementptr inbounds (%struct.s_unsigned_i8, ptr @cost_u_i8, i64 0, i32 2), align 2
294   %cmp = icmp ugt i8 %0, %1
295   br i1 %cmp, label %if.then, label %if.else
297 if.then:                                          ; preds = %entry
298   store i8 %0, ptr @cost_u_i8, align 2
299   br label %if.end8
301 if.else:                                          ; preds = %entry
302   %cmp5 = icmp ult i8 %0, %1
303   br i1 %cmp5, label %if.then7, label %if.end8
305 if.then7:                                         ; preds = %if.else
306   store i8 %1, ptr @cost_u_i8, align 2
307   br label %if.end8
309 if.end8:                                          ; preds = %if.else, %if.then7, %if.then
310   ret void
313 ; Make sure the case below won't crash.
315 ; The optimization of ZERO_EXTEND and SIGN_EXTEND in type legalization stage can't assert
316 ; the operand of a set_cc is always a TRUNCATE.
318 define i1 @foo(float %inl, float %inr) {
319 ; CHECK-LABEL: foo:
320 ; CHECK:       // %bb.0:
321 ; CHECK-NEXT:    fcvtzs w8, s0
322 ; CHECK-NEXT:    fcvtzs w9, s1
323 ; CHECK-NEXT:    cmp w8, w9
324 ; CHECK-NEXT:    cset w0, eq
325 ; CHECK-NEXT:    ret
326   %lval = fptosi float %inl to i8
327   %rval = fptosi float %inr to i8
328   %sum = icmp eq i8 %lval, %rval
329   ret i1 %sum