1 ; RUN: llc -verify-machineinstrs -o - %s -mtriple=aarch64-none-linux-gnu | FileCheck %s 2 ; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -mattr=-fp-armv8 | FileCheck --check-prefix=CHECK-NOFP %s 3 4 @var_8bit = global i8 0 5 @var_16bit = global i16 0 6 @var_32bit = global i32 0 7 @var_64bit = global i64 0 8 9 @var_float = global float 0.0 10 @var_double = global double 0.0 11 12 define void @ldst_8bit(i8* %base, i32 %off32, i64 %off64) minsize { 13 ; CHECK-LABEL: ldst_8bit: 14 15 %addr8_sxtw = getelementptr i8, i8* %base, i32 %off32 16 %val8_sxtw = load volatile i8, i8* %addr8_sxtw 17 %val32_signed = sext i8 %val8_sxtw to i32 18 store volatile i32 %val32_signed, i32* @var_32bit 19 ; CHECK: ldrsb {{w[0-9]+}}, [{{x[0-9]+}}, {{[wx][0-9]+}}, sxtw] 20 21 %addr_lsl = getelementptr i8, i8* %base, i64 %off64 22 %val8_lsl = load volatile i8, i8* %addr_lsl 23 %val32_unsigned = zext i8 %val8_lsl to i32 24 store volatile i32 %val32_unsigned, i32* @var_32bit 25 ; CHECK: ldrb {{w[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}] 26 27 %addrint_uxtw = ptrtoint i8* %base to i64 28 %offset_uxtw = zext i32 %off32 to i64 29 %addrint1_uxtw = add i64 %addrint_uxtw, %offset_uxtw 30 %addr_uxtw = inttoptr i64 %addrint1_uxtw to i8* 31 %val8_uxtw = load volatile i8, i8* %addr_uxtw 32 %newval8 = add i8 %val8_uxtw, 1 33 store volatile i8 %newval8, i8* @var_8bit 34 ; CHECK: ldrb {{w[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, uxtw] 35 36 ret void 37 } 38 39 40 define void @ldst_16bit(i16* %base, i32 %off32, i64 %off64) minsize { 41 ; CHECK-LABEL: ldst_16bit: 42 43 %addr8_sxtwN = getelementptr i16, i16* %base, i32 %off32 44 %val8_sxtwN = load volatile i16, i16* %addr8_sxtwN 45 %val32_signed = sext i16 %val8_sxtwN to i32 46 store volatile i32 %val32_signed, i32* @var_32bit 47 ; CHECK: ldrsh {{w[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, sxtw #1] 48 49 %addr_lslN = getelementptr i16, i16* %base, i64 %off64 50 %val8_lslN = load volatile i16, i16* %addr_lslN 51 %val32_unsigned = zext i16 %val8_lslN to i32 52 store volatile i32 %val32_unsigned, i32* @var_32bit 53 ; CHECK: ldrh {{w[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}, lsl #1] 54 55 %addrint_uxtw = ptrtoint i16* %base to i64 56 %offset_uxtw = zext i32 %off32 to i64 57 %addrint1_uxtw = add i64 %addrint_uxtw, %offset_uxtw 58 %addr_uxtw = inttoptr i64 %addrint1_uxtw to i16* 59 %val8_uxtw = load volatile i16, i16* %addr_uxtw 60 %newval8 = add i16 %val8_uxtw, 1 61 store volatile i16 %newval8, i16* @var_16bit 62 ; CHECK: ldrh {{w[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, uxtw] 63 64 %base_sxtw = ptrtoint i16* %base to i64 65 %offset_sxtw = sext i32 %off32 to i64 66 %addrint_sxtw = add i64 %base_sxtw, %offset_sxtw 67 %addr_sxtw = inttoptr i64 %addrint_sxtw to i16* 68 %val16_sxtw = load volatile i16, i16* %addr_sxtw 69 %val64_signed = sext i16 %val16_sxtw to i64 70 store volatile i64 %val64_signed, i64* @var_64bit 71 ; CHECK: ldrsh {{x[0-9]+}}, [{{x[0-9]+}}, {{[wx][0-9]+}}, sxtw] 72 73 74 %base_lsl = ptrtoint i16* %base to i64 75 %addrint_lsl = add i64 %base_lsl, %off64 76 %addr_lsl = inttoptr i64 %addrint_lsl to i16* 77 %val16_lsl = load volatile i16, i16* %addr_lsl 78 %val64_unsigned = zext i16 %val16_lsl to i64 79 store volatile i64 %val64_unsigned, i64* @var_64bit 80 ; CHECK: ldrh {{w[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}] 81 82 %base_uxtwN = ptrtoint i16* %base to i64 83 %offset_uxtwN = zext i32 %off32 to i64 84 %offset2_uxtwN = shl i64 %offset_uxtwN, 1 85 %addrint_uxtwN = add i64 %base_uxtwN, %offset2_uxtwN 86 %addr_uxtwN = inttoptr i64 %addrint_uxtwN to i16* 87 %val32 = load volatile i32, i32* @var_32bit 88 %val16_trunc32 = trunc i32 %val32 to i16 89 store volatile i16 %val16_trunc32, i16* %addr_uxtwN 90 ; CHECK: strh {{w[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, uxtw #1] 91 ret void 92 } 93 94 define void @ldst_32bit(i32* %base, i32 %off32, i64 %off64) minsize { 95 ; CHECK-LABEL: ldst_32bit: 96 97 %addr_sxtwN = getelementptr i32, i32* %base, i32 %off32 98 %val_sxtwN = load volatile i32, i32* %addr_sxtwN 99 store volatile i32 %val_sxtwN, i32* @var_32bit 100 ; CHECK: ldr {{w[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, sxtw #2] 101 102 %addr_lslN = getelementptr i32, i32* %base, i64 %off64 103 %val_lslN = load volatile i32, i32* %addr_lslN 104 store volatile i32 %val_lslN, i32* @var_32bit 105 ; CHECK: ldr {{w[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}, lsl #2] 106 107 %addrint_uxtw = ptrtoint i32* %base to i64 108 %offset_uxtw = zext i32 %off32 to i64 109 %addrint1_uxtw = add i64 %addrint_uxtw, %offset_uxtw 110 %addr_uxtw = inttoptr i64 %addrint1_uxtw to i32* 111 %val_uxtw = load volatile i32, i32* %addr_uxtw 112 %newval8 = add i32 %val_uxtw, 1 113 store volatile i32 %newval8, i32* @var_32bit 114 ; CHECK: ldr {{w[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, uxtw] 115 116 117 %base_sxtw = ptrtoint i32* %base to i64 118 %offset_sxtw = sext i32 %off32 to i64 119 %addrint_sxtw = add i64 %base_sxtw, %offset_sxtw 120 %addr_sxtw = inttoptr i64 %addrint_sxtw to i32* 121 %val16_sxtw = load volatile i32, i32* %addr_sxtw 122 %val64_signed = sext i32 %val16_sxtw to i64 123 store volatile i64 %val64_signed, i64* @var_64bit 124 ; CHECK: ldrsw {{x[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, sxtw] 125 126 127 %base_lsl = ptrtoint i32* %base to i64 128 %addrint_lsl = add i64 %base_lsl, %off64 129 %addr_lsl = inttoptr i64 %addrint_lsl to i32* 130 %val16_lsl = load volatile i32, i32* %addr_lsl 131 %val64_unsigned = zext i32 %val16_lsl to i64 132 store volatile i64 %val64_unsigned, i64* @var_64bit 133 ; CHECK: ldr {{w[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}] 134 135 %base_uxtwN = ptrtoint i32* %base to i64 136 %offset_uxtwN = zext i32 %off32 to i64 137 %offset2_uxtwN = shl i64 %offset_uxtwN, 2 138 %addrint_uxtwN = add i64 %base_uxtwN, %offset2_uxtwN 139 %addr_uxtwN = inttoptr i64 %addrint_uxtwN to i32* 140 %val32 = load volatile i32, i32* @var_32bit 141 store volatile i32 %val32, i32* %addr_uxtwN 142 ; CHECK: str {{w[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, uxtw #2] 143 ret void 144 } 145 146 define void @ldst_64bit(i64* %base, i32 %off32, i64 %off64) minsize { 147 ; CHECK-LABEL: ldst_64bit: 148 149 %addr_sxtwN = getelementptr i64, i64* %base, i32 %off32 150 %val_sxtwN = load volatile i64, i64* %addr_sxtwN 151 store volatile i64 %val_sxtwN, i64* @var_64bit 152 ; CHECK: ldr {{x[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, sxtw #3] 153 154 %addr_lslN = getelementptr i64, i64* %base, i64 %off64 155 %val_lslN = load volatile i64, i64* %addr_lslN 156 store volatile i64 %val_lslN, i64* @var_64bit 157 ; CHECK: ldr {{x[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}, lsl #3] 158 159 %addrint_uxtw = ptrtoint i64* %base to i64 160 %offset_uxtw = zext i32 %off32 to i64 161 %addrint1_uxtw = add i64 %addrint_uxtw, %offset_uxtw 162 %addr_uxtw = inttoptr i64 %addrint1_uxtw to i64* 163 %val8_uxtw = load volatile i64, i64* %addr_uxtw 164 %newval8 = add i64 %val8_uxtw, 1 165 store volatile i64 %newval8, i64* @var_64bit 166 ; CHECK: ldr {{x[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, uxtw] 167 168 %base_sxtw = ptrtoint i64* %base to i64 169 %offset_sxtw = sext i32 %off32 to i64 170 %addrint_sxtw = add i64 %base_sxtw, %offset_sxtw 171 %addr_sxtw = inttoptr i64 %addrint_sxtw to i64* 172 %val64_sxtw = load volatile i64, i64* %addr_sxtw 173 store volatile i64 %val64_sxtw, i64* @var_64bit 174 ; CHECK: ldr {{x[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, sxtw] 175 176 %base_lsl = ptrtoint i64* %base to i64 177 %addrint_lsl = add i64 %base_lsl, %off64 178 %addr_lsl = inttoptr i64 %addrint_lsl to i64* 179 %val64_lsl = load volatile i64, i64* %addr_lsl 180 store volatile i64 %val64_lsl, i64* @var_64bit 181 ; CHECK: ldr {{x[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}] 182 183 %base_uxtwN = ptrtoint i64* %base to i64 184 %offset_uxtwN = zext i32 %off32 to i64 185 %offset2_uxtwN = shl i64 %offset_uxtwN, 3 186 %addrint_uxtwN = add i64 %base_uxtwN, %offset2_uxtwN 187 %addr_uxtwN = inttoptr i64 %addrint_uxtwN to i64* 188 %val64 = load volatile i64, i64* @var_64bit 189 store volatile i64 %val64, i64* %addr_uxtwN 190 ; CHECK: str {{x[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, uxtw #3] 191 ret void 192 } 193 194 define void @ldst_float(float* %base, i32 %off32, i64 %off64) minsize { 195 ; CHECK-LABEL: ldst_float: 196 197 %addr_sxtwN = getelementptr float, float* %base, i32 %off32 198 %val_sxtwN = load volatile float, float* %addr_sxtwN 199 store volatile float %val_sxtwN, float* @var_float 200 ; CHECK: ldr {{s[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, sxtw #2] 201 ; CHECK-NOFP-NOT: ldr {{s[0-9]+}}, 202 203 %addr_lslN = getelementptr float, float* %base, i64 %off64 204 %val_lslN = load volatile float, float* %addr_lslN 205 store volatile float %val_lslN, float* @var_float 206 ; CHECK: ldr {{s[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}, lsl #2] 207 ; CHECK-NOFP-NOT: ldr {{s[0-9]+}}, 208 209 %addrint_uxtw = ptrtoint float* %base to i64 210 %offset_uxtw = zext i32 %off32 to i64 211 %addrint1_uxtw = add i64 %addrint_uxtw, %offset_uxtw 212 %addr_uxtw = inttoptr i64 %addrint1_uxtw to float* 213 %val_uxtw = load volatile float, float* %addr_uxtw 214 store volatile float %val_uxtw, float* @var_float 215 ; CHECK: ldr {{s[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, uxtw] 216 ; CHECK-NOFP-NOT: ldr {{s[0-9]+}}, 217 218 %base_sxtw = ptrtoint float* %base to i64 219 %offset_sxtw = sext i32 %off32 to i64 220 %addrint_sxtw = add i64 %base_sxtw, %offset_sxtw 221 %addr_sxtw = inttoptr i64 %addrint_sxtw to float* 222 %val64_sxtw = load volatile float, float* %addr_sxtw 223 store volatile float %val64_sxtw, float* @var_float 224 ; CHECK: ldr {{s[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, sxtw] 225 ; CHECK-NOFP-NOT: ldr {{s[0-9]+}}, 226 227 %base_lsl = ptrtoint float* %base to i64 228 %addrint_lsl = add i64 %base_lsl, %off64 229 %addr_lsl = inttoptr i64 %addrint_lsl to float* 230 %val64_lsl = load volatile float, float* %addr_lsl 231 store volatile float %val64_lsl, float* @var_float 232 ; CHECK: ldr {{s[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}] 233 ; CHECK-NOFP-NOT: ldr {{s[0-9]+}}, 234 235 %base_uxtwN = ptrtoint float* %base to i64 236 %offset_uxtwN = zext i32 %off32 to i64 237 %offset2_uxtwN = shl i64 %offset_uxtwN, 2 238 %addrint_uxtwN = add i64 %base_uxtwN, %offset2_uxtwN 239 %addr_uxtwN = inttoptr i64 %addrint_uxtwN to float* 240 %val64 = load volatile float, float* @var_float 241 store volatile float %val64, float* %addr_uxtwN 242 ; CHECK: str {{s[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, uxtw #2] 243 ; CHECK-NOFP-NOT: ldr {{s[0-9]+}}, 244 ret void 245 } 246 247 define void @ldst_double(double* %base, i32 %off32, i64 %off64) minsize { 248 ; CHECK-LABEL: ldst_double: 249 250 %addr_sxtwN = getelementptr double, double* %base, i32 %off32 251 %val_sxtwN = load volatile double, double* %addr_sxtwN 252 store volatile double %val_sxtwN, double* @var_double 253 ; CHECK: ldr {{d[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, sxtw #3] 254 ; CHECK-NOFP-NOT: ldr {{d[0-9]+}}, 255 256 %addr_lslN = getelementptr double, double* %base, i64 %off64 257 %val_lslN = load volatile double, double* %addr_lslN 258 store volatile double %val_lslN, double* @var_double 259 ; CHECK: ldr {{d[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}, lsl #3] 260 ; CHECK-NOFP-NOT: ldr {{d[0-9]+}}, 261 262 %addrint_uxtw = ptrtoint double* %base to i64 263 %offset_uxtw = zext i32 %off32 to i64 264 %addrint1_uxtw = add i64 %addrint_uxtw, %offset_uxtw 265 %addr_uxtw = inttoptr i64 %addrint1_uxtw to double* 266 %val_uxtw = load volatile double, double* %addr_uxtw 267 store volatile double %val_uxtw, double* @var_double 268 ; CHECK: ldr {{d[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, uxtw] 269 ; CHECK-NOFP-NOT: ldr {{d[0-9]+}}, 270 271 %base_sxtw = ptrtoint double* %base to i64 272 %offset_sxtw = sext i32 %off32 to i64 273 %addrint_sxtw = add i64 %base_sxtw, %offset_sxtw 274 %addr_sxtw = inttoptr i64 %addrint_sxtw to double* 275 %val64_sxtw = load volatile double, double* %addr_sxtw 276 store volatile double %val64_sxtw, double* @var_double 277 ; CHECK: ldr {{d[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, sxtw] 278 ; CHECK-NOFP-NOT: ldr {{d[0-9]+}}, 279 280 %base_lsl = ptrtoint double* %base to i64 281 %addrint_lsl = add i64 %base_lsl, %off64 282 %addr_lsl = inttoptr i64 %addrint_lsl to double* 283 %val64_lsl = load volatile double, double* %addr_lsl 284 store volatile double %val64_lsl, double* @var_double 285 ; CHECK: ldr {{d[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}] 286 ; CHECK-NOFP-NOT: ldr {{d[0-9]+}}, 287 288 %base_uxtwN = ptrtoint double* %base to i64 289 %offset_uxtwN = zext i32 %off32 to i64 290 %offset2_uxtwN = shl i64 %offset_uxtwN, 3 291 %addrint_uxtwN = add i64 %base_uxtwN, %offset2_uxtwN 292 %addr_uxtwN = inttoptr i64 %addrint_uxtwN to double* 293 %val64 = load volatile double, double* @var_double 294 store volatile double %val64, double* %addr_uxtwN 295 ; CHECK: str {{d[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, uxtw #3] 296 ; CHECK-NOFP-NOT: ldr {{d[0-9]+}}, 297 ret void 298 } 299 300 301 define void @ldst_128bit(fp128* %base, i32 %off32, i64 %off64) minsize { 302 ; CHECK-LABEL: ldst_128bit: 303 304 %addr_sxtwN = getelementptr fp128, fp128* %base, i32 %off32 305 %val_sxtwN = load volatile fp128, fp128* %addr_sxtwN 306 store volatile fp128 %val_sxtwN, fp128* %base 307 ; CHECK: ldr {{q[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, sxtw #4] 308 ; CHECK-NOFP-NOT: ldr {{q[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, sxtw #4] 309 310 %addr_lslN = getelementptr fp128, fp128* %base, i64 %off64 311 %val_lslN = load volatile fp128, fp128* %addr_lslN 312 store volatile fp128 %val_lslN, fp128* %base 313 ; CHECK: ldr {{q[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}, lsl #4] 314 ; CHECK-NOFP-NOT: ldr {{q[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, sxtw #4] 315 316 %addrint_uxtw = ptrtoint fp128* %base to i64 317 %offset_uxtw = zext i32 %off32 to i64 318 %addrint1_uxtw = add i64 %addrint_uxtw, %offset_uxtw 319 %addr_uxtw = inttoptr i64 %addrint1_uxtw to fp128* 320 %val_uxtw = load volatile fp128, fp128* %addr_uxtw 321 store volatile fp128 %val_uxtw, fp128* %base 322 ; CHECK: ldr {{q[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, uxtw] 323 ; CHECK-NOFP-NOT: ldr {{q[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, sxtw #4] 324 325 %base_sxtw = ptrtoint fp128* %base to i64 326 %offset_sxtw = sext i32 %off32 to i64 327 %addrint_sxtw = add i64 %base_sxtw, %offset_sxtw 328 %addr_sxtw = inttoptr i64 %addrint_sxtw to fp128* 329 %val64_sxtw = load volatile fp128, fp128* %addr_sxtw 330 store volatile fp128 %val64_sxtw, fp128* %base 331 ; CHECK: ldr {{q[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, sxtw] 332 ; CHECK-NOFP-NOT: ldr {{q[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, sxtw #4] 333 334 %base_lsl = ptrtoint fp128* %base to i64 335 %addrint_lsl = add i64 %base_lsl, %off64 336 %addr_lsl = inttoptr i64 %addrint_lsl to fp128* 337 %val64_lsl = load volatile fp128, fp128* %addr_lsl 338 store volatile fp128 %val64_lsl, fp128* %base 339 ; CHECK: ldr {{q[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}] 340 ; CHECK-NOFP-NOT: ldr {{q[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, sxtw #4] 341 342 %base_uxtwN = ptrtoint fp128* %base to i64 343 %offset_uxtwN = zext i32 %off32 to i64 344 %offset2_uxtwN = shl i64 %offset_uxtwN, 4 345 %addrint_uxtwN = add i64 %base_uxtwN, %offset2_uxtwN 346 %addr_uxtwN = inttoptr i64 %addrint_uxtwN to fp128* 347 %val64 = load volatile fp128, fp128* %base 348 store volatile fp128 %val64, fp128* %addr_uxtwN 349 ; CHECK: str {{q[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, uxtw #4] 350 ; CHECK-NOFP-NOT: ldr {{q[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, sxtw #4] 351 ret void 352 } 353