1; RUN: llc -mtriple=aarch64-apple-darwin -verify-machineinstrs < %s | FileCheck %s --check-prefix=CHECK --check-prefix=SDAG 2; RUN: llc -mtriple=aarch64-apple-darwin -fast-isel -fast-isel-abort=1 -verify-machineinstrs < %s | FileCheck %s --check-prefix=CHECK --check-prefix=FAST 3 4; Load / Store Base Register only 5define zeroext i1 @load_breg_i1(i1* %a) { 6; CHECK-LABEL: load_breg_i1 7; CHECK: ldrb {{w[0-9]+}}, [x0] 8 %1 = load i1, i1* %a 9 ret i1 %1 10} 11 12define zeroext i8 @load_breg_i8(i8* %a) { 13; CHECK-LABEL: load_breg_i8 14; CHECK: ldrb {{w[0-9]+}}, [x0] 15 %1 = load i8, i8* %a 16 ret i8 %1 17} 18 19define zeroext i16 @load_breg_i16(i16* %a) { 20; CHECK-LABEL: load_breg_i16 21; CHECK: ldrh {{w[0-9]+}}, [x0] 22 %1 = load i16, i16* %a 23 ret i16 %1 24} 25 26define i32 @load_breg_i32(i32* %a) { 27; CHECK-LABEL: load_breg_i32 28; CHECK: ldr {{w[0-9]+}}, [x0] 29 %1 = load i32, i32* %a 30 ret i32 %1 31} 32 33define i64 @load_breg_i64(i64* %a) { 34; CHECK-LABEL: load_breg_i64 35; CHECK: ldr {{x[0-9]+}}, [x0] 36 %1 = load i64, i64* %a 37 ret i64 %1 38} 39 40define float @load_breg_f32(float* %a) { 41; CHECK-LABEL: load_breg_f32 42; CHECK: ldr {{s[0-9]+}}, [x0] 43 %1 = load float, float* %a 44 ret float %1 45} 46 47define double @load_breg_f64(double* %a) { 48; CHECK-LABEL: load_breg_f64 49; CHECK: ldr {{d[0-9]+}}, [x0] 50 %1 = load double, double* %a 51 ret double %1 52} 53 54define void @store_breg_i1(i1* %a) { 55; CHECK-LABEL: store_breg_i1 56; CHECK: strb wzr, [x0] 57 store i1 0, i1* %a 58 ret void 59} 60 61define void @store_breg_i1_2(i1* %a) { 62; CHECK-LABEL: store_breg_i1_2 63; CHECK: strb {{w[0-9]+}}, [x0] 64 store i1 true, i1* %a 65 ret void 66} 67 68define void @store_breg_i8(i8* %a) { 69; CHECK-LABEL: store_breg_i8 70; CHECK: strb wzr, [x0] 71 store i8 0, i8* %a 72 ret void 73} 74 75define void @store_breg_i16(i16* %a) { 76; CHECK-LABEL: store_breg_i16 77; CHECK: strh wzr, [x0] 78 store i16 0, i16* %a 79 ret void 80} 81 82define void @store_breg_i32(i32* %a) { 83; CHECK-LABEL: store_breg_i32 84; CHECK: str wzr, [x0] 85 store i32 0, i32* %a 86 ret void 87} 88 89define void @store_breg_i64(i64* %a) { 90; CHECK-LABEL: store_breg_i64 91; CHECK: str xzr, [x0] 92 store i64 0, i64* %a 93 ret void 94} 95 96define void @store_breg_f32(float* %a) { 97; CHECK-LABEL: store_breg_f32 98; CHECK: str wzr, [x0] 99 store float 0.0, float* %a 100 ret void 101} 102 103define void @store_breg_f64(double* %a) { 104; CHECK-LABEL: store_breg_f64 105; CHECK: str xzr, [x0] 106 store double 0.0, double* %a 107 ret void 108} 109 110; Load Immediate 111define i32 @load_immoff_1() { 112; CHECK-LABEL: load_immoff_1 113; CHECK: orr {{w|x}}[[REG:[0-9]+]], {{wzr|xzr}}, #0x80 114; CHECK: ldr {{w[0-9]+}}, {{\[}}x[[REG]]{{\]}} 115 %1 = inttoptr i64 128 to i32* 116 %2 = load i32, i32* %1 117 ret i32 %2 118} 119 120; Load / Store Base Register + Immediate Offset 121; Max supported negative offset 122define i32 @load_breg_immoff_1(i64 %a) { 123; CHECK-LABEL: load_breg_immoff_1 124; CHECK: ldur {{w[0-9]+}}, [x0, #-256] 125 %1 = add i64 %a, -256 126 %2 = inttoptr i64 %1 to i32* 127 %3 = load i32, i32* %2 128 ret i32 %3 129} 130 131; Min not-supported negative offset 132define i32 @load_breg_immoff_2(i64 %a) { 133; CHECK-LABEL: load_breg_immoff_2 134; CHECK: sub [[REG:x[0-9]+]], x0, #257 135; CHECK-NEXT: ldr {{w[0-9]+}}, {{\[}}[[REG]]{{\]}} 136 %1 = add i64 %a, -257 137 %2 = inttoptr i64 %1 to i32* 138 %3 = load i32, i32* %2 139 ret i32 %3 140} 141 142; Max supported unscaled offset 143define i32 @load_breg_immoff_3(i64 %a) { 144; CHECK-LABEL: load_breg_immoff_3 145; CHECK: ldur {{w[0-9]+}}, [x0, #255] 146 %1 = add i64 %a, 255 147 %2 = inttoptr i64 %1 to i32* 148 %3 = load i32, i32* %2 149 ret i32 %3 150} 151 152; Min un-supported unscaled offset 153define i32 @load_breg_immoff_4(i64 %a) { 154; CHECK-LABEL: load_breg_immoff_4 155; CHECK: add [[REG:x[0-9]+]], x0, #257 156; CHECK-NEXT: ldr {{w[0-9]+}}, {{\[}}[[REG]]{{\]}} 157 %1 = add i64 %a, 257 158 %2 = inttoptr i64 %1 to i32* 159 %3 = load i32, i32* %2 160 ret i32 %3 161} 162 163; Max supported scaled offset 164define i32 @load_breg_immoff_5(i64 %a) { 165; CHECK-LABEL: load_breg_immoff_5 166; CHECK: ldr {{w[0-9]+}}, [x0, #16380] 167 %1 = add i64 %a, 16380 168 %2 = inttoptr i64 %1 to i32* 169 %3 = load i32, i32* %2 170 ret i32 %3 171} 172 173; Min un-supported scaled offset 174define i32 @load_breg_immoff_6(i64 %a) { 175; SDAG-LABEL: load_breg_immoff_6 176; SDAG: orr w[[NUM:[0-9]+]], wzr, #0x4000 177; SDAG-NEXT: ldr {{w[0-9]+}}, [x0, x[[NUM]]] 178; FAST-LABEL: load_breg_immoff_6 179; FAST: add [[REG:x[0-9]+]], x0, #4, lsl #12 180; FAST-NEXT: ldr {{w[0-9]+}}, {{\[}}[[REG]]{{\]}} 181 %1 = add i64 %a, 16384 182 %2 = inttoptr i64 %1 to i32* 183 %3 = load i32, i32* %2 184 ret i32 %3 185} 186 187; Max supported negative offset 188define void @store_breg_immoff_1(i64 %a) { 189; CHECK-LABEL: store_breg_immoff_1 190; CHECK: stur wzr, [x0, #-256] 191 %1 = add i64 %a, -256 192 %2 = inttoptr i64 %1 to i32* 193 store i32 0, i32* %2 194 ret void 195} 196 197; Min not-supported negative offset 198define void @store_breg_immoff_2(i64 %a) { 199; CHECK-LABEL: store_breg_immoff_2 200; CHECK: sub [[REG:x[0-9]+]], x0, #257 201; CHECK-NEXT: str wzr, {{\[}}[[REG]]{{\]}} 202 %1 = add i64 %a, -257 203 %2 = inttoptr i64 %1 to i32* 204 store i32 0, i32* %2 205 ret void 206} 207 208; Max supported unscaled offset 209define void @store_breg_immoff_3(i64 %a) { 210; CHECK-LABEL: store_breg_immoff_3 211; CHECK: stur wzr, [x0, #255] 212 %1 = add i64 %a, 255 213 %2 = inttoptr i64 %1 to i32* 214 store i32 0, i32* %2 215 ret void 216} 217 218; Min un-supported unscaled offset 219define void @store_breg_immoff_4(i64 %a) { 220; CHECK-LABEL: store_breg_immoff_4 221; CHECK: add [[REG:x[0-9]+]], x0, #257 222; CHECK-NEXT: str wzr, {{\[}}[[REG]]{{\]}} 223 %1 = add i64 %a, 257 224 %2 = inttoptr i64 %1 to i32* 225 store i32 0, i32* %2 226 ret void 227} 228 229; Max supported scaled offset 230define void @store_breg_immoff_5(i64 %a) { 231; CHECK-LABEL: store_breg_immoff_5 232; CHECK: str wzr, [x0, #16380] 233 %1 = add i64 %a, 16380 234 %2 = inttoptr i64 %1 to i32* 235 store i32 0, i32* %2 236 ret void 237} 238 239; Min un-supported scaled offset 240define void @store_breg_immoff_6(i64 %a) { 241; SDAG-LABEL: store_breg_immoff_6 242; SDAG: orr w[[NUM:[0-9]+]], wzr, #0x4000 243; SDAG-NEXT: str wzr, [x0, x[[NUM]]] 244; FAST-LABEL: store_breg_immoff_6 245; FAST: add [[REG:x[0-9]+]], x0, #4, lsl #12 246; FAST-NEXT: str wzr, {{\[}}[[REG]]{{\]}} 247 %1 = add i64 %a, 16384 248 %2 = inttoptr i64 %1 to i32* 249 store i32 0, i32* %2 250 ret void 251} 252 253define i64 @load_breg_immoff_7(i64 %a) { 254; CHECK-LABEL: load_breg_immoff_7 255; CHECK: ldr {{x[0-9]+}}, [x0, #48] 256 %1 = add i64 %a, 48 257 %2 = inttoptr i64 %1 to i64* 258 %3 = load i64, i64* %2 259 ret i64 %3 260} 261 262; Flip add operands 263define i64 @load_breg_immoff_8(i64 %a) { 264; CHECK-LABEL: load_breg_immoff_8 265; CHECK: ldr {{x[0-9]+}}, [x0, #48] 266 %1 = add i64 48, %a 267 %2 = inttoptr i64 %1 to i64* 268 %3 = load i64, i64* %2 269 ret i64 %3 270} 271 272; Load Base Register + Register Offset 273define i64 @load_breg_offreg_1(i64 %a, i64 %b) { 274; CHECK-LABEL: load_breg_offreg_1 275; CHECK: ldr {{x[0-9]+}}, [x0, x1] 276 %1 = add i64 %a, %b 277 %2 = inttoptr i64 %1 to i64* 278 %3 = load i64, i64* %2 279 ret i64 %3 280} 281 282; Flip add operands 283define i64 @load_breg_offreg_2(i64 %a, i64 %b) { 284; CHECK-LABEL: load_breg_offreg_2 285; CHECK: ldr {{x[0-9]+}}, [x1, x0] 286 %1 = add i64 %b, %a 287 %2 = inttoptr i64 %1 to i64* 288 %3 = load i64, i64* %2 289 ret i64 %3 290} 291 292; Load Base Register + Register Offset + Immediate Offset 293define i64 @load_breg_offreg_immoff_1(i64 %a, i64 %b) { 294; CHECK-LABEL: load_breg_offreg_immoff_1 295; CHECK: add [[REG:x[0-9]+]], x0, x1 296; CHECK-NEXT: ldr x0, {{\[}}[[REG]], #48{{\]}} 297 %1 = add i64 %a, %b 298 %2 = add i64 %1, 48 299 %3 = inttoptr i64 %2 to i64* 300 %4 = load i64, i64* %3 301 ret i64 %4 302} 303 304define i64 @load_breg_offreg_immoff_2(i64 %a, i64 %b) { 305; SDAG-LABEL: load_breg_offreg_immoff_2 306; SDAG: add [[REG1:x[0-9]+]], x0, x1 307; SDAG-NEXT: orr w[[NUM:[0-9]+]], wzr, #0xf000 308; SDAG-NEXT: ldr x0, {{\[}}[[REG1]], x[[NUM]]] 309; FAST-LABEL: load_breg_offreg_immoff_2 310; FAST: add [[REG:x[0-9]+]], x0, #15, lsl #12 311; FAST-NEXT: ldr x0, {{\[}}[[REG]], x1{{\]}} 312 %1 = add i64 %a, %b 313 %2 = add i64 %1, 61440 314 %3 = inttoptr i64 %2 to i64* 315 %4 = load i64, i64* %3 316 ret i64 %4 317} 318 319; Load Scaled Register Offset 320define i32 @load_shift_offreg_1(i64 %a) { 321; CHECK-LABEL: load_shift_offreg_1 322; CHECK: lsl [[REG:x[0-9]+]], x0, #2 323; CHECK: ldr {{w[0-9]+}}, {{\[}}[[REG]]{{\]}} 324 %1 = shl i64 %a, 2 325 %2 = inttoptr i64 %1 to i32* 326 %3 = load i32, i32* %2 327 ret i32 %3 328} 329 330define i32 @load_mul_offreg_1(i64 %a) { 331; CHECK-LABEL: load_mul_offreg_1 332; CHECK: lsl [[REG:x[0-9]+]], x0, #2 333; CHECK: ldr {{w[0-9]+}}, {{\[}}[[REG]]{{\]}} 334 %1 = mul i64 %a, 4 335 %2 = inttoptr i64 %1 to i32* 336 %3 = load i32, i32* %2 337 ret i32 %3 338} 339 340; Load Base Register + Scaled Register Offset 341define i32 @load_breg_shift_offreg_1(i64 %a, i64 %b) { 342; CHECK-LABEL: load_breg_shift_offreg_1 343; CHECK: ldr {{w[0-9]+}}, [x1, x0, lsl #2] 344 %1 = shl i64 %a, 2 345 %2 = add i64 %1, %b 346 %3 = inttoptr i64 %2 to i32* 347 %4 = load i32, i32* %3 348 ret i32 %4 349} 350 351define i32 @load_breg_shift_offreg_2(i64 %a, i64 %b) { 352; CHECK-LABEL: load_breg_shift_offreg_2 353; CHECK: ldr {{w[0-9]+}}, [x1, x0, lsl #2] 354 %1 = shl i64 %a, 2 355 %2 = add i64 %b, %1 356 %3 = inttoptr i64 %2 to i32* 357 %4 = load i32, i32* %3 358 ret i32 %4 359} 360 361define i32 @load_breg_shift_offreg_3(i64 %a, i64 %b) { 362; SDAG-LABEL: load_breg_shift_offreg_3 363; SDAG: lsl [[REG:x[0-9]+]], x0, #2 364; SDAG-NEXT: ldr {{w[0-9]+}}, {{\[}}[[REG]], x1, lsl #2{{\]}} 365; FAST-LABEL: load_breg_shift_offreg_3 366; FAST: lsl [[REG:x[0-9]+]], x1, #2 367; FAST-NEXT: ldr {{w[0-9]+}}, {{\[}}[[REG]], x0, lsl #2{{\]}} 368 %1 = shl i64 %a, 2 369 %2 = shl i64 %b, 2 370 %3 = add i64 %1, %2 371 %4 = inttoptr i64 %3 to i32* 372 %5 = load i32, i32* %4 373 ret i32 %5 374} 375 376define i32 @load_breg_shift_offreg_4(i64 %a, i64 %b) { 377; SDAG-LABEL: load_breg_shift_offreg_4 378; SDAG: lsl [[REG:x[0-9]+]], x1, #2 379; SDAG-NEXT: ldr {{w[0-9]+}}, {{\[}}[[REG]], x0, lsl #2{{\]}} 380; FAST-LABEL: load_breg_shift_offreg_4 381; FAST: lsl [[REG:x[0-9]+]], x0, #2 382; FAST-NEXT: ldr {{w[0-9]+}}, {{\[}}[[REG]], x1, lsl #2{{\]}} 383 %1 = shl i64 %a, 2 384 %2 = shl i64 %b, 2 385 %3 = add i64 %2, %1 386 %4 = inttoptr i64 %3 to i32* 387 %5 = load i32, i32* %4 388 ret i32 %5 389} 390 391define i32 @load_breg_shift_offreg_5(i64 %a, i64 %b) { 392; SDAG-LABEL: load_breg_shift_offreg_5 393; SDAG: lsl [[REG:x[0-9]+]], x1, #3 394; SDAG-NEXT: ldr {{w[0-9]+}}, {{\[}}[[REG]], x0, lsl #2{{\]}} 395; FAST-LABEL: load_breg_shift_offreg_5 396; FAST: lsl [[REG:x[0-9]+]], x1, #3 397; FAST-NEXT: ldr {{w[0-9]+}}, {{\[}}[[REG]], x0, lsl #2{{\]}} 398 %1 = shl i64 %a, 2 399 %2 = shl i64 %b, 3 400 %3 = add i64 %1, %2 401 %4 = inttoptr i64 %3 to i32* 402 %5 = load i32, i32* %4 403 ret i32 %5 404} 405 406define i32 @load_breg_mul_offreg_1(i64 %a, i64 %b) { 407; CHECK-LABEL: load_breg_mul_offreg_1 408; CHECK: ldr {{w[0-9]+}}, [x1, x0, lsl #2] 409 %1 = mul i64 %a, 4 410 %2 = add i64 %1, %b 411 %3 = inttoptr i64 %2 to i32* 412 %4 = load i32, i32* %3 413 ret i32 %4 414} 415 416define zeroext i8 @load_breg_and_offreg_1(i64 %a, i64 %b) { 417; CHECK-LABEL: load_breg_and_offreg_1 418; CHECK: ldrb {{w[0-9]+}}, [x1, w0, uxtw] 419 %1 = and i64 %a, 4294967295 420 %2 = add i64 %1, %b 421 %3 = inttoptr i64 %2 to i8* 422 %4 = load i8, i8* %3 423 ret i8 %4 424} 425 426define zeroext i16 @load_breg_and_offreg_2(i64 %a, i64 %b) { 427; CHECK-LABEL: load_breg_and_offreg_2 428; CHECK: ldrh {{w[0-9]+}}, [x1, w0, uxtw #1] 429 %1 = and i64 %a, 4294967295 430 %2 = shl i64 %1, 1 431 %3 = add i64 %2, %b 432 %4 = inttoptr i64 %3 to i16* 433 %5 = load i16, i16* %4 434 ret i16 %5 435} 436 437define i32 @load_breg_and_offreg_3(i64 %a, i64 %b) { 438; CHECK-LABEL: load_breg_and_offreg_3 439; CHECK: ldr {{w[0-9]+}}, [x1, w0, uxtw #2] 440 %1 = and i64 %a, 4294967295 441 %2 = shl i64 %1, 2 442 %3 = add i64 %2, %b 443 %4 = inttoptr i64 %3 to i32* 444 %5 = load i32, i32* %4 445 ret i32 %5 446} 447 448define i64 @load_breg_and_offreg_4(i64 %a, i64 %b) { 449; CHECK-LABEL: load_breg_and_offreg_4 450; CHECK: ldr {{x[0-9]+}}, [x1, w0, uxtw #3] 451 %1 = and i64 %a, 4294967295 452 %2 = shl i64 %1, 3 453 %3 = add i64 %2, %b 454 %4 = inttoptr i64 %3 to i64* 455 %5 = load i64, i64* %4 456 ret i64 %5 457} 458 459; Not all 'and' instructions have immediates. 460define i64 @load_breg_and_offreg_5(i64 %a, i64 %b, i64 %c) { 461; CHECK-LABEL: load_breg_and_offreg_5 462; CHECK: and [[REG:x[0-9]+]], x0, x2 463; CHECK-NEXT: ldr {{x[0-9]+}}, {{\[}}[[REG]], x1{{\]}} 464 %1 = and i64 %a, %c 465 %2 = add i64 %1, %b 466 %3 = inttoptr i64 %2 to i64* 467 %4 = load i64, i64* %3 468 ret i64 %4 469} 470 471define i64 @load_breg_and_offreg_6(i64 %a, i64 %b, i64 %c) { 472; CHECK-LABEL: load_breg_and_offreg_6 473; CHECK: and [[REG:x[0-9]+]], x0, x2 474; CHECK-NEXT: ldr {{x[0-9]+}}, {{\[}}x1, [[REG]], lsl #3{{\]}} 475 %1 = and i64 %a, %c 476 %2 = shl i64 %1, 3 477 %3 = add i64 %2, %b 478 %4 = inttoptr i64 %3 to i64* 479 %5 = load i64, i64* %4 480 ret i64 %5 481} 482 483; Load Base Register + Scaled Register Offset + Sign/Zero extension 484define i32 @load_breg_zext_shift_offreg_1(i32 %a, i64 %b) { 485; CHECK-LABEL: load_breg_zext_shift_offreg_1 486; CHECK: ldr {{w[0-9]+}}, [x1, w0, uxtw #2] 487 %1 = zext i32 %a to i64 488 %2 = shl i64 %1, 2 489 %3 = add i64 %2, %b 490 %4 = inttoptr i64 %3 to i32* 491 %5 = load i32, i32* %4 492 ret i32 %5 493} 494 495define i32 @load_breg_zext_shift_offreg_2(i32 %a, i64 %b) { 496; CHECK-LABEL: load_breg_zext_shift_offreg_2 497; CHECK: ldr {{w[0-9]+}}, [x1, w0, uxtw #2] 498 %1 = zext i32 %a to i64 499 %2 = shl i64 %1, 2 500 %3 = add i64 %b, %2 501 %4 = inttoptr i64 %3 to i32* 502 %5 = load i32, i32* %4 503 ret i32 %5 504} 505 506define i32 @load_breg_zext_mul_offreg_1(i32 %a, i64 %b) { 507; CHECK-LABEL: load_breg_zext_mul_offreg_1 508; CHECK: ldr {{w[0-9]+}}, [x1, w0, uxtw #2] 509 %1 = zext i32 %a to i64 510 %2 = mul i64 %1, 4 511 %3 = add i64 %2, %b 512 %4 = inttoptr i64 %3 to i32* 513 %5 = load i32, i32* %4 514 ret i32 %5 515} 516 517define i32 @load_breg_sext_shift_offreg_1(i32 %a, i64 %b) { 518; CHECK-LABEL: load_breg_sext_shift_offreg_1 519; CHECK: ldr {{w[0-9]+}}, [x1, w0, sxtw #2] 520 %1 = sext i32 %a to i64 521 %2 = shl i64 %1, 2 522 %3 = add i64 %2, %b 523 %4 = inttoptr i64 %3 to i32* 524 %5 = load i32, i32* %4 525 ret i32 %5 526} 527 528define i32 @load_breg_sext_shift_offreg_2(i32 %a, i64 %b) { 529; CHECK-LABEL: load_breg_sext_shift_offreg_2 530; CHECK: ldr {{w[0-9]+}}, [x1, w0, sxtw #2] 531 %1 = sext i32 %a to i64 532 %2 = shl i64 %1, 2 533 %3 = add i64 %b, %2 534 %4 = inttoptr i64 %3 to i32* 535 %5 = load i32, i32* %4 536 ret i32 %5 537} 538 539; Make sure that we don't drop the first 'add' instruction. 540define i32 @load_breg_sext_shift_offreg_3(i32 %a, i64 %b) { 541; CHECK-LABEL: load_breg_sext_shift_offreg_3 542; CHECK: add [[REG:w[0-9]+]], w0, #4 543; CHECK: ldr {{w[0-9]+}}, {{\[}}x1, [[REG]], sxtw #2{{\]}} 544 %1 = add i32 %a, 4 545 %2 = sext i32 %1 to i64 546 %3 = shl i64 %2, 2 547 %4 = add i64 %b, %3 548 %5 = inttoptr i64 %4 to i32* 549 %6 = load i32, i32* %5 550 ret i32 %6 551} 552 553 554define i32 @load_breg_sext_mul_offreg_1(i32 %a, i64 %b) { 555; CHECK-LABEL: load_breg_sext_mul_offreg_1 556; CHECK: ldr {{w[0-9]+}}, [x1, w0, sxtw #2] 557 %1 = sext i32 %a to i64 558 %2 = mul i64 %1, 4 559 %3 = add i64 %2, %b 560 %4 = inttoptr i64 %3 to i32* 561 %5 = load i32, i32* %4 562 ret i32 %5 563} 564 565; Load Scaled Register Offset + Immediate Offset + Sign/Zero extension 566define i64 @load_sext_shift_offreg_imm1(i32 %a) { 567; CHECK-LABEL: load_sext_shift_offreg_imm1 568; CHECK: sbfiz [[REG:x[0-9]+]], {{x[0-9]+}}, #3, #32 569; CHECK-NEXT: ldr {{x[0-9]+}}, {{\[}}[[REG]], #8{{\]}} 570 %1 = sext i32 %a to i64 571 %2 = shl i64 %1, 3 572 %3 = add i64 %2, 8 573 %4 = inttoptr i64 %3 to i64* 574 %5 = load i64, i64* %4 575 ret i64 %5 576} 577 578; Load Base Register + Scaled Register Offset + Immediate Offset + Sign/Zero extension 579define i64 @load_breg_sext_shift_offreg_imm1(i32 %a, i64 %b) { 580; CHECK-LABEL: load_breg_sext_shift_offreg_imm1 581; CHECK: add [[REG:x[0-9]+]], x1, w0, sxtw #3 582; CHECK-NEXT: ldr {{x[0-9]+}}, {{\[}}[[REG]], #8{{\]}} 583 %1 = sext i32 %a to i64 584 %2 = shl i64 %1, 3 585 %3 = add i64 %b, %2 586 %4 = add i64 %3, 8 587 %5 = inttoptr i64 %4 to i64* 588 %6 = load i64, i64* %5 589 ret i64 %6 590} 591 592; Test that the kill flag is not set - the machine instruction verifier does that for us. 593define i64 @kill_reg(i64 %a) { 594 %1 = sub i64 %a, 8 595 %2 = add i64 %1, 96 596 %3 = inttoptr i64 %2 to i64* 597 %4 = load i64, i64* %3 598 %5 = add i64 %2, %4 599 ret i64 %5 600} 601 602define void @store_fi(i64 %i) { 603; CHECK-LABEL: store_fi 604; CHECK: mov [[REG:x[0-9]+]], sp 605; CHECK: str {{w[0-9]+}}, {{\[}}[[REG]], x0, lsl #2{{\]}} 606 %1 = alloca [8 x i32] 607 %2 = ptrtoint [8 x i32]* %1 to i64 608 %3 = mul i64 %i, 4 609 %4 = add i64 %2, %3 610 %5 = inttoptr i64 %4 to i32* 611 store i32 47, i32* %5, align 4 612 ret void 613} 614 615define i32 @load_fi(i64 %i) { 616; CHECK-LABEL: load_fi 617; CHECK: mov [[REG:x[0-9]+]], sp 618; CHECK: ldr {{w[0-9]+}}, {{\[}}[[REG]], x0, lsl #2{{\]}} 619 %1 = alloca [8 x i32] 620 %2 = ptrtoint [8 x i32]* %1 to i64 621 %3 = mul i64 %i, 4 622 %4 = add i64 %2, %3 623 %5 = inttoptr i64 %4 to i32* 624 %6 = load i32, i32* %5, align 4 625 ret i32 %6 626} 627 628