llvm.org GIT mirror llvm / ae4d462
UpdateTestChecks: arm64-eabi handlind Summary: Was looking into supporting `(srl (shl x, c1), c2)` with c1 != c2 in dagcombiner, this test changes, but makes `update_llc_test_checks.py` unhappy Reviewers: RKSimon Reviewed By: RKSimon Subscribers: javed.absar, kristof.beyls, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D62097 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@361100 91177308-0d34-0410-b5e6-96231b3b80d8 Roman Lebedev 1 year, 6 months ago
2 changed file(s) with 546 addition(s) and 172 deletion(s). Raw diff Collapse all Expand all
0 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
1 ; RUN: opt -codegenprepare -mtriple=arm64-apple=ios -S -o - %s | FileCheck --check-prefix=OPT %s
1 ; RUN: llc < %s -mtriple=arm64-eabi | FileCheck %s
2 ; RUN: llc < %s -mtriple=arm64-eabi | FileCheck --check-prefix=LLC %s
3
24 %struct.X = type { i8, i8, [2 x i8] }
35 %struct.Y = type { i32, i8 }
46 %struct.Z = type { i8, i8, [2 x i8], i16 }
57 %struct.A = type { i64, i8 }
68
79 define void @foo(%struct.X* nocapture %x, %struct.Y* nocapture %y) nounwind optsize ssp {
8 ; CHECK-LABEL: foo:
9 ; CHECK: ubfx
10 ; CHECK-NOT: and
11 ; CHECK: ret
12
10 ; LLC-LABEL: foo:
11 ; LLC: // %bb.0:
12 ; LLC-NEXT: ldr w8, [x0]
13 ; LLC-NEXT: ubfx w8, w8, #3, #1
14 ; LLC-NEXT: strb w8, [x1, #4]
15 ; LLC-NEXT: ret
16 ; OPT-LABEL: @foo(
17 ; OPT-NEXT: [[TMP:%.*]] = bitcast %struct.X* [[X:%.*]] to i32*
18 ; OPT-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 4
19 ; OPT-NEXT: [[B:%.*]] = getelementptr inbounds [[STRUCT_Y:%.*]], %struct.Y* [[Y:%.*]], i64 0, i32 1
20 ; OPT-NEXT: [[BF_CLEAR:%.*]] = lshr i32 [[TMP1]], 3
21 ; OPT-NEXT: [[BF_CLEAR_LOBIT:%.*]] = and i32 [[BF_CLEAR]], 1
22 ; OPT-NEXT: [[FROMBOOL:%.*]] = trunc i32 [[BF_CLEAR_LOBIT]] to i8
23 ; OPT-NEXT: store i8 [[FROMBOOL]], i8* [[B]], align 1
24 ; OPT-NEXT: ret void
25 ;
1326 %tmp = bitcast %struct.X* %x to i32*
1427 %tmp1 = load i32, i32* %tmp, align 4
1528 %b = getelementptr inbounds %struct.Y, %struct.Y* %y, i64 0, i32 1
2134 }
2235
2336 define i32 @baz(i64 %cav1.coerce) nounwind {
24 ; CHECK-LABEL: baz:
25 ; CHECK: sbfx w0, w0, #0, #4
37 ; LLC-LABEL: baz:
38 ; LLC: // %bb.0:
39 ; LLC-NEXT: sbfx w0, w0, #0, #4
40 ; LLC-NEXT: ret
41 ; OPT-LABEL: @baz(
42 ; OPT-NEXT: [[TMP:%.*]] = trunc i64 [[CAV1_COERCE:%.*]] to i32
43 ; OPT-NEXT: [[TMP1:%.*]] = shl i32 [[TMP]], 28
44 ; OPT-NEXT: [[BF_VAL_SEXT:%.*]] = ashr exact i32 [[TMP1]], 28
45 ; OPT-NEXT: ret i32 [[BF_VAL_SEXT]]
46 ;
2647 %tmp = trunc i64 %cav1.coerce to i32
2748 %tmp1 = shl i32 %tmp, 28
2849 %bf.val.sext = ashr exact i32 %tmp1, 28
3051 }
3152
3253 define i32 @bar(i64 %cav1.coerce) nounwind {
33 ; CHECK-LABEL: bar:
34 ; CHECK: sbfx w0, w0, #4, #6
54 ; LLC-LABEL: bar:
55 ; LLC: // %bb.0:
56 ; LLC-NEXT: sbfx w0, w0, #4, #6
57 ; LLC-NEXT: ret
58 ; OPT-LABEL: @bar(
59 ; OPT-NEXT: [[TMP:%.*]] = trunc i64 [[CAV1_COERCE:%.*]] to i32
60 ; OPT-NEXT: [[CAV1_SROA_0_1_INSERT:%.*]] = shl i32 [[TMP]], 22
61 ; OPT-NEXT: [[TMP1:%.*]] = ashr i32 [[CAV1_SROA_0_1_INSERT]], 26
62 ; OPT-NEXT: ret i32 [[TMP1]]
63 ;
3564 %tmp = trunc i64 %cav1.coerce to i32
3665 %cav1.sroa.0.1.insert = shl i32 %tmp, 22
3766 %tmp1 = ashr i32 %cav1.sroa.0.1.insert, 26
3968 }
4069
4170 define void @fct1(%struct.Z* nocapture %x, %struct.A* nocapture %y) nounwind optsize ssp {
42 ; CHECK-LABEL: fct1:
43 ; CHECK: ubfx x{{[0-9]+}}, x{{[0-9]+}}
44 ; CHECK-NOT: and
45 ; CHECK: ret
46
71 ; LLC-LABEL: fct1:
72 ; LLC: // %bb.0:
73 ; LLC-NEXT: ldr x8, [x0]
74 ; LLC-NEXT: ubfx x8, x8, #3, #1
75 ; LLC-NEXT: str x8, [x1]
76 ; LLC-NEXT: ret
77 ; OPT-LABEL: @fct1(
78 ; OPT-NEXT: [[TMP:%.*]] = bitcast %struct.Z* [[X:%.*]] to i64*
79 ; OPT-NEXT: [[TMP1:%.*]] = load i64, i64* [[TMP]], align 4
80 ; OPT-NEXT: [[B1:%.*]] = bitcast %struct.A* [[Y:%.*]] to i64*
81 ; OPT-NEXT: [[BF_CLEAR:%.*]] = lshr i64 [[TMP1]], 3
82 ; OPT-NEXT: [[BF_CLEAR_LOBIT:%.*]] = and i64 [[BF_CLEAR]], 1
83 ; OPT-NEXT: store i64 [[BF_CLEAR_LOBIT]], i64* [[B1]], align 8
84 ; OPT-NEXT: ret void
85 ;
4786 %tmp = bitcast %struct.Z* %x to i64*
4887 %tmp1 = load i64, i64* %tmp, align 4
4988 %b = getelementptr inbounds %struct.A, %struct.A* %y, i64 0, i32 0
5493 }
5594
5695 define i64 @fct2(i64 %cav1.coerce) nounwind {
57 ; CHECK-LABEL: fct2:
58 ; CHECK: sbfx x0, x0, #0, #36
96 ; LLC-LABEL: fct2:
97 ; LLC: // %bb.0:
98 ; LLC-NEXT: sbfx x0, x0, #0, #36
99 ; LLC-NEXT: ret
100 ; OPT-LABEL: @fct2(
101 ; OPT-NEXT: [[TMP:%.*]] = shl i64 [[CAV1_COERCE:%.*]], 28
102 ; OPT-NEXT: [[BF_VAL_SEXT:%.*]] = ashr exact i64 [[TMP]], 28
103 ; OPT-NEXT: ret i64 [[BF_VAL_SEXT]]
104 ;
59105 %tmp = shl i64 %cav1.coerce, 28
60106 %bf.val.sext = ashr exact i64 %tmp, 28
61107 ret i64 %bf.val.sext
62108 }
63109
64110 define i64 @fct3(i64 %cav1.coerce) nounwind {
65 ; CHECK-LABEL: fct3:
66 ; CHECK: sbfx x0, x0, #4, #38
111 ; LLC-LABEL: fct3:
112 ; LLC: // %bb.0:
113 ; LLC-NEXT: sbfx x0, x0, #4, #38
114 ; LLC-NEXT: ret
115 ; OPT-LABEL: @fct3(
116 ; OPT-NEXT: [[CAV1_SROA_0_1_INSERT:%.*]] = shl i64 [[CAV1_COERCE:%.*]], 22
117 ; OPT-NEXT: [[TMP1:%.*]] = ashr i64 [[CAV1_SROA_0_1_INSERT]], 26
118 ; OPT-NEXT: ret i64 [[TMP1]]
119 ;
67120 %cav1.sroa.0.1.insert = shl i64 %cav1.coerce, 22
68121 %tmp1 = ashr i64 %cav1.sroa.0.1.insert, 26
69122 ret i64 %tmp1
70123 }
71124
72125 define void @fct4(i64* nocapture %y, i64 %x) nounwind optsize inlinehint ssp {
73 entry:
74 ; CHECK-LABEL: fct4:
75 ; CHECK: ldr [[REG1:x[0-9]+]],
76 ; CHECK-NEXT: bfxil [[REG1]], x1, #16, #24
77 ; CHECK-NEXT: str [[REG1]],
78 ; CHECK-NEXT: ret
126 ; LLC-LABEL: fct4:
127 ; LLC: // %bb.0: // %entry
128 ; LLC-NEXT: ldr x8, [x0]
129 ; LLC-NEXT: bfxil x8, x1, #16, #24
130 ; LLC-NEXT: str x8, [x0]
131 ; LLC-NEXT: ret
132 ; OPT-LABEL: @fct4(
133 ; OPT-NEXT: entry:
134 ; OPT-NEXT: [[TMP0:%.*]] = load i64, i64* [[Y:%.*]], align 8
135 ; OPT-NEXT: [[AND:%.*]] = and i64 [[TMP0]], -16777216
136 ; OPT-NEXT: [[SHR:%.*]] = lshr i64 [[X:%.*]], 16
137 ; OPT-NEXT: [[AND1:%.*]] = and i64 [[SHR]], 16777215
138 ; OPT-NEXT: [[OR:%.*]] = or i64 [[AND]], [[AND1]]
139 ; OPT-NEXT: store i64 [[OR]], i64* [[Y]], align 8
140 ; OPT-NEXT: ret void
141 ;
142 entry:
79143 %0 = load i64, i64* %y, align 8
80144 %and = and i64 %0, -16777216
81145 %shr = lshr i64 %x, 16
86150 }
87151
88152 define void @fct5(i32* nocapture %y, i32 %x) nounwind optsize inlinehint ssp {
89 entry:
90 ; CHECK-LABEL: fct5:
91 ; CHECK: ldr [[REG1:w[0-9]+]],
92 ; CHECK-NEXT: bfxil [[REG1]], w1, #16, #3
93 ; CHECK-NEXT: str [[REG1]],
94 ; CHECK-NEXT: ret
153 ; LLC-LABEL: fct5:
154 ; LLC: // %bb.0: // %entry
155 ; LLC-NEXT: ldr w8, [x0]
156 ; LLC-NEXT: bfxil w8, w1, #16, #3
157 ; LLC-NEXT: str w8, [x0]
158 ; LLC-NEXT: ret
159 ; OPT-LABEL: @fct5(
160 ; OPT-NEXT: entry:
161 ; OPT-NEXT: [[TMP0:%.*]] = load i32, i32* [[Y:%.*]], align 8
162 ; OPT-NEXT: [[AND:%.*]] = and i32 [[TMP0]], -8
163 ; OPT-NEXT: [[SHR:%.*]] = lshr i32 [[X:%.*]], 16
164 ; OPT-NEXT: [[AND1:%.*]] = and i32 [[SHR]], 7
165 ; OPT-NEXT: [[OR:%.*]] = or i32 [[AND]], [[AND1]]
166 ; OPT-NEXT: store i32 [[OR]], i32* [[Y]], align 8
167 ; OPT-NEXT: ret void
168 ;
169 entry:
95170 %0 = load i32, i32* %y, align 8
96171 %and = and i32 %0, -8
97172 %shr = lshr i32 %x, 16
103178
104179 ; Check if we can still catch bfm instruction when we drop some low bits
105180 define void @fct6(i32* nocapture %y, i32 %x) nounwind optsize inlinehint ssp {
106 entry:
107 ; CHECK-LABEL: fct6:
108 ; CHECK: ldr [[REG1:w[0-9]+]],
109 ; CHECK-NEXT: bfxil [[REG1]], w1, #16, #3
181 ; LLC-LABEL: fct6:
182 ; LLC: // %bb.0: // %entry
183 ; LLC-NEXT: ldr w8, [x0]
184 ; LLC-NEXT: bfxil w8, w1, #16, #3
185 ; LLC-NEXT: lsr w8, w8, #2
186 ; LLC-NEXT: str w8, [x0]
187 ; LLC-NEXT: ret
188 ; OPT-LABEL: @fct6(
189 ; OPT-NEXT: entry:
190 ; OPT-NEXT: [[TMP0:%.*]] = load i32, i32* [[Y:%.*]], align 8
191 ; OPT-NEXT: [[AND:%.*]] = and i32 [[TMP0]], -8
192 ; OPT-NEXT: [[SHR:%.*]] = lshr i32 [[X:%.*]], 16
193 ; OPT-NEXT: [[AND1:%.*]] = and i32 [[SHR]], 7
194 ; OPT-NEXT: [[OR:%.*]] = or i32 [[AND]], [[AND1]]
195 ; OPT-NEXT: [[SHR1:%.*]] = lshr i32 [[OR]], 2
196 ; OPT-NEXT: store i32 [[SHR1]], i32* [[Y]], align 8
197 ; OPT-NEXT: ret void
198 ;
199 entry:
110200 ; lsr is an alias of ubfm
111 ; CHECK-NEXT: lsr [[REG2:w[0-9]+]], [[REG1]], #2
112 ; CHECK-NEXT: str [[REG2]],
113 ; CHECK-NEXT: ret
114201 %0 = load i32, i32* %y, align 8
115202 %and = and i32 %0, -8
116203 %shr = lshr i32 %x, 16
124211
125212 ; Check if we can still catch bfm instruction when we drop some high bits
126213 define void @fct7(i32* nocapture %y, i32 %x) nounwind optsize inlinehint ssp {
127 entry:
128 ; CHECK-LABEL: fct7:
129 ; CHECK: ldr [[REG1:w[0-9]+]],
130 ; CHECK-NEXT: bfxil [[REG1]], w1, #16, #3
214 ; LLC-LABEL: fct7:
215 ; LLC: // %bb.0: // %entry
216 ; LLC-NEXT: ldr w8, [x0]
217 ; LLC-NEXT: bfxil w8, w1, #16, #3
218 ; LLC-NEXT: lsl w8, w8, #2
219 ; LLC-NEXT: str w8, [x0]
220 ; LLC-NEXT: ret
221 ; OPT-LABEL: @fct7(
222 ; OPT-NEXT: entry:
223 ; OPT-NEXT: [[TMP0:%.*]] = load i32, i32* [[Y:%.*]], align 8
224 ; OPT-NEXT: [[AND:%.*]] = and i32 [[TMP0]], -8
225 ; OPT-NEXT: [[SHR:%.*]] = lshr i32 [[X:%.*]], 16
226 ; OPT-NEXT: [[AND1:%.*]] = and i32 [[SHR]], 7
227 ; OPT-NEXT: [[OR:%.*]] = or i32 [[AND]], [[AND1]]
228 ; OPT-NEXT: [[SHL:%.*]] = shl i32 [[OR]], 2
229 ; OPT-NEXT: store i32 [[SHL]], i32* [[Y]], align 8
230 ; OPT-NEXT: ret void
231 ;
232 entry:
131233 ; lsl is an alias of ubfm
132 ; CHECK-NEXT: lsl [[REG2:w[0-9]+]], [[REG1]], #2
133 ; CHECK-NEXT: str [[REG2]],
134 ; CHECK-NEXT: ret
135234 %0 = load i32, i32* %y, align 8
136235 %and = and i32 %0, -8
137236 %shr = lshr i32 %x, 16
146245 ; Check if we can still catch bfm instruction when we drop some low bits
147246 ; (i64 version)
148247 define void @fct8(i64* nocapture %y, i64 %x) nounwind optsize inlinehint ssp {
149 entry:
150 ; CHECK-LABEL: fct8:
151 ; CHECK: ldr [[REG1:x[0-9]+]],
152 ; CHECK-NEXT: bfxil [[REG1]], x1, #16, #3
248 ; LLC-LABEL: fct8:
249 ; LLC: // %bb.0: // %entry
250 ; LLC-NEXT: ldr x8, [x0]
251 ; LLC-NEXT: bfxil x8, x1, #16, #3
252 ; LLC-NEXT: lsr x8, x8, #2
253 ; LLC-NEXT: str x8, [x0]
254 ; LLC-NEXT: ret
255 ; OPT-LABEL: @fct8(
256 ; OPT-NEXT: entry:
257 ; OPT-NEXT: [[TMP0:%.*]] = load i64, i64* [[Y:%.*]], align 8
258 ; OPT-NEXT: [[AND:%.*]] = and i64 [[TMP0]], -8
259 ; OPT-NEXT: [[SHR:%.*]] = lshr i64 [[X:%.*]], 16
260 ; OPT-NEXT: [[AND1:%.*]] = and i64 [[SHR]], 7
261 ; OPT-NEXT: [[OR:%.*]] = or i64 [[AND]], [[AND1]]
262 ; OPT-NEXT: [[SHR1:%.*]] = lshr i64 [[OR]], 2
263 ; OPT-NEXT: store i64 [[SHR1]], i64* [[Y]], align 8
264 ; OPT-NEXT: ret void
265 ;
266 entry:
153267 ; lsr is an alias of ubfm
154 ; CHECK-NEXT: lsr [[REG2:x[0-9]+]], [[REG1]], #2
155 ; CHECK-NEXT: str [[REG2]],
156 ; CHECK-NEXT: ret
157268 %0 = load i64, i64* %y, align 8
158269 %and = and i64 %0, -8
159270 %shr = lshr i64 %x, 16
168279 ; Check if we can still catch bfm instruction when we drop some high bits
169280 ; (i64 version)
170281 define void @fct9(i64* nocapture %y, i64 %x) nounwind optsize inlinehint ssp {
171 entry:
172 ; CHECK-LABEL: fct9:
173 ; CHECK: ldr [[REG1:x[0-9]+]],
174 ; CHECK-NEXT: bfxil [[REG1]], x1, #16, #3
282 ; LLC-LABEL: fct9:
283 ; LLC: // %bb.0: // %entry
284 ; LLC-NEXT: ldr x8, [x0]
285 ; LLC-NEXT: bfxil x8, x1, #16, #3
286 ; LLC-NEXT: lsl x8, x8, #2
287 ; LLC-NEXT: str x8, [x0]
288 ; LLC-NEXT: ret
289 ; OPT-LABEL: @fct9(
290 ; OPT-NEXT: entry:
291 ; OPT-NEXT: [[TMP0:%.*]] = load i64, i64* [[Y:%.*]], align 8
292 ; OPT-NEXT: [[AND:%.*]] = and i64 [[TMP0]], -8
293 ; OPT-NEXT: [[SHR:%.*]] = lshr i64 [[X:%.*]], 16
294 ; OPT-NEXT: [[AND1:%.*]] = and i64 [[SHR]], 7
295 ; OPT-NEXT: [[OR:%.*]] = or i64 [[AND]], [[AND1]]
296 ; OPT-NEXT: [[SHL:%.*]] = shl i64 [[OR]], 2
297 ; OPT-NEXT: store i64 [[SHL]], i64* [[Y]], align 8
298 ; OPT-NEXT: ret void
299 ;
300 entry:
175301 ; lsr is an alias of ubfm
176 ; CHECK-NEXT: lsl [[REG2:x[0-9]+]], [[REG1]], #2
177 ; CHECK-NEXT: str [[REG2]],
178 ; CHECK-NEXT: ret
179302 %0 = load i64, i64* %y, align 8
180303 %and = and i64 %0, -8
181304 %shr = lshr i64 %x, 16
189312 ; Check if we can catch bfm instruction when lsb is 0 (i.e., no lshr)
190313 ; (i32 version)
191314 define void @fct10(i32* nocapture %y, i32 %x) nounwind optsize inlinehint ssp {
192 entry:
193 ; CHECK-LABEL: fct10:
194 ; CHECK: ldr [[REG1:w[0-9]+]],
195 ; CHECK-NEXT: bfxil [[REG1]], w1, #0, #3
315 ; LLC-LABEL: fct10:
316 ; LLC: // %bb.0: // %entry
317 ; LLC-NEXT: ldr w8, [x0]
318 ; LLC-NEXT: bfxil w8, w1, #0, #3
319 ; LLC-NEXT: lsl w8, w8, #2
320 ; LLC-NEXT: str w8, [x0]
321 ; LLC-NEXT: ret
322 ; OPT-LABEL: @fct10(
323 ; OPT-NEXT: entry:
324 ; OPT-NEXT: [[TMP0:%.*]] = load i32, i32* [[Y:%.*]], align 8
325 ; OPT-NEXT: [[AND:%.*]] = and i32 [[TMP0]], -8
326 ; OPT-NEXT: [[AND1:%.*]] = and i32 [[X:%.*]], 7
327 ; OPT-NEXT: [[OR:%.*]] = or i32 [[AND]], [[AND1]]
328 ; OPT-NEXT: [[SHL:%.*]] = shl i32 [[OR]], 2
329 ; OPT-NEXT: store i32 [[SHL]], i32* [[Y]], align 8
330 ; OPT-NEXT: ret void
331 ;
332 entry:
196333 ; lsl is an alias of ubfm
197 ; CHECK-NEXT: lsl [[REG2:w[0-9]+]], [[REG1]], #2
198 ; CHECK-NEXT: str [[REG2]],
199 ; CHECK-NEXT: ret
200334 %0 = load i32, i32* %y, align 8
201335 %and = and i32 %0, -8
202336 %and1 = and i32 %x, 7
209343 ; Check if we can catch bfm instruction when lsb is 0 (i.e., no lshr)
210344 ; (i64 version)
211345 define void @fct11(i64* nocapture %y, i64 %x) nounwind optsize inlinehint ssp {
212 entry:
213 ; CHECK-LABEL: fct11:
214 ; CHECK: ldr [[REG1:x[0-9]+]],
215 ; CHECK-NEXT: bfxil [[REG1]], x1, #0, #3
346 ; LLC-LABEL: fct11:
347 ; LLC: // %bb.0: // %entry
348 ; LLC-NEXT: ldr x8, [x0]
349 ; LLC-NEXT: bfxil x8, x1, #0, #3
350 ; LLC-NEXT: lsl x8, x8, #2
351 ; LLC-NEXT: str x8, [x0]
352 ; LLC-NEXT: ret
353 ; OPT-LABEL: @fct11(
354 ; OPT-NEXT: entry:
355 ; OPT-NEXT: [[TMP0:%.*]] = load i64, i64* [[Y:%.*]], align 8
356 ; OPT-NEXT: [[AND:%.*]] = and i64 [[TMP0]], -8
357 ; OPT-NEXT: [[AND1:%.*]] = and i64 [[X:%.*]], 7
358 ; OPT-NEXT: [[OR:%.*]] = or i64 [[AND]], [[AND1]]
359 ; OPT-NEXT: [[SHL:%.*]] = shl i64 [[OR]], 2
360 ; OPT-NEXT: store i64 [[SHL]], i64* [[Y]], align 8
361 ; OPT-NEXT: ret void
362 ;
363 entry:
216364 ; lsl is an alias of ubfm
217 ; CHECK-NEXT: lsl [[REG2:x[0-9]+]], [[REG1]], #2
218 ; CHECK-NEXT: str [[REG2]],
219 ; CHECK-NEXT: ret
220365 %0 = load i64, i64* %y, align 8
221366 %and = and i64 %0, -8
222367 %and1 = and i64 %x, 7
227372 }
228373
229374 define zeroext i1 @fct12bis(i32 %tmp2) unnamed_addr nounwind ssp align 2 {
230 ; CHECK-LABEL: fct12bis:
231 ; CHECK-NOT: and
232 ; CHECK: ubfx w0, w0, #11, #1
375 ; LLC-LABEL: fct12bis:
376 ; LLC: // %bb.0:
377 ; LLC-NEXT: ubfx w0, w0, #11, #1
378 ; LLC-NEXT: ret
379 ; OPT-LABEL: @fct12bis(
380 ; OPT-NEXT: [[AND_I_I:%.*]] = and i32 [[TMP2:%.*]], 2048
381 ; OPT-NEXT: [[TOBOOL_I_I:%.*]] = icmp ne i32 [[AND_I_I]], 0
382 ; OPT-NEXT: ret i1 [[TOBOOL_I_I]]
383 ;
233384 %and.i.i = and i32 %tmp2, 2048
234385 %tobool.i.i = icmp ne i32 %and.i.i, 0
235386 ret i1 %tobool.i.i
238389 ; Check if we can still catch bfm instruction when we drop some high bits
239390 ; and some low bits
240391 define void @fct12(i32* nocapture %y, i32 %x) nounwind optsize inlinehint ssp {
241 entry:
242 ; CHECK-LABEL: fct12:
243 ; CHECK: ldr [[REG1:w[0-9]+]],
244 ; CHECK-NEXT: bfxil [[REG1]], w1, #16, #3
392 ; LLC-LABEL: fct12:
393 ; LLC: // %bb.0: // %entry
394 ; LLC-NEXT: ldr w8, [x0]
395 ; LLC-NEXT: bfxil w8, w1, #16, #3
396 ; LLC-NEXT: ubfx w8, w8, #2, #28
397 ; LLC-NEXT: str w8, [x0]
398 ; LLC-NEXT: ret
399 ; OPT-LABEL: @fct12(
400 ; OPT-NEXT: entry:
401 ; OPT-NEXT: [[TMP0:%.*]] = load i32, i32* [[Y:%.*]], align 8
402 ; OPT-NEXT: [[AND:%.*]] = and i32 [[TMP0]], -8
403 ; OPT-NEXT: [[SHR:%.*]] = lshr i32 [[X:%.*]], 16
404 ; OPT-NEXT: [[AND1:%.*]] = and i32 [[SHR]], 7
405 ; OPT-NEXT: [[OR:%.*]] = or i32 [[AND]], [[AND1]]
406 ; OPT-NEXT: [[SHL:%.*]] = shl i32 [[OR]], 2
407 ; OPT-NEXT: [[SHR2:%.*]] = lshr i32 [[SHL]], 4
408 ; OPT-NEXT: store i32 [[SHR2]], i32* [[Y]], align 8
409 ; OPT-NEXT: ret void
410 ;
411 entry:
245412 ; lsr is an alias of ubfm
246 ; CHECK-NEXT: ubfx [[REG2:w[0-9]+]], [[REG1]], #2, #28
247 ; CHECK-NEXT: str [[REG2]],
248 ; CHECK-NEXT: ret
249413 %0 = load i32, i32* %y, align 8
250414 %and = and i32 %0, -8
251415 %shr = lshr i32 %x, 16
261425 ; and some low bits
262426 ; (i64 version)
263427 define void @fct13(i64* nocapture %y, i64 %x) nounwind optsize inlinehint ssp {
264 entry:
265 ; CHECK-LABEL: fct13:
266 ; CHECK: ldr [[REG1:x[0-9]+]],
267 ; CHECK-NEXT: bfxil [[REG1]], x1, #16, #3
428 ; LLC-LABEL: fct13:
429 ; LLC: // %bb.0: // %entry
430 ; LLC-NEXT: ldr x8, [x0]
431 ; LLC-NEXT: bfxil x8, x1, #16, #3
432 ; LLC-NEXT: ubfx x8, x8, #2, #60
433 ; LLC-NEXT: str x8, [x0]
434 ; LLC-NEXT: ret
435 ; OPT-LABEL: @fct13(
436 ; OPT-NEXT: entry:
437 ; OPT-NEXT: [[TMP0:%.*]] = load i64, i64* [[Y:%.*]], align 8
438 ; OPT-NEXT: [[AND:%.*]] = and i64 [[TMP0]], -8
439 ; OPT-NEXT: [[SHR:%.*]] = lshr i64 [[X:%.*]], 16
440 ; OPT-NEXT: [[AND1:%.*]] = and i64 [[SHR]], 7
441 ; OPT-NEXT: [[OR:%.*]] = or i64 [[AND]], [[AND1]]
442 ; OPT-NEXT: [[SHL:%.*]] = shl i64 [[OR]], 2
443 ; OPT-NEXT: [[SHR2:%.*]] = lshr i64 [[SHL]], 4
444 ; OPT-NEXT: store i64 [[SHR2]], i64* [[Y]], align 8
445 ; OPT-NEXT: ret void
446 ;
447 entry:
268448 ; lsr is an alias of ubfm
269 ; CHECK-NEXT: ubfx [[REG2:x[0-9]+]], [[REG1]], #2, #60
270 ; CHECK-NEXT: str [[REG2]],
271 ; CHECK-NEXT: ret
272449 %0 = load i64, i64* %y, align 8
273450 %and = and i64 %0, -8
274451 %shr = lshr i64 %x, 16
284461 ; Check if we can still catch bfm instruction when we drop some high bits
285462 ; and some low bits
286463 define void @fct14(i32* nocapture %y, i32 %x, i32 %x1) nounwind optsize inlinehint ssp {
287 entry:
288 ; CHECK-LABEL: fct14:
289 ; CHECK: ldr [[REG1:w[0-9]+]],
290 ; CHECK-NEXT: bfxil [[REG1]], w1, #16, #8
464 ; LLC-LABEL: fct14:
465 ; LLC: // %bb.0: // %entry
466 ; LLC-NEXT: ldr w8, [x0]
467 ; LLC-NEXT: bfxil w8, w1, #16, #8
468 ; LLC-NEXT: lsr w8, w8, #4
469 ; LLC-NEXT: bfxil w8, w2, #5, #3
470 ; LLC-NEXT: lsl w8, w8, #2
471 ; LLC-NEXT: str w8, [x0]
472 ; LLC-NEXT: ret
473 ; OPT-LABEL: @fct14(
474 ; OPT-NEXT: entry:
475 ; OPT-NEXT: [[TMP0:%.*]] = load i32, i32* [[Y:%.*]], align 8
476 ; OPT-NEXT: [[AND:%.*]] = and i32 [[TMP0]], -256
477 ; OPT-NEXT: [[SHR:%.*]] = lshr i32 [[X:%.*]], 16
478 ; OPT-NEXT: [[AND1:%.*]] = and i32 [[SHR]], 255
479 ; OPT-NEXT: [[OR:%.*]] = or i32 [[AND]], [[AND1]]
480 ; OPT-NEXT: [[SHL:%.*]] = lshr i32 [[OR]], 4
481 ; OPT-NEXT: [[AND2:%.*]] = and i32 [[SHL]], -8
482 ; OPT-NEXT: [[SHR1:%.*]] = lshr i32 [[X1:%.*]], 5
483 ; OPT-NEXT: [[AND3:%.*]] = and i32 [[SHR1]], 7
484 ; OPT-NEXT: [[OR1:%.*]] = or i32 [[AND2]], [[AND3]]
485 ; OPT-NEXT: [[SHL1:%.*]] = shl i32 [[OR1]], 2
486 ; OPT-NEXT: store i32 [[SHL1]], i32* [[Y]], align 8
487 ; OPT-NEXT: ret void
488 ;
489 entry:
291490 ; lsr is an alias of ubfm
292 ; CHECK-NEXT: lsr [[REG2:w[0-9]+]], [[REG1]], #4
293 ; CHECK-NEXT: bfxil [[REG2]], w2, #5, #3
294491 ; lsl is an alias of ubfm
295 ; CHECK-NEXT: lsl [[REG3:w[0-9]+]], [[REG2]], #2
296 ; CHECK-NEXT: str [[REG3]],
297 ; CHECK-NEXT: ret
298492 %0 = load i32, i32* %y, align 8
299493 %and = and i32 %0, -256
300494 %shr = lshr i32 %x, 16
314508 ; and some low bits
315509 ; (i64 version)
316510 define void @fct15(i64* nocapture %y, i64 %x, i64 %x1) nounwind optsize inlinehint ssp {
317 entry:
318 ; CHECK-LABEL: fct15:
319 ; CHECK: ldr [[REG1:x[0-9]+]],
320 ; CHECK-NEXT: bfxil [[REG1]], x1, #16, #8
511 ; LLC-LABEL: fct15:
512 ; LLC: // %bb.0: // %entry
513 ; LLC-NEXT: ldr x8, [x0]
514 ; LLC-NEXT: bfxil x8, x1, #16, #8
515 ; LLC-NEXT: lsr x8, x8, #4
516 ; LLC-NEXT: bfxil x8, x2, #5, #3
517 ; LLC-NEXT: lsl x8, x8, #2
518 ; LLC-NEXT: str x8, [x0]
519 ; LLC-NEXT: ret
520 ; OPT-LABEL: @fct15(
521 ; OPT-NEXT: entry:
522 ; OPT-NEXT: [[TMP0:%.*]] = load i64, i64* [[Y:%.*]], align 8
523 ; OPT-NEXT: [[AND:%.*]] = and i64 [[TMP0]], -256
524 ; OPT-NEXT: [[SHR:%.*]] = lshr i64 [[X:%.*]], 16
525 ; OPT-NEXT: [[AND1:%.*]] = and i64 [[SHR]], 255
526 ; OPT-NEXT: [[OR:%.*]] = or i64 [[AND]], [[AND1]]
527 ; OPT-NEXT: [[SHL:%.*]] = lshr i64 [[OR]], 4
528 ; OPT-NEXT: [[AND2:%.*]] = and i64 [[SHL]], -8
529 ; OPT-NEXT: [[SHR1:%.*]] = lshr i64 [[X1:%.*]], 5
530 ; OPT-NEXT: [[AND3:%.*]] = and i64 [[SHR1]], 7
531 ; OPT-NEXT: [[OR1:%.*]] = or i64 [[AND2]], [[AND3]]
532 ; OPT-NEXT: [[SHL1:%.*]] = shl i64 [[OR1]], 2
533 ; OPT-NEXT: store i64 [[SHL1]], i64* [[Y]], align 8
534 ; OPT-NEXT: ret void
535 ;
536 entry:
321537 ; lsr is an alias of ubfm
322 ; CHECK-NEXT: lsr [[REG2:x[0-9]+]], [[REG1]], #4
323 ; CHECK-NEXT: bfxil [[REG2]], x2, #5, #3
324538 ; lsl is an alias of ubfm
325 ; CHECK-NEXT: lsl [[REG3:x[0-9]+]], [[REG2]], #2
326 ; CHECK-NEXT: str [[REG3]],
327 ; CHECK-NEXT: ret
328539 %0 = load i64, i64* %y, align 8
329540 %and = and i64 %0, -256
330541 %shr = lshr i64 %x, 16
343554 ; Check if we can still catch bfm instruction when we drop some high bits
344555 ; and some low bits and a masking operation has to be kept
345556 define void @fct16(i32* nocapture %y, i32 %x) nounwind optsize inlinehint ssp {
346 entry:
347 ; CHECK-LABEL: fct16:
348 ; CHECK: ldr [[REG1:w[0-9]+]],
557 ; LLC-LABEL: fct16:
558 ; LLC: // %bb.0: // %entry
559 ; LLC-NEXT: ldr w8, [x0]
560 ; LLC-NEXT: mov w9, #33120
561 ; LLC-NEXT: movk w9, #26, lsl #16
562 ; LLC-NEXT: and w8, w8, w9
563 ; LLC-NEXT: bfxil w8, w1, #16, #3
564 ; LLC-NEXT: ubfx w8, w8, #2, #28
565 ; LLC-NEXT: str w8, [x0]
566 ; LLC-NEXT: ret
567 ; OPT-LABEL: @fct16(
568 ; OPT-NEXT: entry:
569 ; OPT-NEXT: [[TMP0:%.*]] = load i32, i32* [[Y:%.*]], align 8
570 ; OPT-NEXT: [[AND:%.*]] = and i32 [[TMP0]], 1737056
571 ; OPT-NEXT: [[SHR:%.*]] = lshr i32 [[X:%.*]], 16
572 ; OPT-NEXT: [[AND1:%.*]] = and i32 [[SHR]], 7
573 ; OPT-NEXT: [[OR:%.*]] = or i32 [[AND]], [[AND1]]
574 ; OPT-NEXT: [[SHL:%.*]] = shl i32 [[OR]], 2
575 ; OPT-NEXT: [[SHR2:%.*]] = lshr i32 [[SHL]], 4
576 ; OPT-NEXT: store i32 [[SHR2]], i32* [[Y]], align 8
577 ; OPT-NEXT: ret void
578 ;
579 entry:
349580 ; Create the constant
350 ; CHECK: mov [[REGCST:w[0-9]+]], #33120
351 ; CHECK: movk [[REGCST]], #26, lsl #16
352581 ; Do the masking
353 ; CHECK: and [[REG2:w[0-9]+]], [[REG1]], [[REGCST]]
354 ; CHECK-NEXT: bfxil [[REG2]], w1, #16, #3
355582 ; lsr is an alias of ubfm
356 ; CHECK-NEXT: ubfx [[REG3:w[0-9]+]], [[REG2]], #2, #28
357 ; CHECK-NEXT: str [[REG3]],
358 ; CHECK-NEXT: ret
359583 %0 = load i32, i32* %y, align 8
360584 %and = and i32 %0, 1737056
361585 %shr = lshr i32 %x, 16
372596 ; and some low bits and a masking operation has to be kept
373597 ; (i64 version)
374598 define void @fct17(i64* nocapture %y, i64 %x) nounwind optsize inlinehint ssp {
375 entry:
376 ; CHECK-LABEL: fct17:
377 ; CHECK: ldr [[REG1:x[0-9]+]],
599 ; LLC-LABEL: fct17:
600 ; LLC: // %bb.0: // %entry
601 ; LLC-NEXT: ldr x8, [x0]
602 ; LLC-NEXT: mov w9, #33120
603 ; LLC-NEXT: movk w9, #26, lsl #16
604 ; LLC-NEXT: and x8, x8, x9
605 ; LLC-NEXT: bfxil x8, x1, #16, #3
606 ; LLC-NEXT: ubfx x8, x8, #2, #60
607 ; LLC-NEXT: str x8, [x0]
608 ; LLC-NEXT: ret
609 ; OPT-LABEL: @fct17(
610 ; OPT-NEXT: entry:
611 ; OPT-NEXT: [[TMP0:%.*]] = load i64, i64* [[Y:%.*]], align 8
612 ; OPT-NEXT: [[AND:%.*]] = and i64 [[TMP0]], 1737056
613 ; OPT-NEXT: [[SHR:%.*]] = lshr i64 [[X:%.*]], 16
614 ; OPT-NEXT: [[AND1:%.*]] = and i64 [[SHR]], 7
615 ; OPT-NEXT: [[OR:%.*]] = or i64 [[AND]], [[AND1]]
616 ; OPT-NEXT: [[SHL:%.*]] = shl i64 [[OR]], 2
617 ; OPT-NEXT: [[SHR2:%.*]] = lshr i64 [[SHL]], 4
618 ; OPT-NEXT: store i64 [[SHR2]], i64* [[Y]], align 8
619 ; OPT-NEXT: ret void
620 ;
621 entry:
378622 ; Create the constant
379 ; CHECK: mov w[[REGCST:[0-9]+]], #33120
380 ; CHECK: movk w[[REGCST]], #26, lsl #16
381623 ; Do the masking
382 ; CHECK: and [[REG2:x[0-9]+]], [[REG1]], x[[REGCST]]
383 ; CHECK-NEXT: bfxil [[REG2]], x1, #16, #3
384624 ; lsr is an alias of ubfm
385 ; CHECK-NEXT: ubfx [[REG3:x[0-9]+]], [[REG2]], #2, #60
386 ; CHECK-NEXT: str [[REG3]],
387 ; CHECK-NEXT: ret
388625 %0 = load i64, i64* %y, align 8
389626 %and = and i64 %0, 1737056
390627 %shr = lshr i64 %x, 16
397634 }
398635
399636 define i64 @fct18(i32 %xor72) nounwind ssp {
400 ; CHECK-LABEL: fct18:
401 ; CHECK: ubfx x0, x0, #9, #8
637 ; LLC-LABEL: fct18:
638 ; LLC: // %bb.0:
639 ; LLC-NEXT: // kill: def $w0 killed $w0 def $x0
640 ; LLC-NEXT: ubfx x0, x0, #9, #8
641 ; LLC-NEXT: ret
642 ; OPT-LABEL: @fct18(
643 ; OPT-NEXT: [[SHR81:%.*]] = lshr i32 [[XOR72:%.*]], 9
644 ; OPT-NEXT: [[CONV82:%.*]] = zext i32 [[SHR81]] to i64
645 ; OPT-NEXT: [[RESULT:%.*]] = and i64 [[CONV82]], 255
646 ; OPT-NEXT: ret i64 [[RESULT]]
647 ;
402648 %shr81 = lshr i32 %xor72, 9
403649 %conv82 = zext i32 %shr81 to i64
404650 %result = and i64 %conv82, 255
410656
411657 ; Function Attrs: nounwind readonly ssp
412658 define i32 @fct19(i64 %arg1) nounwind readonly ssp {
413 ; CHECK-LABEL: fct19:
659 ; LLC-LABEL: fct19:
660 ; LLC: // %bb.0: // %entry
661 ; LLC-NEXT: lsr x8, x0, #48
662 ; LLC-NEXT: cbz x8, .LBB22_2
663 ; LLC-NEXT: // %bb.1: // %if.then
664 ; LLC-NEXT: adrp x9, first_ones
665 ; LLC-NEXT: add x9, x9, :lo12:first_ones
666 ; LLC-NEXT: ldrb w0, [x9, x8]
667 ; LLC-NEXT: ret
668 ; LLC-NEXT: .LBB22_2: // %if.end
669 ; LLC-NEXT: ubfx x8, x0, #32, #16
670 ; LLC-NEXT: cbz w8, .LBB22_4
671 ; LLC-NEXT: // %bb.3: // %if.then7
672 ; LLC-NEXT: adrp x9, first_ones
673 ; LLC-NEXT: add x9, x9, :lo12:first_ones
674 ; LLC-NEXT: ldrb w8, [x9, x8]
675 ; LLC-NEXT: add w0, w8, #16 // =16
676 ; LLC-NEXT: ret
677 ; LLC-NEXT: .LBB22_4: // %if.end13
678 ; LLC-NEXT: ubfx x8, x0, #16, #16
679 ; LLC-NEXT: cbz w8, .LBB22_6
680 ; LLC-NEXT: // %bb.5: // %if.then17
681 ; LLC-NEXT: adrp x9, first_ones
682 ; LLC-NEXT: add x9, x9, :lo12:first_ones
683 ; LLC-NEXT: ldrb w8, [x9, x8]
684 ; LLC-NEXT: add w0, w8, #32 // =32
685 ; LLC-NEXT: ret
686 ; LLC-NEXT: .LBB22_6:
687 ; LLC-NEXT: mov w0, #64
688 ; LLC-NEXT: ret
689 ; OPT-LABEL: @fct19(
690 ; OPT-NEXT: entry:
691 ; OPT-NEXT: [[X_SROA_1_0_EXTRACT_SHIFT:%.*]] = lshr i64 [[ARG1:%.*]], 16
692 ; OPT-NEXT: [[X_SROA_1_0_EXTRACT_TRUNC:%.*]] = trunc i64 [[X_SROA_1_0_EXTRACT_SHIFT]] to i16
693 ; OPT-NEXT: [[X_SROA_5_0_EXTRACT_SHIFT:%.*]] = lshr i64 [[ARG1]], 48
694 ; OPT-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[X_SROA_5_0_EXTRACT_SHIFT]], 0
695 ; OPT-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
696 ; OPT: if.then:
697 ; OPT-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds [65536 x i8], [65536 x i8]* @first_ones, i64 0, i64 [[X_SROA_5_0_EXTRACT_SHIFT]]
698 ; OPT-NEXT: [[TMP0:%.*]] = load i8, i8* [[ARRAYIDX3]], align 1
699 ; OPT-NEXT: [[CONV:%.*]] = zext i8 [[TMP0]] to i32
700 ; OPT-NEXT: br label [[RETURN:%.*]]
701 ; OPT: if.end:
702 ; OPT-NEXT: [[TMP1:%.*]] = lshr i64 [[ARG1]], 32
703 ; OPT-NEXT: [[X_SROA_3_0_EXTRACT_TRUNC:%.*]] = trunc i64 [[TMP1]] to i16
704 ; OPT-NEXT: [[TOBOOL6:%.*]] = icmp eq i16 [[X_SROA_3_0_EXTRACT_TRUNC]], 0
705 ; OPT-NEXT: br i1 [[TOBOOL6]], label [[IF_END13:%.*]], label [[IF_THEN7:%.*]]
706 ; OPT: if.then7:
707 ; OPT-NEXT: [[TMP2:%.*]] = lshr i64 [[ARG1]], 32
708 ; OPT-NEXT: [[IDXPROM10:%.*]] = and i64 [[TMP2]], 65535
709 ; OPT-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [65536 x i8], [65536 x i8]* @first_ones, i64 0, i64 [[IDXPROM10]]
710 ; OPT-NEXT: [[TMP3:%.*]] = load i8, i8* [[ARRAYIDX11]], align 1
711 ; OPT-NEXT: [[CONV12:%.*]] = zext i8 [[TMP3]] to i32
712 ; OPT-NEXT: [[ADD:%.*]] = add nsw i32 [[CONV12]], 16
713 ; OPT-NEXT: br label [[RETURN]]
714 ; OPT: if.end13:
715 ; OPT-NEXT: [[TMP4:%.*]] = lshr i64 [[ARG1]], 16
716 ; OPT-NEXT: [[TMP5:%.*]] = trunc i64 [[TMP4]] to i16
717 ; OPT-NEXT: [[TOBOOL16:%.*]] = icmp eq i16 [[TMP5]], 0
718 ; OPT-NEXT: br i1 [[TOBOOL16]], label [[RETURN]], label [[IF_THEN17:%.*]]
719 ; OPT: if.then17:
720 ; OPT-NEXT: [[TMP6:%.*]] = lshr i64 [[ARG1]], 16
721 ; OPT-NEXT: [[IDXPROM20:%.*]] = and i64 [[TMP6]], 65535
722 ; OPT-NEXT: [[ARRAYIDX21:%.*]] = getelementptr inbounds [65536 x i8], [65536 x i8]* @first_ones, i64 0, i64 [[IDXPROM20]]
723 ; OPT-NEXT: [[TMP7:%.*]] = load i8, i8* [[ARRAYIDX21]], align 1
724 ; OPT-NEXT: [[CONV22:%.*]] = zext i8 [[TMP7]] to i32
725 ; OPT-NEXT: [[ADD23:%.*]] = add nsw i32 [[CONV22]], 32
726 ; OPT-NEXT: br label [[RETURN]]
727 ; OPT: return:
728 ; OPT-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[CONV]], [[IF_THEN]] ], [ [[ADD]], [[IF_THEN7]] ], [ [[ADD23]], [[IF_THEN17]] ], [ 64, [[IF_END13]] ]
729 ; OPT-NEXT: ret i32 [[RETVAL_0]]
730 ;
414731 entry:
415732 %x.sroa.1.0.extract.shift = lshr i64 %arg1, 16
416733 %x.sroa.1.0.extract.trunc = trunc i64 %x.sroa.1.0.extract.shift to i16
425742 %conv = zext i8 %0 to i32
426743 br label %return
427744
428 ; OPT-LABEL: if.end
429745 if.end: ; preds = %entry
430 ; OPT: lshr
431 ; CHECK: ubfx [[REG1:x[0-9]+]], [[REG2:x[0-9]+]], #32, #16
432746 %x.sroa.3.0.extract.trunc = trunc i64 %x.sroa.3.0.extract.shift to i16
433747 %tobool6 = icmp eq i16 %x.sroa.3.0.extract.trunc, 0
434 ; CHECK: cbz
435748 br i1 %tobool6, label %if.end13, label %if.then7
436749
437 ; OPT-LABEL: if.then7
438750 if.then7: ; preds = %if.end
439 ; OPT: lshr
440 ; "and" should be combined to "ubfm" while "ubfm" should be removed by cse.
441 ; So neither of them should be in the assemble code.
442 ; CHECK-NOT: and
443 ; CHECK-NOT: ubfm
751 ; "and" should be combined to "ubfm" while "ubfm" should be removed by cse.
752 ; So neither of them should be in the assemble code.
444753 %idxprom10 = and i64 %x.sroa.3.0.extract.shift, 65535
445754 %arrayidx11 = getelementptr inbounds [65536 x i8], [65536 x i8]* @first_ones, i64 0, i64 %idxprom10
446755 %1 = load i8, i8* %arrayidx11, align 1
448757 %add = add nsw i32 %conv12, 16
449758 br label %return
450759
451 ; OPT-LABEL: if.end13
452760 if.end13: ; preds = %if.end
453 ; OPT: lshr
454 ; OPT: trunc
455 ; CHECK: ubfx [[REG3:x[0-9]+]], [[REG4:x[0-9]+]], #16, #16
456761 %tobool16 = icmp eq i16 %x.sroa.1.0.extract.trunc, 0
457 ; CHECK: cbz
458762 br i1 %tobool16, label %return, label %if.then17
459763
460 ; OPT-LABEL: if.then17
461764 if.then17: ; preds = %if.end13
462 ; OPT: lshr
463 ; "and" should be combined to "ubfm" while "ubfm" should be removed by cse.
464 ; So neither of them should be in the assemble code.
465 ; CHECK-NOT: and
466 ; CHECK-NOT: ubfm
765 ; "and" should be combined to "ubfm" while "ubfm" should be removed by cse.
766 ; So neither of them should be in the assemble code.
467767 %idxprom20 = and i64 %x.sroa.1.0.extract.shift, 65535
468768 %arrayidx21 = getelementptr inbounds [65536 x i8], [65536 x i8]* @first_ones, i64 0, i64 %idxprom20
469769 %2 = load i8, i8* %arrayidx21, align 1
472772 br label %return
473773
474774 return: ; preds = %if.end13, %if.then17, %if.then7, %if.then
475 ; CHECK: ret
476775 %retval.0 = phi i32 [ %conv, %if.then ], [ %add, %if.then7 ], [ %add23, %if.then17 ], [ 64, %if.end13 ]
477776 ret i32 %retval.0
478777 }
479778
480779 ; Make sure we do not assert if the immediate in and is bigger than i64.
481780 ; PR19503.
482 ; OPT-LABEL: @fct20
483 ; OPT: lshr
484 ; OPT-NOT: lshr
485 ; OPT: ret
486 ; CHECK-LABEL: fct20:
487 ; CHECK: ret
488781 define i80 @fct20(i128 %a, i128 %b) {
782 ; LLC-LABEL: fct20:
783 ; LLC: // %bb.0: // %entry
784 ; LLC-NEXT: mov x12, #11776
785 ; LLC-NEXT: movk x12, #25856, lsl #16
786 ; LLC-NEXT: movk x12, #11077, lsl #32
787 ; LLC-NEXT: extr x8, x1, x0, #18
788 ; LLC-NEXT: lsr x9, x1, #18
789 ; LLC-NEXT: orr x10, x2, x3
790 ; LLC-NEXT: mov w11, #26220
791 ; LLC-NEXT: movk x12, #45, lsl #48
792 ; LLC-NEXT: and x11, x9, x11
793 ; LLC-NEXT: and x12, x8, x12
794 ; LLC-NEXT: cmp x10, #0 // =0
795 ; LLC-NEXT: csel x0, x12, x8, eq
796 ; LLC-NEXT: csel x1, x11, x9, eq
797 ; LLC-NEXT: ret
798 ; OPT-LABEL: @fct20(
799 ; OPT-NEXT: entry:
800 ; OPT-NEXT: [[SHR:%.*]] = lshr i128 [[A:%.*]], 18
801 ; OPT-NEXT: [[CONV:%.*]] = trunc i128 [[SHR]] to i80
802 ; OPT-NEXT: [[TOBOOL:%.*]] = icmp eq i128 [[B:%.*]], 0
803 ; OPT-NEXT: br i1 [[TOBOOL]], label [[THEN:%.*]], label [[END:%.*]]
804 ; OPT: then:
805 ; OPT-NEXT: [[AND:%.*]] = and i128 [[SHR]], 483673642326615442599424
806 ; OPT-NEXT: [[CONV2:%.*]] = trunc i128 [[AND]] to i80
807 ; OPT-NEXT: br label [[END]]
808 ; OPT: end:
809 ; OPT-NEXT: [[CONV3:%.*]] = phi i80 [ [[CONV]], [[ENTRY:%.*]] ], [ [[CONV2]], [[THEN]] ]
810 ; OPT-NEXT: ret i80 [[CONV3]]
811 ;
489812 entry:
490813 %shr = lshr i128 %a, 18
491814 %conv = trunc i128 %shr to i80
492815 %tobool = icmp eq i128 %b, 0
493816 br i1 %tobool, label %then, label %end
494 then:
817 then:
495818 %and = and i128 %shr, 483673642326615442599424
496819 %conv2 = trunc i128 %and to i80
497820 br label %end
498821 end:
499 %conv3 = phi i80 [%conv, %entry], [%conv2, %then]
822 %conv3 = phi i80 [%conv, %entry], [%conv2, %then]
500823 ret i80 %conv3
501824 }
502825
503826 ; Check if we can still catch UBFX when "AND" is used by SHL.
504 ; CHECK-LABEL: fct21:
505 ; CHECK: ubfx
506827 @arr = external global [8 x [64 x i64]]
507828 define i64 @fct21(i64 %x) {
829 ; LLC-LABEL: fct21:
830 ; LLC: // %bb.0: // %entry
831 ; LLC-NEXT: adrp x9, arr
832 ; LLC-NEXT: ubfx x8, x0, #4, #4
833 ; LLC-NEXT: add x9, x9, :lo12:arr
834 ; LLC-NEXT: ldr x0, [x9, x8, lsl #3]
835 ; LLC-NEXT: ret
836 ; OPT-LABEL: @fct21(
837 ; OPT-NEXT: entry:
838 ; OPT-NEXT: [[SHR:%.*]] = lshr i64 [[X:%.*]], 4
839 ; OPT-NEXT: [[AND:%.*]] = and i64 [[SHR]], 15
840 ; OPT-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x [64 x i64]], [8 x [64 x i64]]* @arr, i64 0, i64 0, i64 [[AND]]
841 ; OPT-NEXT: [[TMP0:%.*]] = load i64, i64* [[ARRAYIDX]], align 8
842 ; OPT-NEXT: ret i64 [[TMP0]]
843 ;
508844 entry:
509845 %shr = lshr i64 %x, 4
510846 %and = and i64 %shr, 15
514850 }
515851
516852 define i16 @test_ignored_rightbits(i32 %dst, i32 %in) {
517 ; CHECK-LABEL: test_ignored_rightbits:
518
853 ; LLC-LABEL: test_ignored_rightbits:
854 ; LLC: // %bb.0:
855 ; LLC-NEXT: and w0, w0, #0x7
856 ; LLC-NEXT: bfi w0, w1, #3, #4
857 ; LLC-NEXT: bfi w0, w0, #8, #7
858 ; LLC-NEXT: ret
859 ; OPT-LABEL: @test_ignored_rightbits(
860 ; OPT-NEXT: [[POSITIONED_FIELD:%.*]] = shl i32 [[IN:%.*]], 3
861 ; OPT-NEXT: [[POSITIONED_MASKED_FIELD:%.*]] = and i32 [[POSITIONED_FIELD]], 120
862 ; OPT-NEXT: [[MASKED_DST:%.*]] = and i32 [[DST:%.*]], 7
863 ; OPT-NEXT: [[INSERTION:%.*]] = or i32 [[MASKED_DST]], [[POSITIONED_MASKED_FIELD]]
864 ; OPT-NEXT: [[SHL16:%.*]] = shl i32 [[INSERTION]], 8
865 ; OPT-NEXT: [[OR18:%.*]] = or i32 [[SHL16]], [[INSERTION]]
866 ; OPT-NEXT: [[CONV19:%.*]] = trunc i32 [[OR18]] to i16
867 ; OPT-NEXT: ret i16 [[CONV19]]
868 ;
519869 %positioned_field = shl i32 %in, 3
520870 %positioned_masked_field = and i32 %positioned_field, 120
521871 %masked_dst = and i32 %dst, 7
522872 %insertion = or i32 %masked_dst, %positioned_masked_field
523 ; CHECK: {{bfm|bfi|bfxil}}
524873
525874 %shl16 = shl i32 %insertion, 8
526875 %or18 = or i32 %shl16, %insertion
527876 %conv19 = trunc i32 %or18 to i16
528 ; CHECK: bfi {{w[0-9]+}}, {{w[0-9]+}}, #8, #7
529877
530878 ret i16 %conv19
531879 }
533881 ; The following test excercises the case where we have a BFI
534882 ; instruction with the same input in both operands. We need to
535883 ; track the useful bits through both operands.
536 ; CHECK-LABEL: sameOperandBFI
537 ; CHECK: lsr
538 ; CHECK: and
539 ; CHECK: bfi
540 ; CHECK: bfi
541884 define void @sameOperandBFI(i64 %src, i64 %src2, i16 *%ptr) {
885 ; LLC-LABEL: sameOperandBFI:
886 ; LLC: // %bb.0: // %entry
887 ; LLC-NEXT: cbnz wzr, .LBB26_2
888 ; LLC-NEXT: // %bb.1: // %if.else
889 ; LLC-NEXT: lsr x8, x0, #47
890 ; LLC-NEXT: and w9, w1, #0x3
891 ; LLC-NEXT: bfi w9, w8, #2, #2
892 ; LLC-NEXT: bfi w9, w9, #4, #4
893 ; LLC-NEXT: strh w9, [x2]
894 ; LLC-NEXT: .LBB26_2: // %end
895 ; LLC-NEXT: ret
896 ; OPT-LABEL: @sameOperandBFI(
897 ; OPT-NEXT: entry:
898 ; OPT-NEXT: [[SHR47:%.*]] = lshr i64 [[SRC:%.*]], 47
899 ; OPT-NEXT: [[SRC2_TRUNC:%.*]] = trunc i64 [[SRC2:%.*]] to i32
900 ; OPT-NEXT: br i1 undef, label [[END:%.*]], label [[IF_ELSE:%.*]]
901 ; OPT: if.else:
902 ; OPT-NEXT: [[AND3:%.*]] = and i32 [[SRC2_TRUNC]], 3
903 ; OPT-NEXT: [[SHL2:%.*]] = shl nuw nsw i64 [[SHR47]], 2
904 ; OPT-NEXT: [[SHL2_TRUNC:%.*]] = trunc i64 [[SHL2]] to i32
905 ; OPT-NEXT: [[AND12:%.*]] = and i32 [[SHL2_TRUNC]], 12
906 ; OPT-NEXT: [[BFISOURCE:%.*]] = or i32 [[AND3]], [[AND12]]
907 ; OPT-NEXT: [[BFIRHS:%.*]] = shl nuw nsw i32 [[BFISOURCE]], 4
908 ; OPT-NEXT: [[BFI:%.*]] = or i32 [[BFIRHS]], [[BFISOURCE]]
909 ; OPT-NEXT: [[BFITRUNC:%.*]] = trunc i32 [[BFI]] to i16
910 ; OPT-NEXT: store i16 [[BFITRUNC]], i16* [[PTR:%.*]], align 4
911 ; OPT-NEXT: br label [[END]]
912 ; OPT: end:
913 ; OPT-NEXT: ret void
914 ;
542915 entry:
543916 %shr47 = lshr i64 %src, 47
544917 %src2.trunc = trunc i64 %src2 to i32
205205 'i686': (scrub_asm_x86, ASM_FUNCTION_X86_RE),
206206 'x86': (scrub_asm_x86, ASM_FUNCTION_X86_RE),
207207 'i386': (scrub_asm_x86, ASM_FUNCTION_X86_RE),
208 'arm64-eabi': (scrub_asm_arm_eabi, ASM_FUNCTION_AARCH64_RE),
208209 'aarch64': (scrub_asm_arm_eabi, ASM_FUNCTION_AARCH64_RE),
209210 'r600': (scrub_asm_amdgpu, ASM_FUNCTION_AMDGPU_RE),
210211 'amdgcn': (scrub_asm_amdgpu, ASM_FUNCTION_AMDGPU_RE),