xref: /aosp_15_r20/external/llvm/test/CodeGen/AArch64/arm64-bitfield-extract.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: opt -codegenprepare -mtriple=arm64-apple=ios -S -o - %s | FileCheck --check-prefix=OPT %s
2*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -march=arm64 | FileCheck %s
3*9880d681SAndroid Build Coastguard Worker%struct.X = type { i8, i8, [2 x i8] }
4*9880d681SAndroid Build Coastguard Worker%struct.Y = type { i32, i8 }
5*9880d681SAndroid Build Coastguard Worker%struct.Z = type { i8, i8, [2 x i8], i16 }
6*9880d681SAndroid Build Coastguard Worker%struct.A = type { i64, i8 }
7*9880d681SAndroid Build Coastguard Worker
8*9880d681SAndroid Build Coastguard Workerdefine void @foo(%struct.X* nocapture %x, %struct.Y* nocapture %y) nounwind optsize ssp {
9*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: foo:
10*9880d681SAndroid Build Coastguard Worker; CHECK: ubfx
11*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: and
12*9880d681SAndroid Build Coastguard Worker; CHECK: ret
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Worker  %tmp = bitcast %struct.X* %x to i32*
15*9880d681SAndroid Build Coastguard Worker  %tmp1 = load i32, i32* %tmp, align 4
16*9880d681SAndroid Build Coastguard Worker  %b = getelementptr inbounds %struct.Y, %struct.Y* %y, i64 0, i32 1
17*9880d681SAndroid Build Coastguard Worker  %bf.clear = lshr i32 %tmp1, 3
18*9880d681SAndroid Build Coastguard Worker  %bf.clear.lobit = and i32 %bf.clear, 1
19*9880d681SAndroid Build Coastguard Worker  %frombool = trunc i32 %bf.clear.lobit to i8
20*9880d681SAndroid Build Coastguard Worker  store i8 %frombool, i8* %b, align 1
21*9880d681SAndroid Build Coastguard Worker  ret void
22*9880d681SAndroid Build Coastguard Worker}
23*9880d681SAndroid Build Coastguard Worker
24*9880d681SAndroid Build Coastguard Workerdefine i32 @baz(i64 %cav1.coerce) nounwind {
25*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: baz:
26*9880d681SAndroid Build Coastguard Worker; CHECK: sbfx  w0, w0, #0, #4
27*9880d681SAndroid Build Coastguard Worker  %tmp = trunc i64 %cav1.coerce to i32
28*9880d681SAndroid Build Coastguard Worker  %tmp1 = shl i32 %tmp, 28
29*9880d681SAndroid Build Coastguard Worker  %bf.val.sext = ashr exact i32 %tmp1, 28
30*9880d681SAndroid Build Coastguard Worker  ret i32 %bf.val.sext
31*9880d681SAndroid Build Coastguard Worker}
32*9880d681SAndroid Build Coastguard Worker
33*9880d681SAndroid Build Coastguard Workerdefine i32 @bar(i64 %cav1.coerce) nounwind {
34*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: bar:
35*9880d681SAndroid Build Coastguard Worker; CHECK: sbfx  w0, w0, #4, #6
36*9880d681SAndroid Build Coastguard Worker  %tmp = trunc i64 %cav1.coerce to i32
37*9880d681SAndroid Build Coastguard Worker  %cav1.sroa.0.1.insert = shl i32 %tmp, 22
38*9880d681SAndroid Build Coastguard Worker  %tmp1 = ashr i32 %cav1.sroa.0.1.insert, 26
39*9880d681SAndroid Build Coastguard Worker  ret i32 %tmp1
40*9880d681SAndroid Build Coastguard Worker}
41*9880d681SAndroid Build Coastguard Worker
42*9880d681SAndroid Build Coastguard Workerdefine void @fct1(%struct.Z* nocapture %x, %struct.A* nocapture %y) nounwind optsize ssp {
43*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fct1:
44*9880d681SAndroid Build Coastguard Worker; CHECK: ubfx x{{[0-9]+}}, x{{[0-9]+}}
45*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: and
46*9880d681SAndroid Build Coastguard Worker; CHECK: ret
47*9880d681SAndroid Build Coastguard Worker
48*9880d681SAndroid Build Coastguard Worker  %tmp = bitcast %struct.Z* %x to i64*
49*9880d681SAndroid Build Coastguard Worker  %tmp1 = load i64, i64* %tmp, align 4
50*9880d681SAndroid Build Coastguard Worker  %b = getelementptr inbounds %struct.A, %struct.A* %y, i64 0, i32 0
51*9880d681SAndroid Build Coastguard Worker  %bf.clear = lshr i64 %tmp1, 3
52*9880d681SAndroid Build Coastguard Worker  %bf.clear.lobit = and i64 %bf.clear, 1
53*9880d681SAndroid Build Coastguard Worker  store i64 %bf.clear.lobit, i64* %b, align 8
54*9880d681SAndroid Build Coastguard Worker  ret void
55*9880d681SAndroid Build Coastguard Worker}
56*9880d681SAndroid Build Coastguard Worker
57*9880d681SAndroid Build Coastguard Workerdefine i64 @fct2(i64 %cav1.coerce) nounwind {
58*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fct2:
59*9880d681SAndroid Build Coastguard Worker; CHECK: sbfx  x0, x0, #0, #36
60*9880d681SAndroid Build Coastguard Worker  %tmp = shl i64 %cav1.coerce, 28
61*9880d681SAndroid Build Coastguard Worker  %bf.val.sext = ashr exact i64 %tmp, 28
62*9880d681SAndroid Build Coastguard Worker  ret i64 %bf.val.sext
63*9880d681SAndroid Build Coastguard Worker}
64*9880d681SAndroid Build Coastguard Worker
65*9880d681SAndroid Build Coastguard Workerdefine i64 @fct3(i64 %cav1.coerce) nounwind {
66*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fct3:
67*9880d681SAndroid Build Coastguard Worker; CHECK: sbfx  x0, x0, #4, #38
68*9880d681SAndroid Build Coastguard Worker  %cav1.sroa.0.1.insert = shl i64 %cav1.coerce, 22
69*9880d681SAndroid Build Coastguard Worker  %tmp1 = ashr i64 %cav1.sroa.0.1.insert, 26
70*9880d681SAndroid Build Coastguard Worker  ret i64 %tmp1
71*9880d681SAndroid Build Coastguard Worker}
72*9880d681SAndroid Build Coastguard Worker
73*9880d681SAndroid Build Coastguard Workerdefine void @fct4(i64* nocapture %y, i64 %x) nounwind optsize inlinehint ssp {
74*9880d681SAndroid Build Coastguard Workerentry:
75*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fct4:
76*9880d681SAndroid Build Coastguard Worker; CHECK: ldr [[REG1:x[0-9]+]],
77*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bfxil [[REG1]], x1, #16, #24
78*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: str [[REG1]],
79*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
80*9880d681SAndroid Build Coastguard Worker  %0 = load i64, i64* %y, align 8
81*9880d681SAndroid Build Coastguard Worker  %and = and i64 %0, -16777216
82*9880d681SAndroid Build Coastguard Worker  %shr = lshr i64 %x, 16
83*9880d681SAndroid Build Coastguard Worker  %and1 = and i64 %shr, 16777215
84*9880d681SAndroid Build Coastguard Worker  %or = or i64 %and, %and1
85*9880d681SAndroid Build Coastguard Worker  store i64 %or, i64* %y, align 8
86*9880d681SAndroid Build Coastguard Worker  ret void
87*9880d681SAndroid Build Coastguard Worker}
88*9880d681SAndroid Build Coastguard Worker
89*9880d681SAndroid Build Coastguard Workerdefine void @fct5(i32* nocapture %y, i32 %x) nounwind optsize inlinehint ssp {
90*9880d681SAndroid Build Coastguard Workerentry:
91*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fct5:
92*9880d681SAndroid Build Coastguard Worker; CHECK: ldr [[REG1:w[0-9]+]],
93*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bfxil [[REG1]], w1, #16, #3
94*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: str [[REG1]],
95*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
96*9880d681SAndroid Build Coastguard Worker  %0 = load i32, i32* %y, align 8
97*9880d681SAndroid Build Coastguard Worker  %and = and i32 %0, -8
98*9880d681SAndroid Build Coastguard Worker  %shr = lshr i32 %x, 16
99*9880d681SAndroid Build Coastguard Worker  %and1 = and i32 %shr, 7
100*9880d681SAndroid Build Coastguard Worker  %or = or i32 %and, %and1
101*9880d681SAndroid Build Coastguard Worker  store i32 %or, i32* %y, align 8
102*9880d681SAndroid Build Coastguard Worker  ret void
103*9880d681SAndroid Build Coastguard Worker}
104*9880d681SAndroid Build Coastguard Worker
105*9880d681SAndroid Build Coastguard Worker; Check if we can still catch bfm instruction when we drop some low bits
106*9880d681SAndroid Build Coastguard Workerdefine void @fct6(i32* nocapture %y, i32 %x) nounwind optsize inlinehint ssp {
107*9880d681SAndroid Build Coastguard Workerentry:
108*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fct6:
109*9880d681SAndroid Build Coastguard Worker; CHECK: ldr [[REG1:w[0-9]+]],
110*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bfxil [[REG1]], w1, #16, #3
111*9880d681SAndroid Build Coastguard Worker; lsr is an alias of ubfm
112*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: lsr [[REG2:w[0-9]+]], [[REG1]], #2
113*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: str [[REG2]],
114*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
115*9880d681SAndroid Build Coastguard Worker  %0 = load i32, i32* %y, align 8
116*9880d681SAndroid Build Coastguard Worker  %and = and i32 %0, -8
117*9880d681SAndroid Build Coastguard Worker  %shr = lshr i32 %x, 16
118*9880d681SAndroid Build Coastguard Worker  %and1 = and i32 %shr, 7
119*9880d681SAndroid Build Coastguard Worker  %or = or i32 %and, %and1
120*9880d681SAndroid Build Coastguard Worker  %shr1 = lshr i32 %or, 2
121*9880d681SAndroid Build Coastguard Worker  store i32 %shr1, i32* %y, align 8
122*9880d681SAndroid Build Coastguard Worker  ret void
123*9880d681SAndroid Build Coastguard Worker}
124*9880d681SAndroid Build Coastguard Worker
125*9880d681SAndroid Build Coastguard Worker
126*9880d681SAndroid Build Coastguard Worker; Check if we can still catch bfm instruction when we drop some high bits
127*9880d681SAndroid Build Coastguard Workerdefine void @fct7(i32* nocapture %y, i32 %x) nounwind optsize inlinehint ssp {
128*9880d681SAndroid Build Coastguard Workerentry:
129*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fct7:
130*9880d681SAndroid Build Coastguard Worker; CHECK: ldr [[REG1:w[0-9]+]],
131*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bfxil [[REG1]], w1, #16, #3
132*9880d681SAndroid Build Coastguard Worker; lsl is an alias of ubfm
133*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: lsl [[REG2:w[0-9]+]], [[REG1]], #2
134*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: str [[REG2]],
135*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
136*9880d681SAndroid Build Coastguard Worker  %0 = load i32, i32* %y, align 8
137*9880d681SAndroid Build Coastguard Worker  %and = and i32 %0, -8
138*9880d681SAndroid Build Coastguard Worker  %shr = lshr i32 %x, 16
139*9880d681SAndroid Build Coastguard Worker  %and1 = and i32 %shr, 7
140*9880d681SAndroid Build Coastguard Worker  %or = or i32 %and, %and1
141*9880d681SAndroid Build Coastguard Worker  %shl = shl i32 %or, 2
142*9880d681SAndroid Build Coastguard Worker  store i32 %shl, i32* %y, align 8
143*9880d681SAndroid Build Coastguard Worker  ret void
144*9880d681SAndroid Build Coastguard Worker}
145*9880d681SAndroid Build Coastguard Worker
146*9880d681SAndroid Build Coastguard Worker
147*9880d681SAndroid Build Coastguard Worker; Check if we can still catch bfm instruction when we drop some low bits
148*9880d681SAndroid Build Coastguard Worker; (i64 version)
149*9880d681SAndroid Build Coastguard Workerdefine void @fct8(i64* nocapture %y, i64 %x) nounwind optsize inlinehint ssp {
150*9880d681SAndroid Build Coastguard Workerentry:
151*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fct8:
152*9880d681SAndroid Build Coastguard Worker; CHECK: ldr [[REG1:x[0-9]+]],
153*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bfxil [[REG1]], x1, #16, #3
154*9880d681SAndroid Build Coastguard Worker; lsr is an alias of ubfm
155*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: lsr [[REG2:x[0-9]+]], [[REG1]], #2
156*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: str [[REG2]],
157*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
158*9880d681SAndroid Build Coastguard Worker  %0 = load i64, i64* %y, align 8
159*9880d681SAndroid Build Coastguard Worker  %and = and i64 %0, -8
160*9880d681SAndroid Build Coastguard Worker  %shr = lshr i64 %x, 16
161*9880d681SAndroid Build Coastguard Worker  %and1 = and i64 %shr, 7
162*9880d681SAndroid Build Coastguard Worker  %or = or i64 %and, %and1
163*9880d681SAndroid Build Coastguard Worker  %shr1 = lshr i64 %or, 2
164*9880d681SAndroid Build Coastguard Worker  store i64 %shr1, i64* %y, align 8
165*9880d681SAndroid Build Coastguard Worker  ret void
166*9880d681SAndroid Build Coastguard Worker}
167*9880d681SAndroid Build Coastguard Worker
168*9880d681SAndroid Build Coastguard Worker
169*9880d681SAndroid Build Coastguard Worker; Check if we can still catch bfm instruction when we drop some high bits
170*9880d681SAndroid Build Coastguard Worker; (i64 version)
171*9880d681SAndroid Build Coastguard Workerdefine void @fct9(i64* nocapture %y, i64 %x) nounwind optsize inlinehint ssp {
172*9880d681SAndroid Build Coastguard Workerentry:
173*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fct9:
174*9880d681SAndroid Build Coastguard Worker; CHECK: ldr [[REG1:x[0-9]+]],
175*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bfxil [[REG1]], x1, #16, #3
176*9880d681SAndroid Build Coastguard Worker; lsr is an alias of ubfm
177*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: lsl [[REG2:x[0-9]+]], [[REG1]], #2
178*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: str [[REG2]],
179*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
180*9880d681SAndroid Build Coastguard Worker  %0 = load i64, i64* %y, align 8
181*9880d681SAndroid Build Coastguard Worker  %and = and i64 %0, -8
182*9880d681SAndroid Build Coastguard Worker  %shr = lshr i64 %x, 16
183*9880d681SAndroid Build Coastguard Worker  %and1 = and i64 %shr, 7
184*9880d681SAndroid Build Coastguard Worker  %or = or i64 %and, %and1
185*9880d681SAndroid Build Coastguard Worker  %shl = shl i64 %or, 2
186*9880d681SAndroid Build Coastguard Worker  store i64 %shl, i64* %y, align 8
187*9880d681SAndroid Build Coastguard Worker  ret void
188*9880d681SAndroid Build Coastguard Worker}
189*9880d681SAndroid Build Coastguard Worker
190*9880d681SAndroid Build Coastguard Worker; Check if we can catch bfm instruction when lsb is 0 (i.e., no lshr)
191*9880d681SAndroid Build Coastguard Worker; (i32 version)
192*9880d681SAndroid Build Coastguard Workerdefine void @fct10(i32* nocapture %y, i32 %x) nounwind optsize inlinehint ssp {
193*9880d681SAndroid Build Coastguard Workerentry:
194*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fct10:
195*9880d681SAndroid Build Coastguard Worker; CHECK: ldr [[REG1:w[0-9]+]],
196*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bfxil [[REG1]], w1, #0, #3
197*9880d681SAndroid Build Coastguard Worker; lsl is an alias of ubfm
198*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: lsl [[REG2:w[0-9]+]], [[REG1]], #2
199*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: str [[REG2]],
200*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
201*9880d681SAndroid Build Coastguard Worker  %0 = load i32, i32* %y, align 8
202*9880d681SAndroid Build Coastguard Worker  %and = and i32 %0, -8
203*9880d681SAndroid Build Coastguard Worker  %and1 = and i32 %x, 7
204*9880d681SAndroid Build Coastguard Worker  %or = or i32 %and, %and1
205*9880d681SAndroid Build Coastguard Worker  %shl = shl i32 %or, 2
206*9880d681SAndroid Build Coastguard Worker  store i32 %shl, i32* %y, align 8
207*9880d681SAndroid Build Coastguard Worker  ret void
208*9880d681SAndroid Build Coastguard Worker}
209*9880d681SAndroid Build Coastguard Worker
210*9880d681SAndroid Build Coastguard Worker; Check if we can catch bfm instruction when lsb is 0 (i.e., no lshr)
211*9880d681SAndroid Build Coastguard Worker; (i64 version)
212*9880d681SAndroid Build Coastguard Workerdefine void @fct11(i64* nocapture %y, i64 %x) nounwind optsize inlinehint ssp {
213*9880d681SAndroid Build Coastguard Workerentry:
214*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fct11:
215*9880d681SAndroid Build Coastguard Worker; CHECK: ldr [[REG1:x[0-9]+]],
216*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bfxil [[REG1]], x1, #0, #3
217*9880d681SAndroid Build Coastguard Worker; lsl is an alias of ubfm
218*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: lsl [[REG2:x[0-9]+]], [[REG1]], #2
219*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: str [[REG2]],
220*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
221*9880d681SAndroid Build Coastguard Worker  %0 = load i64, i64* %y, align 8
222*9880d681SAndroid Build Coastguard Worker  %and = and i64 %0, -8
223*9880d681SAndroid Build Coastguard Worker  %and1 = and i64 %x, 7
224*9880d681SAndroid Build Coastguard Worker  %or = or i64 %and, %and1
225*9880d681SAndroid Build Coastguard Worker  %shl = shl i64 %or, 2
226*9880d681SAndroid Build Coastguard Worker  store i64 %shl, i64* %y, align 8
227*9880d681SAndroid Build Coastguard Worker  ret void
228*9880d681SAndroid Build Coastguard Worker}
229*9880d681SAndroid Build Coastguard Worker
230*9880d681SAndroid Build Coastguard Workerdefine zeroext i1 @fct12bis(i32 %tmp2) unnamed_addr nounwind ssp align 2 {
231*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fct12bis:
232*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: and
233*9880d681SAndroid Build Coastguard Worker; CHECK: ubfx w0, w0, #11, #1
234*9880d681SAndroid Build Coastguard Worker  %and.i.i = and i32 %tmp2, 2048
235*9880d681SAndroid Build Coastguard Worker  %tobool.i.i = icmp ne i32 %and.i.i, 0
236*9880d681SAndroid Build Coastguard Worker  ret i1 %tobool.i.i
237*9880d681SAndroid Build Coastguard Worker}
238*9880d681SAndroid Build Coastguard Worker
239*9880d681SAndroid Build Coastguard Worker; Check if we can still catch bfm instruction when we drop some high bits
240*9880d681SAndroid Build Coastguard Worker; and some low bits
241*9880d681SAndroid Build Coastguard Workerdefine void @fct12(i32* nocapture %y, i32 %x) nounwind optsize inlinehint ssp {
242*9880d681SAndroid Build Coastguard Workerentry:
243*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fct12:
244*9880d681SAndroid Build Coastguard Worker; CHECK: ldr [[REG1:w[0-9]+]],
245*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bfxil [[REG1]], w1, #16, #3
246*9880d681SAndroid Build Coastguard Worker; lsr is an alias of ubfm
247*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ubfx [[REG2:w[0-9]+]], [[REG1]], #2, #28
248*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: str [[REG2]],
249*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
250*9880d681SAndroid Build Coastguard Worker  %0 = load i32, i32* %y, align 8
251*9880d681SAndroid Build Coastguard Worker  %and = and i32 %0, -8
252*9880d681SAndroid Build Coastguard Worker  %shr = lshr i32 %x, 16
253*9880d681SAndroid Build Coastguard Worker  %and1 = and i32 %shr, 7
254*9880d681SAndroid Build Coastguard Worker  %or = or i32 %and, %and1
255*9880d681SAndroid Build Coastguard Worker  %shl = shl i32 %or, 2
256*9880d681SAndroid Build Coastguard Worker  %shr2 = lshr i32 %shl, 4
257*9880d681SAndroid Build Coastguard Worker  store i32 %shr2, i32* %y, align 8
258*9880d681SAndroid Build Coastguard Worker  ret void
259*9880d681SAndroid Build Coastguard Worker}
260*9880d681SAndroid Build Coastguard Worker
261*9880d681SAndroid Build Coastguard Worker; Check if we can still catch bfm instruction when we drop some high bits
262*9880d681SAndroid Build Coastguard Worker; and some low bits
263*9880d681SAndroid Build Coastguard Worker; (i64 version)
264*9880d681SAndroid Build Coastguard Workerdefine void @fct13(i64* nocapture %y, i64 %x) nounwind optsize inlinehint ssp {
265*9880d681SAndroid Build Coastguard Workerentry:
266*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fct13:
267*9880d681SAndroid Build Coastguard Worker; CHECK: ldr [[REG1:x[0-9]+]],
268*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bfxil [[REG1]], x1, #16, #3
269*9880d681SAndroid Build Coastguard Worker; lsr is an alias of ubfm
270*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ubfx [[REG2:x[0-9]+]], [[REG1]], #2, #60
271*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: str [[REG2]],
272*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
273*9880d681SAndroid Build Coastguard Worker  %0 = load i64, i64* %y, align 8
274*9880d681SAndroid Build Coastguard Worker  %and = and i64 %0, -8
275*9880d681SAndroid Build Coastguard Worker  %shr = lshr i64 %x, 16
276*9880d681SAndroid Build Coastguard Worker  %and1 = and i64 %shr, 7
277*9880d681SAndroid Build Coastguard Worker  %or = or i64 %and, %and1
278*9880d681SAndroid Build Coastguard Worker  %shl = shl i64 %or, 2
279*9880d681SAndroid Build Coastguard Worker  %shr2 = lshr i64 %shl, 4
280*9880d681SAndroid Build Coastguard Worker  store i64 %shr2, i64* %y, align 8
281*9880d681SAndroid Build Coastguard Worker  ret void
282*9880d681SAndroid Build Coastguard Worker}
283*9880d681SAndroid Build Coastguard Worker
284*9880d681SAndroid Build Coastguard Worker
285*9880d681SAndroid Build Coastguard Worker; Check if we can still catch bfm instruction when we drop some high bits
286*9880d681SAndroid Build Coastguard Worker; and some low bits
287*9880d681SAndroid Build Coastguard Workerdefine void @fct14(i32* nocapture %y, i32 %x, i32 %x1) nounwind optsize inlinehint ssp {
288*9880d681SAndroid Build Coastguard Workerentry:
289*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fct14:
290*9880d681SAndroid Build Coastguard Worker; CHECK: ldr [[REG1:w[0-9]+]],
291*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bfxil [[REG1]], w1, #16, #8
292*9880d681SAndroid Build Coastguard Worker; lsr is an alias of ubfm
293*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: lsr [[REG2:w[0-9]+]], [[REG1]], #4
294*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bfxil [[REG2]], w2, #5, #3
295*9880d681SAndroid Build Coastguard Worker; lsl is an alias of ubfm
296*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: lsl [[REG3:w[0-9]+]], [[REG2]], #2
297*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: str [[REG3]],
298*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
299*9880d681SAndroid Build Coastguard Worker  %0 = load i32, i32* %y, align 8
300*9880d681SAndroid Build Coastguard Worker  %and = and i32 %0, -256
301*9880d681SAndroid Build Coastguard Worker  %shr = lshr i32 %x, 16
302*9880d681SAndroid Build Coastguard Worker  %and1 = and i32 %shr, 255
303*9880d681SAndroid Build Coastguard Worker  %or = or i32 %and, %and1
304*9880d681SAndroid Build Coastguard Worker  %shl = lshr i32 %or, 4
305*9880d681SAndroid Build Coastguard Worker  %and2 = and i32 %shl, -8
306*9880d681SAndroid Build Coastguard Worker  %shr1 = lshr i32 %x1, 5
307*9880d681SAndroid Build Coastguard Worker  %and3 = and i32 %shr1, 7
308*9880d681SAndroid Build Coastguard Worker  %or1 = or i32 %and2, %and3
309*9880d681SAndroid Build Coastguard Worker  %shl1 = shl i32 %or1, 2
310*9880d681SAndroid Build Coastguard Worker  store i32 %shl1, i32* %y, align 8
311*9880d681SAndroid Build Coastguard Worker  ret void
312*9880d681SAndroid Build Coastguard Worker}
313*9880d681SAndroid Build Coastguard Worker
314*9880d681SAndroid Build Coastguard Worker; Check if we can still catch bfm instruction when we drop some high bits
315*9880d681SAndroid Build Coastguard Worker; and some low bits
316*9880d681SAndroid Build Coastguard Worker; (i64 version)
317*9880d681SAndroid Build Coastguard Workerdefine void @fct15(i64* nocapture %y, i64 %x, i64 %x1) nounwind optsize inlinehint ssp {
318*9880d681SAndroid Build Coastguard Workerentry:
319*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fct15:
320*9880d681SAndroid Build Coastguard Worker; CHECK: ldr [[REG1:x[0-9]+]],
321*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bfxil [[REG1]], x1, #16, #8
322*9880d681SAndroid Build Coastguard Worker; lsr is an alias of ubfm
323*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: lsr [[REG2:x[0-9]+]], [[REG1]], #4
324*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bfxil [[REG2]], x2, #5, #3
325*9880d681SAndroid Build Coastguard Worker; lsl is an alias of ubfm
326*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: lsl [[REG3:x[0-9]+]], [[REG2]], #2
327*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: str [[REG3]],
328*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
329*9880d681SAndroid Build Coastguard Worker  %0 = load i64, i64* %y, align 8
330*9880d681SAndroid Build Coastguard Worker  %and = and i64 %0, -256
331*9880d681SAndroid Build Coastguard Worker  %shr = lshr i64 %x, 16
332*9880d681SAndroid Build Coastguard Worker  %and1 = and i64 %shr, 255
333*9880d681SAndroid Build Coastguard Worker  %or = or i64 %and, %and1
334*9880d681SAndroid Build Coastguard Worker  %shl = lshr i64 %or, 4
335*9880d681SAndroid Build Coastguard Worker  %and2 = and i64 %shl, -8
336*9880d681SAndroid Build Coastguard Worker  %shr1 = lshr i64 %x1, 5
337*9880d681SAndroid Build Coastguard Worker  %and3 = and i64 %shr1, 7
338*9880d681SAndroid Build Coastguard Worker  %or1 = or i64 %and2, %and3
339*9880d681SAndroid Build Coastguard Worker  %shl1 = shl i64 %or1, 2
340*9880d681SAndroid Build Coastguard Worker  store i64 %shl1, i64* %y, align 8
341*9880d681SAndroid Build Coastguard Worker  ret void
342*9880d681SAndroid Build Coastguard Worker}
343*9880d681SAndroid Build Coastguard Worker
344*9880d681SAndroid Build Coastguard Worker; Check if we can still catch bfm instruction when we drop some high bits
345*9880d681SAndroid Build Coastguard Worker; and some low bits and a masking operation has to be kept
346*9880d681SAndroid Build Coastguard Workerdefine void @fct16(i32* nocapture %y, i32 %x) nounwind optsize inlinehint ssp {
347*9880d681SAndroid Build Coastguard Workerentry:
348*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fct16:
349*9880d681SAndroid Build Coastguard Worker; CHECK: ldr [[REG1:w[0-9]+]],
350*9880d681SAndroid Build Coastguard Worker; Create the constant
351*9880d681SAndroid Build Coastguard Worker; CHECK: mov [[REGCST:w[0-9]+]], #1703936
352*9880d681SAndroid Build Coastguard Worker; CHECK: movk [[REGCST]], #33120
353*9880d681SAndroid Build Coastguard Worker; Do the masking
354*9880d681SAndroid Build Coastguard Worker; CHECK: and [[REG2:w[0-9]+]], [[REG1]], [[REGCST]]
355*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bfxil [[REG2]], w1, #16, #3
356*9880d681SAndroid Build Coastguard Worker; lsr is an alias of ubfm
357*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ubfx [[REG3:w[0-9]+]], [[REG2]], #2, #28
358*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: str [[REG3]],
359*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
360*9880d681SAndroid Build Coastguard Worker  %0 = load i32, i32* %y, align 8
361*9880d681SAndroid Build Coastguard Worker  %and = and i32 %0, 1737056
362*9880d681SAndroid Build Coastguard Worker  %shr = lshr i32 %x, 16
363*9880d681SAndroid Build Coastguard Worker  %and1 = and i32 %shr, 7
364*9880d681SAndroid Build Coastguard Worker  %or = or i32 %and, %and1
365*9880d681SAndroid Build Coastguard Worker  %shl = shl i32 %or, 2
366*9880d681SAndroid Build Coastguard Worker  %shr2 = lshr i32 %shl, 4
367*9880d681SAndroid Build Coastguard Worker  store i32 %shr2, i32* %y, align 8
368*9880d681SAndroid Build Coastguard Worker  ret void
369*9880d681SAndroid Build Coastguard Worker}
370*9880d681SAndroid Build Coastguard Worker
371*9880d681SAndroid Build Coastguard Worker
372*9880d681SAndroid Build Coastguard Worker; Check if we can still catch bfm instruction when we drop some high bits
373*9880d681SAndroid Build Coastguard Worker; and some low bits and a masking operation has to be kept
374*9880d681SAndroid Build Coastguard Worker; (i64 version)
375*9880d681SAndroid Build Coastguard Workerdefine void @fct17(i64* nocapture %y, i64 %x) nounwind optsize inlinehint ssp {
376*9880d681SAndroid Build Coastguard Workerentry:
377*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fct17:
378*9880d681SAndroid Build Coastguard Worker; CHECK: ldr [[REG1:x[0-9]+]],
379*9880d681SAndroid Build Coastguard Worker; Create the constant
380*9880d681SAndroid Build Coastguard Worker; CHECK: mov w[[REGCST:[0-9]+]], #1703936
381*9880d681SAndroid Build Coastguard Worker; CHECK: movk w[[REGCST]], #33120
382*9880d681SAndroid Build Coastguard Worker; Do the masking
383*9880d681SAndroid Build Coastguard Worker; CHECK: and [[REG2:x[0-9]+]], [[REG1]], x[[REGCST]]
384*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bfxil [[REG2]], x1, #16, #3
385*9880d681SAndroid Build Coastguard Worker; lsr is an alias of ubfm
386*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ubfx [[REG3:x[0-9]+]], [[REG2]], #2, #60
387*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: str [[REG3]],
388*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
389*9880d681SAndroid Build Coastguard Worker  %0 = load i64, i64* %y, align 8
390*9880d681SAndroid Build Coastguard Worker  %and = and i64 %0, 1737056
391*9880d681SAndroid Build Coastguard Worker  %shr = lshr i64 %x, 16
392*9880d681SAndroid Build Coastguard Worker  %and1 = and i64 %shr, 7
393*9880d681SAndroid Build Coastguard Worker  %or = or i64 %and, %and1
394*9880d681SAndroid Build Coastguard Worker  %shl = shl i64 %or, 2
395*9880d681SAndroid Build Coastguard Worker  %shr2 = lshr i64 %shl, 4
396*9880d681SAndroid Build Coastguard Worker  store i64 %shr2, i64* %y, align 8
397*9880d681SAndroid Build Coastguard Worker  ret void
398*9880d681SAndroid Build Coastguard Worker}
399*9880d681SAndroid Build Coastguard Worker
400*9880d681SAndroid Build Coastguard Workerdefine i64 @fct18(i32 %xor72) nounwind ssp {
401*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fct18:
402*9880d681SAndroid Build Coastguard Worker; CHECK: ubfx x0, x0, #9, #8
403*9880d681SAndroid Build Coastguard Worker  %shr81 = lshr i32 %xor72, 9
404*9880d681SAndroid Build Coastguard Worker  %conv82 = zext i32 %shr81 to i64
405*9880d681SAndroid Build Coastguard Worker  %result = and i64 %conv82, 255
406*9880d681SAndroid Build Coastguard Worker  ret i64 %result
407*9880d681SAndroid Build Coastguard Worker}
408*9880d681SAndroid Build Coastguard Worker
409*9880d681SAndroid Build Coastguard Worker; Using the access to the global array to keep the instruction and control flow.
410*9880d681SAndroid Build Coastguard Worker@first_ones = external global [65536 x i8]
411*9880d681SAndroid Build Coastguard Worker
412*9880d681SAndroid Build Coastguard Worker; Function Attrs: nounwind readonly ssp
413*9880d681SAndroid Build Coastguard Workerdefine i32 @fct19(i64 %arg1) nounwind readonly ssp  {
414*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fct19:
415*9880d681SAndroid Build Coastguard Workerentry:
416*9880d681SAndroid Build Coastguard Worker  %x.sroa.1.0.extract.shift = lshr i64 %arg1, 16
417*9880d681SAndroid Build Coastguard Worker  %x.sroa.1.0.extract.trunc = trunc i64 %x.sroa.1.0.extract.shift to i16
418*9880d681SAndroid Build Coastguard Worker  %x.sroa.3.0.extract.shift = lshr i64 %arg1, 32
419*9880d681SAndroid Build Coastguard Worker  %x.sroa.5.0.extract.shift = lshr i64 %arg1, 48
420*9880d681SAndroid Build Coastguard Worker  %tobool = icmp eq i64 %x.sroa.5.0.extract.shift, 0
421*9880d681SAndroid Build Coastguard Worker  br i1 %tobool, label %if.end, label %if.then
422*9880d681SAndroid Build Coastguard Worker
423*9880d681SAndroid Build Coastguard Workerif.then:                                          ; preds = %entry
424*9880d681SAndroid Build Coastguard Worker  %arrayidx3 = getelementptr inbounds [65536 x i8], [65536 x i8]* @first_ones, i64 0, i64 %x.sroa.5.0.extract.shift
425*9880d681SAndroid Build Coastguard Worker  %0 = load i8, i8* %arrayidx3, align 1
426*9880d681SAndroid Build Coastguard Worker  %conv = zext i8 %0 to i32
427*9880d681SAndroid Build Coastguard Worker  br label %return
428*9880d681SAndroid Build Coastguard Worker
429*9880d681SAndroid Build Coastguard Worker; OPT-LABEL: if.end
430*9880d681SAndroid Build Coastguard Workerif.end:                                           ; preds = %entry
431*9880d681SAndroid Build Coastguard Worker; OPT: lshr
432*9880d681SAndroid Build Coastguard Worker; CHECK: ubfx	[[REG1:x[0-9]+]], [[REG2:x[0-9]+]], #32, #16
433*9880d681SAndroid Build Coastguard Worker  %x.sroa.3.0.extract.trunc = trunc i64 %x.sroa.3.0.extract.shift to i16
434*9880d681SAndroid Build Coastguard Worker  %tobool6 = icmp eq i16 %x.sroa.3.0.extract.trunc, 0
435*9880d681SAndroid Build Coastguard Worker; CHECK: cbz
436*9880d681SAndroid Build Coastguard Worker  br i1 %tobool6, label %if.end13, label %if.then7
437*9880d681SAndroid Build Coastguard Worker
438*9880d681SAndroid Build Coastguard Worker; OPT-LABEL: if.then7
439*9880d681SAndroid Build Coastguard Workerif.then7:                                         ; preds = %if.end
440*9880d681SAndroid Build Coastguard Worker; OPT: lshr
441*9880d681SAndroid Build Coastguard Worker; "and" should be combined to "ubfm" while "ubfm" should be removed by cse.
442*9880d681SAndroid Build Coastguard Worker; So neither of them should be in the assemble code.
443*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: and
444*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: ubfm
445*9880d681SAndroid Build Coastguard Worker  %idxprom10 = and i64 %x.sroa.3.0.extract.shift, 65535
446*9880d681SAndroid Build Coastguard Worker  %arrayidx11 = getelementptr inbounds [65536 x i8], [65536 x i8]* @first_ones, i64 0, i64 %idxprom10
447*9880d681SAndroid Build Coastguard Worker  %1 = load i8, i8* %arrayidx11, align 1
448*9880d681SAndroid Build Coastguard Worker  %conv12 = zext i8 %1 to i32
449*9880d681SAndroid Build Coastguard Worker  %add = add nsw i32 %conv12, 16
450*9880d681SAndroid Build Coastguard Worker  br label %return
451*9880d681SAndroid Build Coastguard Worker
452*9880d681SAndroid Build Coastguard Worker; OPT-LABEL: if.end13
453*9880d681SAndroid Build Coastguard Workerif.end13:                                         ; preds = %if.end
454*9880d681SAndroid Build Coastguard Worker; OPT: lshr
455*9880d681SAndroid Build Coastguard Worker; OPT: trunc
456*9880d681SAndroid Build Coastguard Worker; CHECK: ubfx	[[REG3:x[0-9]+]], [[REG4:x[0-9]+]], #16, #16
457*9880d681SAndroid Build Coastguard Worker  %tobool16 = icmp eq i16 %x.sroa.1.0.extract.trunc, 0
458*9880d681SAndroid Build Coastguard Worker; CHECK: cbz
459*9880d681SAndroid Build Coastguard Worker  br i1 %tobool16, label %return, label %if.then17
460*9880d681SAndroid Build Coastguard Worker
461*9880d681SAndroid Build Coastguard Worker; OPT-LABEL: if.then17
462*9880d681SAndroid Build Coastguard Workerif.then17:                                        ; preds = %if.end13
463*9880d681SAndroid Build Coastguard Worker; OPT: lshr
464*9880d681SAndroid Build Coastguard Worker; "and" should be combined to "ubfm" while "ubfm" should be removed by cse.
465*9880d681SAndroid Build Coastguard Worker; So neither of them should be in the assemble code.
466*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: and
467*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: ubfm
468*9880d681SAndroid Build Coastguard Worker  %idxprom20 = and i64 %x.sroa.1.0.extract.shift, 65535
469*9880d681SAndroid Build Coastguard Worker  %arrayidx21 = getelementptr inbounds [65536 x i8], [65536 x i8]* @first_ones, i64 0, i64 %idxprom20
470*9880d681SAndroid Build Coastguard Worker  %2 = load i8, i8* %arrayidx21, align 1
471*9880d681SAndroid Build Coastguard Worker  %conv22 = zext i8 %2 to i32
472*9880d681SAndroid Build Coastguard Worker  %add23 = add nsw i32 %conv22, 32
473*9880d681SAndroid Build Coastguard Worker  br label %return
474*9880d681SAndroid Build Coastguard Worker
475*9880d681SAndroid Build Coastguard Workerreturn:                                           ; preds = %if.end13, %if.then17, %if.then7, %if.then
476*9880d681SAndroid Build Coastguard Worker; CHECK: ret
477*9880d681SAndroid Build Coastguard Worker  %retval.0 = phi i32 [ %conv, %if.then ], [ %add, %if.then7 ], [ %add23, %if.then17 ], [ 64, %if.end13 ]
478*9880d681SAndroid Build Coastguard Worker  ret i32 %retval.0
479*9880d681SAndroid Build Coastguard Worker}
480*9880d681SAndroid Build Coastguard Worker
481*9880d681SAndroid Build Coastguard Worker; Make sure we do not assert if the immediate in and is bigger than i64.
482*9880d681SAndroid Build Coastguard Worker; PR19503.
483*9880d681SAndroid Build Coastguard Worker; OPT-LABEL: @fct20
484*9880d681SAndroid Build Coastguard Worker; OPT: lshr
485*9880d681SAndroid Build Coastguard Worker; OPT-NOT: lshr
486*9880d681SAndroid Build Coastguard Worker; OPT: ret
487*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fct20:
488*9880d681SAndroid Build Coastguard Worker; CHECK: ret
489*9880d681SAndroid Build Coastguard Workerdefine i80 @fct20(i128 %a, i128 %b) {
490*9880d681SAndroid Build Coastguard Workerentry:
491*9880d681SAndroid Build Coastguard Worker  %shr = lshr i128 %a, 18
492*9880d681SAndroid Build Coastguard Worker  %conv = trunc i128 %shr to i80
493*9880d681SAndroid Build Coastguard Worker  %tobool = icmp eq i128 %b, 0
494*9880d681SAndroid Build Coastguard Worker  br i1 %tobool, label %then, label %end
495*9880d681SAndroid Build Coastguard Workerthen:
496*9880d681SAndroid Build Coastguard Worker  %and = and i128 %shr, 483673642326615442599424
497*9880d681SAndroid Build Coastguard Worker  %conv2 = trunc i128 %and to i80
498*9880d681SAndroid Build Coastguard Worker  br label %end
499*9880d681SAndroid Build Coastguard Workerend:
500*9880d681SAndroid Build Coastguard Worker  %conv3 = phi i80 [%conv, %entry], [%conv2, %then]
501*9880d681SAndroid Build Coastguard Worker  ret i80 %conv3
502*9880d681SAndroid Build Coastguard Worker}
503*9880d681SAndroid Build Coastguard Worker
504*9880d681SAndroid Build Coastguard Worker; Check if we can still catch UBFX when "AND" is used by SHL.
505*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fct21:
506*9880d681SAndroid Build Coastguard Worker; CHECK: ubfx
507*9880d681SAndroid Build Coastguard Worker@arr = external global [8 x [64 x i64]]
508*9880d681SAndroid Build Coastguard Workerdefine i64 @fct21(i64 %x) {
509*9880d681SAndroid Build Coastguard Workerentry:
510*9880d681SAndroid Build Coastguard Worker  %shr = lshr i64 %x, 4
511*9880d681SAndroid Build Coastguard Worker  %and = and i64 %shr, 15
512*9880d681SAndroid Build Coastguard Worker  %arrayidx = getelementptr inbounds [8 x [64 x i64]], [8 x [64 x i64]]* @arr, i64 0, i64 0, i64 %and
513*9880d681SAndroid Build Coastguard Worker  %0 = load i64, i64* %arrayidx, align 8
514*9880d681SAndroid Build Coastguard Worker  ret i64 %0
515*9880d681SAndroid Build Coastguard Worker}
516*9880d681SAndroid Build Coastguard Worker
517*9880d681SAndroid Build Coastguard Workerdefine i16 @test_ignored_rightbits(i32 %dst, i32 %in) {
518*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_ignored_rightbits:
519*9880d681SAndroid Build Coastguard Worker
520*9880d681SAndroid Build Coastguard Worker  %positioned_field = shl i32 %in, 3
521*9880d681SAndroid Build Coastguard Worker  %positioned_masked_field = and i32 %positioned_field, 120
522*9880d681SAndroid Build Coastguard Worker  %masked_dst = and i32 %dst, 7
523*9880d681SAndroid Build Coastguard Worker  %insertion = or i32 %masked_dst, %positioned_masked_field
524*9880d681SAndroid Build Coastguard Worker; CHECK: {{bfm|bfi|bfxil}}
525*9880d681SAndroid Build Coastguard Worker
526*9880d681SAndroid Build Coastguard Worker  %shl16 = shl i32 %insertion, 8
527*9880d681SAndroid Build Coastguard Worker  %or18 = or i32 %shl16, %insertion
528*9880d681SAndroid Build Coastguard Worker  %conv19 = trunc i32 %or18 to i16
529*9880d681SAndroid Build Coastguard Worker; CHECK: bfi {{w[0-9]+}}, {{w[0-9]+}}, #8, #7
530*9880d681SAndroid Build Coastguard Worker
531*9880d681SAndroid Build Coastguard Worker  ret i16 %conv19
532*9880d681SAndroid Build Coastguard Worker}
533