xref: /aosp_15_r20/external/llvm/test/CodeGen/AArch64/bitfield.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s
2*9880d681SAndroid Build Coastguard Worker
3*9880d681SAndroid Build Coastguard Worker@var32 = global i32 0
4*9880d681SAndroid Build Coastguard Worker@var64 = global i64 0
5*9880d681SAndroid Build Coastguard Worker
6*9880d681SAndroid Build Coastguard Workerdefine void @test_extendb32(i8 %var) {
7*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_extendb32:
8*9880d681SAndroid Build Coastguard Worker
9*9880d681SAndroid Build Coastguard Worker  %sxt32 = sext i8 %var to i32
10*9880d681SAndroid Build Coastguard Worker  store volatile i32 %sxt32, i32* @var32
11*9880d681SAndroid Build Coastguard Worker; CHECK: sxtb {{w[0-9]+}}, {{w[0-9]+}}
12*9880d681SAndroid Build Coastguard Worker
13*9880d681SAndroid Build Coastguard Worker; N.b. this doesn't actually produce a bitfield instruction at the
14*9880d681SAndroid Build Coastguard Worker; moment, but it's still a good test to have and the semantics are
15*9880d681SAndroid Build Coastguard Worker; correct.
16*9880d681SAndroid Build Coastguard Worker  %uxt32 = zext i8 %var to i32
17*9880d681SAndroid Build Coastguard Worker  store volatile i32 %uxt32, i32* @var32
18*9880d681SAndroid Build Coastguard Worker; CHECK: and {{w[0-9]+}}, {{w[0-9]+}}, #0xff
19*9880d681SAndroid Build Coastguard Worker  ret void
20*9880d681SAndroid Build Coastguard Worker}
21*9880d681SAndroid Build Coastguard Worker
22*9880d681SAndroid Build Coastguard Workerdefine void @test_extendb64(i8 %var) {
23*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_extendb64:
24*9880d681SAndroid Build Coastguard Worker
25*9880d681SAndroid Build Coastguard Worker  %sxt64 = sext i8 %var to i64
26*9880d681SAndroid Build Coastguard Worker  store volatile i64 %sxt64, i64* @var64
27*9880d681SAndroid Build Coastguard Worker; CHECK: sxtb {{x[0-9]+}}, {{w[0-9]+}}
28*9880d681SAndroid Build Coastguard Worker
29*9880d681SAndroid Build Coastguard Worker; N.b. this doesn't actually produce a bitfield instruction at the
30*9880d681SAndroid Build Coastguard Worker; moment, but it's still a good test to have and the semantics are
31*9880d681SAndroid Build Coastguard Worker; correct.
32*9880d681SAndroid Build Coastguard Worker  %uxt64 = zext i8 %var to i64
33*9880d681SAndroid Build Coastguard Worker  store volatile i64 %uxt64, i64* @var64
34*9880d681SAndroid Build Coastguard Worker; CHECK: and {{w[0-9]+}}, {{w[0-9]+}}, #0xff
35*9880d681SAndroid Build Coastguard Worker  ret void
36*9880d681SAndroid Build Coastguard Worker}
37*9880d681SAndroid Build Coastguard Worker
38*9880d681SAndroid Build Coastguard Workerdefine void @test_extendh32(i16 %var) {
39*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_extendh32:
40*9880d681SAndroid Build Coastguard Worker
41*9880d681SAndroid Build Coastguard Worker  %sxt32 = sext i16 %var to i32
42*9880d681SAndroid Build Coastguard Worker  store volatile i32 %sxt32, i32* @var32
43*9880d681SAndroid Build Coastguard Worker; CHECK: sxth {{w[0-9]+}}, {{w[0-9]+}}
44*9880d681SAndroid Build Coastguard Worker
45*9880d681SAndroid Build Coastguard Worker; N.b. this doesn't actually produce a bitfield instruction at the
46*9880d681SAndroid Build Coastguard Worker; moment, but it's still a good test to have and the semantics are
47*9880d681SAndroid Build Coastguard Worker; correct.
48*9880d681SAndroid Build Coastguard Worker  %uxt32 = zext i16 %var to i32
49*9880d681SAndroid Build Coastguard Worker  store volatile i32 %uxt32, i32* @var32
50*9880d681SAndroid Build Coastguard Worker; CHECK: and {{w[0-9]+}}, {{w[0-9]+}}, #0xffff
51*9880d681SAndroid Build Coastguard Worker  ret void
52*9880d681SAndroid Build Coastguard Worker}
53*9880d681SAndroid Build Coastguard Worker
54*9880d681SAndroid Build Coastguard Workerdefine void @test_extendh64(i16 %var) {
55*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_extendh64:
56*9880d681SAndroid Build Coastguard Worker
57*9880d681SAndroid Build Coastguard Worker  %sxt64 = sext i16 %var to i64
58*9880d681SAndroid Build Coastguard Worker  store volatile i64 %sxt64, i64* @var64
59*9880d681SAndroid Build Coastguard Worker; CHECK: sxth {{x[0-9]+}}, {{w[0-9]+}}
60*9880d681SAndroid Build Coastguard Worker
61*9880d681SAndroid Build Coastguard Worker; N.b. this doesn't actually produce a bitfield instruction at the
62*9880d681SAndroid Build Coastguard Worker; moment, but it's still a good test to have and the semantics are
63*9880d681SAndroid Build Coastguard Worker; correct.
64*9880d681SAndroid Build Coastguard Worker  %uxt64 = zext i16 %var to i64
65*9880d681SAndroid Build Coastguard Worker  store volatile i64 %uxt64, i64* @var64
66*9880d681SAndroid Build Coastguard Worker; CHECK: and {{w[0-9]+}}, {{w[0-9]+}}, #0xffff
67*9880d681SAndroid Build Coastguard Worker  ret void
68*9880d681SAndroid Build Coastguard Worker}
69*9880d681SAndroid Build Coastguard Worker
70*9880d681SAndroid Build Coastguard Workerdefine void @test_extendw(i32 %var) {
71*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_extendw:
72*9880d681SAndroid Build Coastguard Worker
73*9880d681SAndroid Build Coastguard Worker  %sxt64 = sext i32 %var to i64
74*9880d681SAndroid Build Coastguard Worker  store volatile i64 %sxt64, i64* @var64
75*9880d681SAndroid Build Coastguard Worker; CHECK: sxtw {{x[0-9]+}}, {{w[0-9]+}}
76*9880d681SAndroid Build Coastguard Worker
77*9880d681SAndroid Build Coastguard Worker  %uxt64 = zext i32 %var to i64
78*9880d681SAndroid Build Coastguard Worker  store volatile i64 %uxt64, i64* @var64
79*9880d681SAndroid Build Coastguard Worker; CHECK: mov {{w[0-9]+}}, w0
80*9880d681SAndroid Build Coastguard Worker  ret void
81*9880d681SAndroid Build Coastguard Worker}
82*9880d681SAndroid Build Coastguard Worker
83*9880d681SAndroid Build Coastguard Workerdefine void @test_shifts(i32 %val32, i64 %val64) {
84*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_shifts:
85*9880d681SAndroid Build Coastguard Worker
86*9880d681SAndroid Build Coastguard Worker  %shift1 = ashr i32 %val32, 31
87*9880d681SAndroid Build Coastguard Worker  store volatile i32 %shift1, i32* @var32
88*9880d681SAndroid Build Coastguard Worker; CHECK: asr {{w[0-9]+}}, {{w[0-9]+}}, #31
89*9880d681SAndroid Build Coastguard Worker
90*9880d681SAndroid Build Coastguard Worker  %shift2 = lshr i32 %val32, 8
91*9880d681SAndroid Build Coastguard Worker  store volatile i32 %shift2, i32* @var32
92*9880d681SAndroid Build Coastguard Worker; CHECK: lsr {{w[0-9]+}}, {{w[0-9]+}}, #8
93*9880d681SAndroid Build Coastguard Worker
94*9880d681SAndroid Build Coastguard Worker  %shift3 = shl i32 %val32, 1
95*9880d681SAndroid Build Coastguard Worker  store volatile i32 %shift3, i32* @var32
96*9880d681SAndroid Build Coastguard Worker; CHECK: lsl {{w[0-9]+}}, {{w[0-9]+}}, #1
97*9880d681SAndroid Build Coastguard Worker
98*9880d681SAndroid Build Coastguard Worker  %shift4 = ashr i64 %val64, 31
99*9880d681SAndroid Build Coastguard Worker  store volatile i64 %shift4, i64* @var64
100*9880d681SAndroid Build Coastguard Worker; CHECK: asr {{x[0-9]+}}, {{x[0-9]+}}, #31
101*9880d681SAndroid Build Coastguard Worker
102*9880d681SAndroid Build Coastguard Worker  %shift5 = lshr i64 %val64, 8
103*9880d681SAndroid Build Coastguard Worker  store volatile i64 %shift5, i64* @var64
104*9880d681SAndroid Build Coastguard Worker; CHECK: lsr {{x[0-9]+}}, {{x[0-9]+}}, #8
105*9880d681SAndroid Build Coastguard Worker
106*9880d681SAndroid Build Coastguard Worker  %shift6 = shl i64 %val64, 63
107*9880d681SAndroid Build Coastguard Worker  store volatile i64 %shift6, i64* @var64
108*9880d681SAndroid Build Coastguard Worker; CHECK: lsl {{x[0-9]+}}, {{x[0-9]+}}, #63
109*9880d681SAndroid Build Coastguard Worker
110*9880d681SAndroid Build Coastguard Worker  %shift7 = ashr i64 %val64, 63
111*9880d681SAndroid Build Coastguard Worker  store volatile i64 %shift7, i64* @var64
112*9880d681SAndroid Build Coastguard Worker; CHECK: asr {{x[0-9]+}}, {{x[0-9]+}}, #63
113*9880d681SAndroid Build Coastguard Worker
114*9880d681SAndroid Build Coastguard Worker  %shift8 = lshr i64 %val64, 63
115*9880d681SAndroid Build Coastguard Worker  store volatile i64 %shift8, i64* @var64
116*9880d681SAndroid Build Coastguard Worker; CHECK: lsr {{x[0-9]+}}, {{x[0-9]+}}, #63
117*9880d681SAndroid Build Coastguard Worker
118*9880d681SAndroid Build Coastguard Worker  %shift9 = lshr i32 %val32, 31
119*9880d681SAndroid Build Coastguard Worker  store volatile i32 %shift9, i32* @var32
120*9880d681SAndroid Build Coastguard Worker; CHECK: lsr {{w[0-9]+}}, {{w[0-9]+}}, #31
121*9880d681SAndroid Build Coastguard Worker
122*9880d681SAndroid Build Coastguard Worker  %shift10 = shl i32 %val32, 31
123*9880d681SAndroid Build Coastguard Worker  store volatile i32 %shift10, i32* @var32
124*9880d681SAndroid Build Coastguard Worker; CHECK: lsl {{w[0-9]+}}, {{w[0-9]+}}, #31
125*9880d681SAndroid Build Coastguard Worker
126*9880d681SAndroid Build Coastguard Worker  ret void
127*9880d681SAndroid Build Coastguard Worker}
128*9880d681SAndroid Build Coastguard Worker
129*9880d681SAndroid Build Coastguard Worker; LLVM can produce in-register extensions taking place entirely with
130*9880d681SAndroid Build Coastguard Worker; 64-bit registers too.
131*9880d681SAndroid Build Coastguard Workerdefine void @test_sext_inreg_64(i64 %in) {
132*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_sext_inreg_64:
133*9880d681SAndroid Build Coastguard Worker
134*9880d681SAndroid Build Coastguard Worker; i1 doesn't have an official alias, but crops up and is handled by
135*9880d681SAndroid Build Coastguard Worker; the bitfield ops.
136*9880d681SAndroid Build Coastguard Worker  %trunc_i1 = trunc i64 %in to i1
137*9880d681SAndroid Build Coastguard Worker  %sext_i1 = sext i1 %trunc_i1 to i64
138*9880d681SAndroid Build Coastguard Worker  store volatile i64 %sext_i1, i64* @var64
139*9880d681SAndroid Build Coastguard Worker; CHECK: sbfx {{x[0-9]+}}, {{x[0-9]+}}, #0, #1
140*9880d681SAndroid Build Coastguard Worker
141*9880d681SAndroid Build Coastguard Worker  %trunc_i8 = trunc i64 %in to i8
142*9880d681SAndroid Build Coastguard Worker  %sext_i8 = sext i8 %trunc_i8 to i64
143*9880d681SAndroid Build Coastguard Worker  store volatile i64 %sext_i8, i64* @var64
144*9880d681SAndroid Build Coastguard Worker; CHECK: sxtb {{x[0-9]+}}, {{w[0-9]+}}
145*9880d681SAndroid Build Coastguard Worker
146*9880d681SAndroid Build Coastguard Worker  %trunc_i16 = trunc i64 %in to i16
147*9880d681SAndroid Build Coastguard Worker  %sext_i16 = sext i16 %trunc_i16 to i64
148*9880d681SAndroid Build Coastguard Worker  store volatile i64 %sext_i16, i64* @var64
149*9880d681SAndroid Build Coastguard Worker; CHECK: sxth {{x[0-9]+}}, {{w[0-9]+}}
150*9880d681SAndroid Build Coastguard Worker
151*9880d681SAndroid Build Coastguard Worker  %trunc_i32 = trunc i64 %in to i32
152*9880d681SAndroid Build Coastguard Worker  %sext_i32 = sext i32 %trunc_i32 to i64
153*9880d681SAndroid Build Coastguard Worker  store volatile i64 %sext_i32, i64* @var64
154*9880d681SAndroid Build Coastguard Worker; CHECK: sxtw {{x[0-9]+}}, {{w[0-9]+}}
155*9880d681SAndroid Build Coastguard Worker  ret void
156*9880d681SAndroid Build Coastguard Worker}
157*9880d681SAndroid Build Coastguard Worker
158*9880d681SAndroid Build Coastguard Worker; These instructions don't actually select to official bitfield
159*9880d681SAndroid Build Coastguard Worker; operations, but it's important that we select them somehow:
160*9880d681SAndroid Build Coastguard Workerdefine void @test_zext_inreg_64(i64 %in) {
161*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_zext_inreg_64:
162*9880d681SAndroid Build Coastguard Worker
163*9880d681SAndroid Build Coastguard Worker  %trunc_i8 = trunc i64 %in to i8
164*9880d681SAndroid Build Coastguard Worker  %zext_i8 = zext i8 %trunc_i8 to i64
165*9880d681SAndroid Build Coastguard Worker  store volatile i64 %zext_i8, i64* @var64
166*9880d681SAndroid Build Coastguard Worker; CHECK: and {{x[0-9]+}}, {{x[0-9]+}}, #0xff
167*9880d681SAndroid Build Coastguard Worker
168*9880d681SAndroid Build Coastguard Worker  %trunc_i16 = trunc i64 %in to i16
169*9880d681SAndroid Build Coastguard Worker  %zext_i16 = zext i16 %trunc_i16 to i64
170*9880d681SAndroid Build Coastguard Worker  store volatile i64 %zext_i16, i64* @var64
171*9880d681SAndroid Build Coastguard Worker; CHECK: and {{x[0-9]+}}, {{x[0-9]+}}, #0xffff
172*9880d681SAndroid Build Coastguard Worker
173*9880d681SAndroid Build Coastguard Worker  %trunc_i32 = trunc i64 %in to i32
174*9880d681SAndroid Build Coastguard Worker  %zext_i32 = zext i32 %trunc_i32 to i64
175*9880d681SAndroid Build Coastguard Worker  store volatile i64 %zext_i32, i64* @var64
176*9880d681SAndroid Build Coastguard Worker; CHECK: and {{x[0-9]+}}, {{x[0-9]+}}, #0xffffffff
177*9880d681SAndroid Build Coastguard Worker
178*9880d681SAndroid Build Coastguard Worker  ret void
179*9880d681SAndroid Build Coastguard Worker}
180*9880d681SAndroid Build Coastguard Worker
181*9880d681SAndroid Build Coastguard Workerdefine i64 @test_sext_inreg_from_32(i32 %in) {
182*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_sext_inreg_from_32:
183*9880d681SAndroid Build Coastguard Worker
184*9880d681SAndroid Build Coastguard Worker  %small = trunc i32 %in to i1
185*9880d681SAndroid Build Coastguard Worker  %ext = sext i1 %small to i64
186*9880d681SAndroid Build Coastguard Worker
187*9880d681SAndroid Build Coastguard Worker  ; Different registers are of course, possible, though suboptimal. This is
188*9880d681SAndroid Build Coastguard Worker  ; making sure that a 64-bit "(sext_inreg (anyext GPR32), i1)" uses the 64-bit
189*9880d681SAndroid Build Coastguard Worker  ; sbfx rather than just 32-bits.
190*9880d681SAndroid Build Coastguard Worker; CHECK: sbfx x0, x0, #0, #1
191*9880d681SAndroid Build Coastguard Worker  ret i64 %ext
192*9880d681SAndroid Build Coastguard Worker}
193*9880d681SAndroid Build Coastguard Worker
194*9880d681SAndroid Build Coastguard Worker
195*9880d681SAndroid Build Coastguard Workerdefine i32 @test_ubfx32(i32* %addr) {
196*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_ubfx32:
197*9880d681SAndroid Build Coastguard Worker; CHECK: ubfx {{w[0-9]+}}, {{w[0-9]+}}, #23, #3
198*9880d681SAndroid Build Coastguard Worker
199*9880d681SAndroid Build Coastguard Worker   %fields = load i32, i32* %addr
200*9880d681SAndroid Build Coastguard Worker   %shifted = lshr i32 %fields, 23
201*9880d681SAndroid Build Coastguard Worker   %masked = and i32 %shifted, 7
202*9880d681SAndroid Build Coastguard Worker   ret i32 %masked
203*9880d681SAndroid Build Coastguard Worker}
204*9880d681SAndroid Build Coastguard Worker
205*9880d681SAndroid Build Coastguard Workerdefine i64 @test_ubfx64(i64* %addr) {
206*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_ubfx64:
207*9880d681SAndroid Build Coastguard Worker; CHECK: ubfx {{x[0-9]+}}, {{x[0-9]+}}, #25, #10
208*9880d681SAndroid Build Coastguard Worker   %fields = load i64, i64* %addr
209*9880d681SAndroid Build Coastguard Worker   %shifted = lshr i64 %fields, 25
210*9880d681SAndroid Build Coastguard Worker   %masked = and i64 %shifted, 1023
211*9880d681SAndroid Build Coastguard Worker   ret i64 %masked
212*9880d681SAndroid Build Coastguard Worker}
213*9880d681SAndroid Build Coastguard Worker
214*9880d681SAndroid Build Coastguard Workerdefine i32 @test_sbfx32(i32* %addr) {
215*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_sbfx32:
216*9880d681SAndroid Build Coastguard Worker; CHECK: sbfx {{w[0-9]+}}, {{w[0-9]+}}, #6, #3
217*9880d681SAndroid Build Coastguard Worker
218*9880d681SAndroid Build Coastguard Worker   %fields = load i32, i32* %addr
219*9880d681SAndroid Build Coastguard Worker   %shifted = shl i32 %fields, 23
220*9880d681SAndroid Build Coastguard Worker   %extended = ashr i32 %shifted, 29
221*9880d681SAndroid Build Coastguard Worker   ret i32 %extended
222*9880d681SAndroid Build Coastguard Worker}
223*9880d681SAndroid Build Coastguard Worker
224*9880d681SAndroid Build Coastguard Workerdefine i64 @test_sbfx64(i64* %addr) {
225*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_sbfx64:
226*9880d681SAndroid Build Coastguard Worker; CHECK: sbfx {{x[0-9]+}}, {{x[0-9]+}}, #0, #63
227*9880d681SAndroid Build Coastguard Worker
228*9880d681SAndroid Build Coastguard Worker   %fields = load i64, i64* %addr
229*9880d681SAndroid Build Coastguard Worker   %shifted = shl i64 %fields, 1
230*9880d681SAndroid Build Coastguard Worker   %extended = ashr i64 %shifted, 1
231*9880d681SAndroid Build Coastguard Worker   ret i64 %extended
232*9880d681SAndroid Build Coastguard Worker}
233