xref: /aosp_15_r20/external/llvm/test/CodeGen/AArch64/ldst-unscaledimm.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: llc -verify-machineinstrs -o - %s -mtriple=aarch64-linux-gnu | FileCheck %s
2*9880d681SAndroid Build Coastguard Worker; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -mattr=-fp-armv8 | FileCheck --check-prefix=CHECK-NOFP %s
3*9880d681SAndroid Build Coastguard Worker
4*9880d681SAndroid Build Coastguard Worker@var_8bit = global i8 0
5*9880d681SAndroid Build Coastguard Worker@var_16bit = global i16 0
6*9880d681SAndroid Build Coastguard Worker@var_32bit = global i32 0
7*9880d681SAndroid Build Coastguard Worker@var_64bit = global i64 0
8*9880d681SAndroid Build Coastguard Worker
9*9880d681SAndroid Build Coastguard Worker@var_float = global float 0.0
10*9880d681SAndroid Build Coastguard Worker@var_double = global double 0.0
11*9880d681SAndroid Build Coastguard Worker
12*9880d681SAndroid Build Coastguard Worker@varptr = global i8* null
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Workerdefine void @ldst_8bit() {
15*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: ldst_8bit:
16*9880d681SAndroid Build Coastguard Worker
17*9880d681SAndroid Build Coastguard Worker; No architectural support for loads to 16-bit or 8-bit since we
18*9880d681SAndroid Build Coastguard Worker; promote i8 during lowering.
19*9880d681SAndroid Build Coastguard Worker  %addr_8bit = load i8*, i8** @varptr
20*9880d681SAndroid Build Coastguard Worker
21*9880d681SAndroid Build Coastguard Worker; match a sign-extending load 8-bit -> 32-bit
22*9880d681SAndroid Build Coastguard Worker   %addr_sext32 = getelementptr i8, i8* %addr_8bit, i64 -256
23*9880d681SAndroid Build Coastguard Worker   %val8_sext32 = load volatile i8, i8* %addr_sext32
24*9880d681SAndroid Build Coastguard Worker   %val32_signed = sext i8 %val8_sext32 to i32
25*9880d681SAndroid Build Coastguard Worker   store volatile i32 %val32_signed, i32* @var_32bit
26*9880d681SAndroid Build Coastguard Worker; CHECK: ldursb {{w[0-9]+}}, [{{x[0-9]+}}, #-256]
27*9880d681SAndroid Build Coastguard Worker
28*9880d681SAndroid Build Coastguard Worker; match a zero-extending load volatile 8-bit -> 32-bit
29*9880d681SAndroid Build Coastguard Worker  %addr_zext32 = getelementptr i8, i8* %addr_8bit, i64 -12
30*9880d681SAndroid Build Coastguard Worker  %val8_zext32 = load volatile i8, i8* %addr_zext32
31*9880d681SAndroid Build Coastguard Worker  %val32_unsigned = zext i8 %val8_zext32 to i32
32*9880d681SAndroid Build Coastguard Worker  store volatile i32 %val32_unsigned, i32* @var_32bit
33*9880d681SAndroid Build Coastguard Worker; CHECK: ldurb {{w[0-9]+}}, [{{x[0-9]+}}, #-12]
34*9880d681SAndroid Build Coastguard Worker
35*9880d681SAndroid Build Coastguard Worker; match an any-extending load volatile 8-bit -> 32-bit
36*9880d681SAndroid Build Coastguard Worker  %addr_anyext = getelementptr i8, i8* %addr_8bit, i64 -1
37*9880d681SAndroid Build Coastguard Worker  %val8_anyext = load volatile i8, i8* %addr_anyext
38*9880d681SAndroid Build Coastguard Worker  %newval8 = add i8 %val8_anyext, 1
39*9880d681SAndroid Build Coastguard Worker  store volatile i8 %newval8, i8* @var_8bit
40*9880d681SAndroid Build Coastguard Worker; CHECK: ldurb {{w[0-9]+}}, [{{x[0-9]+}}, #-1]
41*9880d681SAndroid Build Coastguard Worker
42*9880d681SAndroid Build Coastguard Worker; match a sign-extending load volatile 8-bit -> 64-bit
43*9880d681SAndroid Build Coastguard Worker  %addr_sext64 = getelementptr i8, i8* %addr_8bit, i64 -5
44*9880d681SAndroid Build Coastguard Worker  %val8_sext64 = load volatile i8, i8* %addr_sext64
45*9880d681SAndroid Build Coastguard Worker  %val64_signed = sext i8 %val8_sext64 to i64
46*9880d681SAndroid Build Coastguard Worker  store volatile i64 %val64_signed, i64* @var_64bit
47*9880d681SAndroid Build Coastguard Worker; CHECK: ldursb {{x[0-9]+}}, [{{x[0-9]+}}, #-5]
48*9880d681SAndroid Build Coastguard Worker
49*9880d681SAndroid Build Coastguard Worker; match a zero-extending load volatile 8-bit -> 64-bit.
50*9880d681SAndroid Build Coastguard Worker; This uses the fact that ldrb w0, [x0] will zero out the high 32-bits
51*9880d681SAndroid Build Coastguard Worker; of x0 so it's identical to load volatileing to 32-bits.
52*9880d681SAndroid Build Coastguard Worker  %addr_zext64 = getelementptr i8, i8* %addr_8bit, i64 -9
53*9880d681SAndroid Build Coastguard Worker  %val8_zext64 = load volatile i8, i8* %addr_zext64
54*9880d681SAndroid Build Coastguard Worker  %val64_unsigned = zext i8 %val8_zext64 to i64
55*9880d681SAndroid Build Coastguard Worker  store volatile i64 %val64_unsigned, i64* @var_64bit
56*9880d681SAndroid Build Coastguard Worker; CHECK: ldurb {{w[0-9]+}}, [{{x[0-9]+}}, #-9]
57*9880d681SAndroid Build Coastguard Worker
58*9880d681SAndroid Build Coastguard Worker; truncating store volatile 32-bits to 8-bits
59*9880d681SAndroid Build Coastguard Worker  %addr_trunc32 = getelementptr i8, i8* %addr_8bit, i64 -256
60*9880d681SAndroid Build Coastguard Worker  %val32 = load volatile i32, i32* @var_32bit
61*9880d681SAndroid Build Coastguard Worker  %val8_trunc32 = trunc i32 %val32 to i8
62*9880d681SAndroid Build Coastguard Worker  store volatile i8 %val8_trunc32, i8* %addr_trunc32
63*9880d681SAndroid Build Coastguard Worker; CHECK: sturb {{w[0-9]+}}, [{{x[0-9]+}}, #-256]
64*9880d681SAndroid Build Coastguard Worker
65*9880d681SAndroid Build Coastguard Worker; truncating store volatile 64-bits to 8-bits
66*9880d681SAndroid Build Coastguard Worker  %addr_trunc64 = getelementptr i8, i8* %addr_8bit, i64 -1
67*9880d681SAndroid Build Coastguard Worker  %val64 = load volatile i64, i64* @var_64bit
68*9880d681SAndroid Build Coastguard Worker  %val8_trunc64 = trunc i64 %val64 to i8
69*9880d681SAndroid Build Coastguard Worker  store volatile i8 %val8_trunc64, i8* %addr_trunc64
70*9880d681SAndroid Build Coastguard Worker; CHECK: sturb {{w[0-9]+}}, [{{x[0-9]+}}, #-1]
71*9880d681SAndroid Build Coastguard Worker
72*9880d681SAndroid Build Coastguard Worker   ret void
73*9880d681SAndroid Build Coastguard Worker}
74*9880d681SAndroid Build Coastguard Worker
75*9880d681SAndroid Build Coastguard Workerdefine void @ldst_16bit() {
76*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: ldst_16bit:
77*9880d681SAndroid Build Coastguard Worker
78*9880d681SAndroid Build Coastguard Worker; No architectural support for loads to 16-bit or 16-bit since we
79*9880d681SAndroid Build Coastguard Worker; promote i16 during lowering.
80*9880d681SAndroid Build Coastguard Worker  %addr_8bit = load i8*, i8** @varptr
81*9880d681SAndroid Build Coastguard Worker
82*9880d681SAndroid Build Coastguard Worker; match a sign-extending load 16-bit -> 32-bit
83*9880d681SAndroid Build Coastguard Worker   %addr8_sext32 = getelementptr i8, i8* %addr_8bit, i64 -256
84*9880d681SAndroid Build Coastguard Worker   %addr_sext32 = bitcast i8* %addr8_sext32 to i16*
85*9880d681SAndroid Build Coastguard Worker   %val16_sext32 = load volatile i16, i16* %addr_sext32
86*9880d681SAndroid Build Coastguard Worker   %val32_signed = sext i16 %val16_sext32 to i32
87*9880d681SAndroid Build Coastguard Worker   store volatile i32 %val32_signed, i32* @var_32bit
88*9880d681SAndroid Build Coastguard Worker; CHECK: ldursh {{w[0-9]+}}, [{{x[0-9]+}}, #-256]
89*9880d681SAndroid Build Coastguard Worker
90*9880d681SAndroid Build Coastguard Worker; match a zero-extending load volatile 16-bit -> 32-bit. With offset that would be unaligned.
91*9880d681SAndroid Build Coastguard Worker  %addr8_zext32 = getelementptr i8, i8* %addr_8bit, i64 15
92*9880d681SAndroid Build Coastguard Worker  %addr_zext32 = bitcast i8* %addr8_zext32 to i16*
93*9880d681SAndroid Build Coastguard Worker  %val16_zext32 = load volatile i16, i16* %addr_zext32
94*9880d681SAndroid Build Coastguard Worker  %val32_unsigned = zext i16 %val16_zext32 to i32
95*9880d681SAndroid Build Coastguard Worker  store volatile i32 %val32_unsigned, i32* @var_32bit
96*9880d681SAndroid Build Coastguard Worker; CHECK: ldurh {{w[0-9]+}}, [{{x[0-9]+}}, #15]
97*9880d681SAndroid Build Coastguard Worker
98*9880d681SAndroid Build Coastguard Worker; match an any-extending load volatile 16-bit -> 32-bit
99*9880d681SAndroid Build Coastguard Worker  %addr8_anyext = getelementptr i8, i8* %addr_8bit, i64 -1
100*9880d681SAndroid Build Coastguard Worker  %addr_anyext = bitcast i8* %addr8_anyext to i16*
101*9880d681SAndroid Build Coastguard Worker  %val16_anyext = load volatile i16, i16* %addr_anyext
102*9880d681SAndroid Build Coastguard Worker  %newval16 = add i16 %val16_anyext, 1
103*9880d681SAndroid Build Coastguard Worker  store volatile i16 %newval16, i16* @var_16bit
104*9880d681SAndroid Build Coastguard Worker; CHECK: ldurh {{w[0-9]+}}, [{{x[0-9]+}}, #-1]
105*9880d681SAndroid Build Coastguard Worker
106*9880d681SAndroid Build Coastguard Worker; match a sign-extending load volatile 16-bit -> 64-bit
107*9880d681SAndroid Build Coastguard Worker  %addr8_sext64 = getelementptr i8, i8* %addr_8bit, i64 -5
108*9880d681SAndroid Build Coastguard Worker  %addr_sext64 = bitcast i8* %addr8_sext64 to i16*
109*9880d681SAndroid Build Coastguard Worker  %val16_sext64 = load volatile i16, i16* %addr_sext64
110*9880d681SAndroid Build Coastguard Worker  %val64_signed = sext i16 %val16_sext64 to i64
111*9880d681SAndroid Build Coastguard Worker  store volatile i64 %val64_signed, i64* @var_64bit
112*9880d681SAndroid Build Coastguard Worker; CHECK: ldursh {{x[0-9]+}}, [{{x[0-9]+}}, #-5]
113*9880d681SAndroid Build Coastguard Worker
114*9880d681SAndroid Build Coastguard Worker; match a zero-extending load volatile 16-bit -> 64-bit.
115*9880d681SAndroid Build Coastguard Worker; This uses the fact that ldrb w0, [x0] will zero out the high 32-bits
116*9880d681SAndroid Build Coastguard Worker; of x0 so it's identical to load volatileing to 32-bits.
117*9880d681SAndroid Build Coastguard Worker  %addr8_zext64 = getelementptr i8, i8* %addr_8bit, i64 9
118*9880d681SAndroid Build Coastguard Worker  %addr_zext64 = bitcast i8* %addr8_zext64 to i16*
119*9880d681SAndroid Build Coastguard Worker  %val16_zext64 = load volatile i16, i16* %addr_zext64
120*9880d681SAndroid Build Coastguard Worker  %val64_unsigned = zext i16 %val16_zext64 to i64
121*9880d681SAndroid Build Coastguard Worker  store volatile i64 %val64_unsigned, i64* @var_64bit
122*9880d681SAndroid Build Coastguard Worker; CHECK: ldurh {{w[0-9]+}}, [{{x[0-9]+}}, #9]
123*9880d681SAndroid Build Coastguard Worker
124*9880d681SAndroid Build Coastguard Worker; truncating store volatile 32-bits to 16-bits
125*9880d681SAndroid Build Coastguard Worker  %addr8_trunc32 = getelementptr i8, i8* %addr_8bit, i64 -256
126*9880d681SAndroid Build Coastguard Worker  %addr_trunc32 = bitcast i8* %addr8_trunc32 to i16*
127*9880d681SAndroid Build Coastguard Worker  %val32 = load volatile i32, i32* @var_32bit
128*9880d681SAndroid Build Coastguard Worker  %val16_trunc32 = trunc i32 %val32 to i16
129*9880d681SAndroid Build Coastguard Worker  store volatile i16 %val16_trunc32, i16* %addr_trunc32
130*9880d681SAndroid Build Coastguard Worker; CHECK: sturh {{w[0-9]+}}, [{{x[0-9]+}}, #-256]
131*9880d681SAndroid Build Coastguard Worker
132*9880d681SAndroid Build Coastguard Worker; truncating store volatile 64-bits to 16-bits
133*9880d681SAndroid Build Coastguard Worker  %addr8_trunc64 = getelementptr i8, i8* %addr_8bit, i64 -1
134*9880d681SAndroid Build Coastguard Worker  %addr_trunc64 = bitcast i8* %addr8_trunc64 to i16*
135*9880d681SAndroid Build Coastguard Worker  %val64 = load volatile i64, i64* @var_64bit
136*9880d681SAndroid Build Coastguard Worker  %val16_trunc64 = trunc i64 %val64 to i16
137*9880d681SAndroid Build Coastguard Worker  store volatile i16 %val16_trunc64, i16* %addr_trunc64
138*9880d681SAndroid Build Coastguard Worker; CHECK: sturh {{w[0-9]+}}, [{{x[0-9]+}}, #-1]
139*9880d681SAndroid Build Coastguard Worker
140*9880d681SAndroid Build Coastguard Worker   ret void
141*9880d681SAndroid Build Coastguard Worker}
142*9880d681SAndroid Build Coastguard Worker
143*9880d681SAndroid Build Coastguard Workerdefine void @ldst_32bit() {
144*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: ldst_32bit:
145*9880d681SAndroid Build Coastguard Worker
146*9880d681SAndroid Build Coastguard Worker  %addr_8bit = load i8*, i8** @varptr
147*9880d681SAndroid Build Coastguard Worker
148*9880d681SAndroid Build Coastguard Worker; Straight 32-bit load/store
149*9880d681SAndroid Build Coastguard Worker  %addr32_8_noext = getelementptr i8, i8* %addr_8bit, i64 1
150*9880d681SAndroid Build Coastguard Worker  %addr32_noext = bitcast i8* %addr32_8_noext to i32*
151*9880d681SAndroid Build Coastguard Worker  %val32_noext = load volatile i32, i32* %addr32_noext
152*9880d681SAndroid Build Coastguard Worker  store volatile i32 %val32_noext, i32* %addr32_noext
153*9880d681SAndroid Build Coastguard Worker; CHECK: ldur {{w[0-9]+}}, [{{x[0-9]+}}, #1]
154*9880d681SAndroid Build Coastguard Worker; CHECK: stur {{w[0-9]+}}, [{{x[0-9]+}}, #1]
155*9880d681SAndroid Build Coastguard Worker
156*9880d681SAndroid Build Coastguard Worker; Zero-extension to 64-bits
157*9880d681SAndroid Build Coastguard Worker  %addr32_8_zext = getelementptr i8, i8* %addr_8bit, i64 -256
158*9880d681SAndroid Build Coastguard Worker  %addr32_zext = bitcast i8* %addr32_8_zext to i32*
159*9880d681SAndroid Build Coastguard Worker  %val32_zext = load volatile i32, i32* %addr32_zext
160*9880d681SAndroid Build Coastguard Worker  %val64_unsigned = zext i32 %val32_zext to i64
161*9880d681SAndroid Build Coastguard Worker  store volatile i64 %val64_unsigned, i64* @var_64bit
162*9880d681SAndroid Build Coastguard Worker; CHECK: ldur {{w[0-9]+}}, [{{x[0-9]+}}, #-256]
163*9880d681SAndroid Build Coastguard Worker; CHECK: str {{x[0-9]+}}, [{{x[0-9]+}}, {{#?}}:lo12:var_64bit]
164*9880d681SAndroid Build Coastguard Worker
165*9880d681SAndroid Build Coastguard Worker; Sign-extension to 64-bits
166*9880d681SAndroid Build Coastguard Worker  %addr32_8_sext = getelementptr i8, i8* %addr_8bit, i64 -12
167*9880d681SAndroid Build Coastguard Worker  %addr32_sext = bitcast i8* %addr32_8_sext to i32*
168*9880d681SAndroid Build Coastguard Worker  %val32_sext = load volatile i32, i32* %addr32_sext
169*9880d681SAndroid Build Coastguard Worker  %val64_signed = sext i32 %val32_sext to i64
170*9880d681SAndroid Build Coastguard Worker  store volatile i64 %val64_signed, i64* @var_64bit
171*9880d681SAndroid Build Coastguard Worker; CHECK: ldursw {{x[0-9]+}}, [{{x[0-9]+}}, #-12]
172*9880d681SAndroid Build Coastguard Worker; CHECK: str {{x[0-9]+}}, [{{x[0-9]+}}, {{#?}}:lo12:var_64bit]
173*9880d681SAndroid Build Coastguard Worker
174*9880d681SAndroid Build Coastguard Worker; Truncation from 64-bits
175*9880d681SAndroid Build Coastguard Worker  %addr64_8_trunc = getelementptr i8, i8* %addr_8bit, i64 255
176*9880d681SAndroid Build Coastguard Worker  %addr64_trunc = bitcast i8* %addr64_8_trunc to i64*
177*9880d681SAndroid Build Coastguard Worker  %addr32_8_trunc = getelementptr i8, i8* %addr_8bit, i64 -20
178*9880d681SAndroid Build Coastguard Worker  %addr32_trunc = bitcast i8* %addr32_8_trunc to i32*
179*9880d681SAndroid Build Coastguard Worker
180*9880d681SAndroid Build Coastguard Worker  %val64_trunc = load volatile i64, i64* %addr64_trunc
181*9880d681SAndroid Build Coastguard Worker  %val32_trunc = trunc i64 %val64_trunc to i32
182*9880d681SAndroid Build Coastguard Worker  store volatile i32 %val32_trunc, i32* %addr32_trunc
183*9880d681SAndroid Build Coastguard Worker; CHECK: ldur {{x[0-9]+}}, [{{x[0-9]+}}, #255]
184*9880d681SAndroid Build Coastguard Worker; CHECK: stur {{w[0-9]+}}, [{{x[0-9]+}}, #-20]
185*9880d681SAndroid Build Coastguard Worker
186*9880d681SAndroid Build Coastguard Worker  ret void
187*9880d681SAndroid Build Coastguard Worker}
188*9880d681SAndroid Build Coastguard Worker
189*9880d681SAndroid Build Coastguard Workerdefine void @ldst_float() {
190*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: ldst_float:
191*9880d681SAndroid Build Coastguard Worker
192*9880d681SAndroid Build Coastguard Worker  %addr_8bit = load i8*, i8** @varptr
193*9880d681SAndroid Build Coastguard Worker  %addrfp_8 = getelementptr i8, i8* %addr_8bit, i64 -5
194*9880d681SAndroid Build Coastguard Worker  %addrfp = bitcast i8* %addrfp_8 to float*
195*9880d681SAndroid Build Coastguard Worker
196*9880d681SAndroid Build Coastguard Worker  %valfp = load volatile float, float* %addrfp
197*9880d681SAndroid Build Coastguard Worker; CHECK: ldur {{s[0-9]+}}, [{{x[0-9]+}}, #-5]
198*9880d681SAndroid Build Coastguard Worker; CHECK-NOFP-NOT: ldur {{s[0-9]+}},
199*9880d681SAndroid Build Coastguard Worker
200*9880d681SAndroid Build Coastguard Worker  store volatile float %valfp, float* %addrfp
201*9880d681SAndroid Build Coastguard Worker; CHECK: stur {{s[0-9]+}}, [{{x[0-9]+}}, #-5]
202*9880d681SAndroid Build Coastguard Worker; CHECK-NOFP-NOT: stur {{s[0-9]+}},
203*9880d681SAndroid Build Coastguard Worker
204*9880d681SAndroid Build Coastguard Worker  ret void
205*9880d681SAndroid Build Coastguard Worker}
206*9880d681SAndroid Build Coastguard Worker
207*9880d681SAndroid Build Coastguard Workerdefine void @ldst_double() {
208*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: ldst_double:
209*9880d681SAndroid Build Coastguard Worker
210*9880d681SAndroid Build Coastguard Worker  %addr_8bit = load i8*, i8** @varptr
211*9880d681SAndroid Build Coastguard Worker  %addrfp_8 = getelementptr i8, i8* %addr_8bit, i64 4
212*9880d681SAndroid Build Coastguard Worker  %addrfp = bitcast i8* %addrfp_8 to double*
213*9880d681SAndroid Build Coastguard Worker
214*9880d681SAndroid Build Coastguard Worker  %valfp = load volatile double, double* %addrfp
215*9880d681SAndroid Build Coastguard Worker; CHECK: ldur {{d[0-9]+}}, [{{x[0-9]+}}, #4]
216*9880d681SAndroid Build Coastguard Worker; CHECK-NOFP-NOT: ldur {{d[0-9]+}},
217*9880d681SAndroid Build Coastguard Worker
218*9880d681SAndroid Build Coastguard Worker  store volatile double %valfp, double* %addrfp
219*9880d681SAndroid Build Coastguard Worker; CHECK: stur {{d[0-9]+}}, [{{x[0-9]+}}, #4]
220*9880d681SAndroid Build Coastguard Worker; CHECK-NOFP-NOT: stur {{d[0-9]+}},
221*9880d681SAndroid Build Coastguard Worker
222*9880d681SAndroid Build Coastguard Worker   ret void
223*9880d681SAndroid Build Coastguard Worker}
224