825 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=aarch64-apple-darwin -verify-machineinstrs < %s | FileCheck %s --check-prefix=CHECK --check-prefix=SDAG3; RUN: llc -mtriple=aarch64-apple-darwin -fast-isel -fast-isel-abort=1 -verify-machineinstrs < %s | FileCheck %s --check-prefix=CHECK --check-prefix=FAST4 5; Load / Store Base Register only6define zeroext i1 @load_breg_i1(ptr %a) {7; SDAG-LABEL: load_breg_i1:8; SDAG: ; %bb.0:9; SDAG-NEXT: ldrb w0, [x0]10; SDAG-NEXT: ret11;12; FAST-LABEL: load_breg_i1:13; FAST: ; %bb.0:14; FAST-NEXT: ldrb w8, [x0]15; FAST-NEXT: and w8, w8, #0x116; FAST-NEXT: and w0, w8, #0x117; FAST-NEXT: ret18 %1 = load i1, ptr %a19 ret i1 %120}21 22define zeroext i8 @load_breg_i8(ptr %a) {23; SDAG-LABEL: load_breg_i8:24; SDAG: ; %bb.0:25; SDAG-NEXT: ldrb w0, [x0]26; SDAG-NEXT: ret27;28; FAST-LABEL: load_breg_i8:29; FAST: ; %bb.0:30; FAST-NEXT: ldrb w8, [x0]31; FAST-NEXT: uxtb w0, w832; FAST-NEXT: ret33 %1 = load i8, ptr %a34 ret i8 %135}36 37define zeroext i16 @load_breg_i16(ptr %a) {38; SDAG-LABEL: load_breg_i16:39; SDAG: ; %bb.0:40; SDAG-NEXT: ldrh w0, [x0]41; SDAG-NEXT: ret42;43; FAST-LABEL: load_breg_i16:44; FAST: ; %bb.0:45; FAST-NEXT: ldrh w8, [x0]46; FAST-NEXT: uxth w0, w847; FAST-NEXT: ret48 %1 = load i16, ptr %a49 ret i16 %150}51 52define i32 @load_breg_i32(ptr %a) {53; CHECK-LABEL: load_breg_i32:54; CHECK: ; %bb.0:55; CHECK-NEXT: ldr w0, [x0]56; CHECK-NEXT: ret57 %1 = load i32, ptr %a58 ret i32 %159}60 61define i64 @load_breg_i64(ptr %a) {62; CHECK-LABEL: load_breg_i64:63; CHECK: ; %bb.0:64; CHECK-NEXT: ldr x0, [x0]65; CHECK-NEXT: ret66 %1 = load i64, ptr %a67 ret i64 %168}69 70define float @load_breg_f32(ptr %a) {71; CHECK-LABEL: load_breg_f32:72; CHECK: ; %bb.0:73; CHECK-NEXT: ldr s0, [x0]74; CHECK-NEXT: ret75 %1 = load float, ptr %a76 ret float %177}78 79define double @load_breg_f64(ptr %a) {80; CHECK-LABEL: load_breg_f64:81; CHECK: ; %bb.0:82; CHECK-NEXT: ldr d0, [x0]83; CHECK-NEXT: ret84 %1 = load double, ptr %a85 ret double %186}87 88define void @store_breg_i1(ptr %a) {89; CHECK-LABEL: store_breg_i1:90; CHECK: ; %bb.0:91; CHECK-NEXT: strb wzr, [x0]92; CHECK-NEXT: ret93 store i1 0, ptr %a94 ret void95}96 97define void @store_breg_i1_2(ptr %a) {98; SDAG-LABEL: store_breg_i1_2:99; SDAG: ; %bb.0:100; SDAG-NEXT: mov w8, #1 ; =0x1101; SDAG-NEXT: strb w8, [x0]102; SDAG-NEXT: ret103;104; FAST-LABEL: store_breg_i1_2:105; FAST: ; %bb.0:106; FAST-NEXT: mov w8, #1 ; =0x1107; FAST-NEXT: and w8, w8, #0x1108; FAST-NEXT: strb w8, [x0]109; FAST-NEXT: ret110 store i1 true, ptr %a111 ret void112}113 114define void @store_breg_i8(ptr %a) {115; CHECK-LABEL: store_breg_i8:116; CHECK: ; %bb.0:117; CHECK-NEXT: strb wzr, [x0]118; CHECK-NEXT: ret119 store i8 0, ptr %a120 ret void121}122 123define void @store_breg_i16(ptr %a) {124; CHECK-LABEL: store_breg_i16:125; CHECK: ; %bb.0:126; CHECK-NEXT: strh wzr, [x0]127; CHECK-NEXT: ret128 store i16 0, ptr %a129 ret void130}131 132define void @store_breg_i32(ptr %a) {133; CHECK-LABEL: store_breg_i32:134; CHECK: ; %bb.0:135; CHECK-NEXT: str wzr, [x0]136; CHECK-NEXT: ret137 store i32 0, ptr %a138 ret void139}140 141define void @store_breg_i64(ptr %a) {142; CHECK-LABEL: store_breg_i64:143; CHECK: ; %bb.0:144; CHECK-NEXT: str xzr, [x0]145; CHECK-NEXT: ret146 store i64 0, ptr %a147 ret void148}149 150define void @store_breg_f32(ptr %a) {151; CHECK-LABEL: store_breg_f32:152; CHECK: ; %bb.0:153; CHECK-NEXT: str wzr, [x0]154; CHECK-NEXT: ret155 store float 0.0, ptr %a156 ret void157}158 159define void @store_breg_f64(ptr %a) {160; CHECK-LABEL: store_breg_f64:161; CHECK: ; %bb.0:162; CHECK-NEXT: str xzr, [x0]163; CHECK-NEXT: ret164 store double 0.0, ptr %a165 ret void166}167 168; Load Immediate169define i32 @load_immoff_1() {170; SDAG-LABEL: load_immoff_1:171; SDAG: ; %bb.0:172; SDAG-NEXT: mov w8, #128 ; =0x80173; SDAG-NEXT: ldr w0, [x8]174; SDAG-NEXT: ret175;176; FAST-LABEL: load_immoff_1:177; FAST: ; %bb.0:178; FAST-NEXT: mov x8, #128 ; =0x80179; FAST-NEXT: ldr w0, [x8]180; FAST-NEXT: ret181 %1 = inttoptr i64 128 to ptr182 %2 = load i32, ptr %1183 ret i32 %2184}185 186; Load / Store Base Register + Immediate Offset187; Max supported negative offset188define i32 @load_breg_immoff_1(i64 %a) {189; CHECK-LABEL: load_breg_immoff_1:190; CHECK: ; %bb.0:191; CHECK-NEXT: ldur w0, [x0, #-256]192; CHECK-NEXT: ret193 %1 = add i64 %a, -256194 %2 = inttoptr i64 %1 to ptr195 %3 = load i32, ptr %2196 ret i32 %3197}198 199; Min not-supported negative offset200define i32 @load_breg_immoff_2(i64 %a) {201; CHECK-LABEL: load_breg_immoff_2:202; CHECK: ; %bb.0:203; CHECK-NEXT: sub x8, x0, #257204; CHECK-NEXT: ldr w0, [x8]205; CHECK-NEXT: ret206 %1 = add i64 %a, -257207 %2 = inttoptr i64 %1 to ptr208 %3 = load i32, ptr %2209 ret i32 %3210}211 212; Max supported unscaled offset213define i32 @load_breg_immoff_3(i64 %a) {214; CHECK-LABEL: load_breg_immoff_3:215; CHECK: ; %bb.0:216; CHECK-NEXT: ldur w0, [x0, #255]217; CHECK-NEXT: ret218 %1 = add i64 %a, 255219 %2 = inttoptr i64 %1 to ptr220 %3 = load i32, ptr %2221 ret i32 %3222}223 224; Min un-supported unscaled offset225define i32 @load_breg_immoff_4(i64 %a) {226; CHECK-LABEL: load_breg_immoff_4:227; CHECK: ; %bb.0:228; CHECK-NEXT: add x8, x0, #257229; CHECK-NEXT: ldr w0, [x8]230; CHECK-NEXT: ret231 %1 = add i64 %a, 257232 %2 = inttoptr i64 %1 to ptr233 %3 = load i32, ptr %2234 ret i32 %3235}236 237; Max supported scaled offset238define i32 @load_breg_immoff_5(i64 %a) {239; CHECK-LABEL: load_breg_immoff_5:240; CHECK: ; %bb.0:241; CHECK-NEXT: ldr w0, [x0, #16380]242; CHECK-NEXT: ret243 %1 = add i64 %a, 16380244 %2 = inttoptr i64 %1 to ptr245 %3 = load i32, ptr %2246 ret i32 %3247}248 249; Min un-supported scaled offset250define i32 @load_breg_immoff_6(i64 %a) {251; SDAG-LABEL: load_breg_immoff_6:252; SDAG: ; %bb.0:253; SDAG-NEXT: mov w8, #16384 ; =0x4000254; SDAG-NEXT: ldr w0, [x0, x8]255; SDAG-NEXT: ret256;257; FAST-LABEL: load_breg_immoff_6:258; FAST: ; %bb.0:259; FAST-NEXT: add x8, x0, #4, lsl #12 ; =16384260; FAST-NEXT: ldr w0, [x8]261; FAST-NEXT: ret262 %1 = add i64 %a, 16384263 %2 = inttoptr i64 %1 to ptr264 %3 = load i32, ptr %2265 ret i32 %3266}267 268; Max supported negative offset269define void @store_breg_immoff_1(i64 %a) {270; CHECK-LABEL: store_breg_immoff_1:271; CHECK: ; %bb.0:272; CHECK-NEXT: stur wzr, [x0, #-256]273; CHECK-NEXT: ret274 %1 = add i64 %a, -256275 %2 = inttoptr i64 %1 to ptr276 store i32 0, ptr %2277 ret void278}279 280; Min not-supported negative offset281define void @store_breg_immoff_2(i64 %a) {282; CHECK-LABEL: store_breg_immoff_2:283; CHECK: ; %bb.0:284; CHECK-NEXT: sub x8, x0, #257285; CHECK-NEXT: str wzr, [x8]286; CHECK-NEXT: ret287 %1 = add i64 %a, -257288 %2 = inttoptr i64 %1 to ptr289 store i32 0, ptr %2290 ret void291}292 293; Max supported unscaled offset294define void @store_breg_immoff_3(i64 %a) {295; CHECK-LABEL: store_breg_immoff_3:296; CHECK: ; %bb.0:297; CHECK-NEXT: stur wzr, [x0, #255]298; CHECK-NEXT: ret299 %1 = add i64 %a, 255300 %2 = inttoptr i64 %1 to ptr301 store i32 0, ptr %2302 ret void303}304 305; Min un-supported unscaled offset306define void @store_breg_immoff_4(i64 %a) {307; CHECK-LABEL: store_breg_immoff_4:308; CHECK: ; %bb.0:309; CHECK-NEXT: add x8, x0, #257310; CHECK-NEXT: str wzr, [x8]311; CHECK-NEXT: ret312 %1 = add i64 %a, 257313 %2 = inttoptr i64 %1 to ptr314 store i32 0, ptr %2315 ret void316}317 318; Max supported scaled offset319define void @store_breg_immoff_5(i64 %a) {320; CHECK-LABEL: store_breg_immoff_5:321; CHECK: ; %bb.0:322; CHECK-NEXT: str wzr, [x0, #16380]323; CHECK-NEXT: ret324 %1 = add i64 %a, 16380325 %2 = inttoptr i64 %1 to ptr326 store i32 0, ptr %2327 ret void328}329 330; Min un-supported scaled offset331define void @store_breg_immoff_6(i64 %a) {332; SDAG-LABEL: store_breg_immoff_6:333; SDAG: ; %bb.0:334; SDAG-NEXT: mov w8, #16384 ; =0x4000335; SDAG-NEXT: str wzr, [x0, x8]336; SDAG-NEXT: ret337;338; FAST-LABEL: store_breg_immoff_6:339; FAST: ; %bb.0:340; FAST-NEXT: add x8, x0, #4, lsl #12 ; =16384341; FAST-NEXT: str wzr, [x8]342; FAST-NEXT: ret343 %1 = add i64 %a, 16384344 %2 = inttoptr i64 %1 to ptr345 store i32 0, ptr %2346 ret void347}348 349define i64 @load_breg_immoff_7(i64 %a) {350; CHECK-LABEL: load_breg_immoff_7:351; CHECK: ; %bb.0:352; CHECK-NEXT: ldr x0, [x0, #48]353; CHECK-NEXT: ret354 %1 = add i64 %a, 48355 %2 = inttoptr i64 %1 to ptr356 %3 = load i64, ptr %2357 ret i64 %3358}359 360; Flip add operands361define i64 @load_breg_immoff_8(i64 %a) {362; CHECK-LABEL: load_breg_immoff_8:363; CHECK: ; %bb.0:364; CHECK-NEXT: ldr x0, [x0, #48]365; CHECK-NEXT: ret366 %1 = add i64 48, %a367 %2 = inttoptr i64 %1 to ptr368 %3 = load i64, ptr %2369 ret i64 %3370}371 372; Load Base Register + Register Offset373define i64 @load_breg_offreg_1(i64 %a, i64 %b) {374; CHECK-LABEL: load_breg_offreg_1:375; CHECK: ; %bb.0:376; CHECK-NEXT: ldr x0, [x0, x1]377; CHECK-NEXT: ret378 %1 = add i64 %a, %b379 %2 = inttoptr i64 %1 to ptr380 %3 = load i64, ptr %2381 ret i64 %3382}383 384; Flip add operands385define i64 @load_breg_offreg_2(i64 %a, i64 %b) {386; CHECK-LABEL: load_breg_offreg_2:387; CHECK: ; %bb.0:388; CHECK-NEXT: ldr x0, [x1, x0]389; CHECK-NEXT: ret390 %1 = add i64 %b, %a391 %2 = inttoptr i64 %1 to ptr392 %3 = load i64, ptr %2393 ret i64 %3394}395 396; Load Base Register + Register Offset + Immediate Offset397define i64 @load_breg_offreg_immoff_1(i64 %a, i64 %b) {398; CHECK-LABEL: load_breg_offreg_immoff_1:399; CHECK: ; %bb.0:400; CHECK-NEXT: add x8, x0, x1401; CHECK-NEXT: ldr x0, [x8, #48]402; CHECK-NEXT: ret403 %1 = add i64 %a, %b404 %2 = add i64 %1, 48405 %3 = inttoptr i64 %2 to ptr406 %4 = load i64, ptr %3407 ret i64 %4408}409 410define i64 @load_breg_offreg_immoff_2(i64 %a, i64 %b) {411; SDAG-LABEL: load_breg_offreg_immoff_2:412; SDAG: ; %bb.0:413; SDAG-NEXT: mov w8, #61440 ; =0xf000414; SDAG-NEXT: add x9, x0, x1415; SDAG-NEXT: ldr x0, [x9, x8]416; SDAG-NEXT: ret417;418; FAST-LABEL: load_breg_offreg_immoff_2:419; FAST: ; %bb.0:420; FAST-NEXT: add x8, x0, #15, lsl #12 ; =61440421; FAST-NEXT: ldr x0, [x8, x1]422; FAST-NEXT: ret423 %1 = add i64 %a, %b424 %2 = add i64 %1, 61440425 %3 = inttoptr i64 %2 to ptr426 %4 = load i64, ptr %3427 ret i64 %4428}429 430; Load Scaled Register Offset431define i32 @load_shift_offreg_1(i64 %a) {432; CHECK-LABEL: load_shift_offreg_1:433; CHECK: ; %bb.0:434; CHECK-NEXT: lsl x8, x0, #2435; CHECK-NEXT: ldr w0, [x8]436; CHECK-NEXT: ret437 %1 = shl i64 %a, 2438 %2 = inttoptr i64 %1 to ptr439 %3 = load i32, ptr %2440 ret i32 %3441}442 443define i32 @load_mul_offreg_1(i64 %a) {444; CHECK-LABEL: load_mul_offreg_1:445; CHECK: ; %bb.0:446; CHECK-NEXT: lsl x8, x0, #2447; CHECK-NEXT: ldr w0, [x8]448; CHECK-NEXT: ret449 %1 = mul i64 %a, 4450 %2 = inttoptr i64 %1 to ptr451 %3 = load i32, ptr %2452 ret i32 %3453}454 455; Load Base Register + Scaled Register Offset456define i32 @load_breg_shift_offreg_1(i64 %a, i64 %b) {457; CHECK-LABEL: load_breg_shift_offreg_1:458; CHECK: ; %bb.0:459; CHECK-NEXT: ldr w0, [x1, x0, lsl #2]460; CHECK-NEXT: ret461 %1 = shl i64 %a, 2462 %2 = add i64 %1, %b463 %3 = inttoptr i64 %2 to ptr464 %4 = load i32, ptr %3465 ret i32 %4466}467 468define i32 @load_breg_shift_offreg_2(i64 %a, i64 %b) {469; CHECK-LABEL: load_breg_shift_offreg_2:470; CHECK: ; %bb.0:471; CHECK-NEXT: ldr w0, [x1, x0, lsl #2]472; CHECK-NEXT: ret473 %1 = shl i64 %a, 2474 %2 = add i64 %b, %1475 %3 = inttoptr i64 %2 to ptr476 %4 = load i32, ptr %3477 ret i32 %4478}479 480define i32 @load_breg_shift_offreg_3(i64 %a, i64 %b) {481; SDAG-LABEL: load_breg_shift_offreg_3:482; SDAG: ; %bb.0:483; SDAG-NEXT: lsl x8, x0, #2484; SDAG-NEXT: ldr w0, [x8, x1, lsl #2]485; SDAG-NEXT: ret486;487; FAST-LABEL: load_breg_shift_offreg_3:488; FAST: ; %bb.0:489; FAST-NEXT: lsl x8, x1, #2490; FAST-NEXT: ldr w0, [x8, x0, lsl #2]491; FAST-NEXT: ret492 %1 = shl i64 %a, 2493 %2 = shl i64 %b, 2494 %3 = add i64 %1, %2495 %4 = inttoptr i64 %3 to ptr496 %5 = load i32, ptr %4497 ret i32 %5498}499 500define i32 @load_breg_shift_offreg_4(i64 %a, i64 %b) {501; SDAG-LABEL: load_breg_shift_offreg_4:502; SDAG: ; %bb.0:503; SDAG-NEXT: lsl x8, x1, #2504; SDAG-NEXT: ldr w0, [x8, x0, lsl #2]505; SDAG-NEXT: ret506;507; FAST-LABEL: load_breg_shift_offreg_4:508; FAST: ; %bb.0:509; FAST-NEXT: lsl x8, x0, #2510; FAST-NEXT: ldr w0, [x8, x1, lsl #2]511; FAST-NEXT: ret512 %1 = shl i64 %a, 2513 %2 = shl i64 %b, 2514 %3 = add i64 %2, %1515 %4 = inttoptr i64 %3 to ptr516 %5 = load i32, ptr %4517 ret i32 %5518}519 520define i32 @load_breg_shift_offreg_5(i64 %a, i64 %b) {521; CHECK-LABEL: load_breg_shift_offreg_5:522; CHECK: ; %bb.0:523; CHECK-NEXT: lsl x8, x1, #3524; CHECK-NEXT: ldr w0, [x8, x0, lsl #2]525; CHECK-NEXT: ret526 %1 = shl i64 %a, 2527 %2 = shl i64 %b, 3528 %3 = add i64 %1, %2529 %4 = inttoptr i64 %3 to ptr530 %5 = load i32, ptr %4531 ret i32 %5532}533 534define i32 @load_breg_mul_offreg_1(i64 %a, i64 %b) {535; CHECK-LABEL: load_breg_mul_offreg_1:536; CHECK: ; %bb.0:537; CHECK-NEXT: ldr w0, [x1, x0, lsl #2]538; CHECK-NEXT: ret539 %1 = mul i64 %a, 4540 %2 = add i64 %1, %b541 %3 = inttoptr i64 %2 to ptr542 %4 = load i32, ptr %3543 ret i32 %4544}545 546define zeroext i8 @load_breg_and_offreg_1(i64 %a, i64 %b) {547; SDAG-LABEL: load_breg_and_offreg_1:548; SDAG: ; %bb.0:549; SDAG-NEXT: ldrb w0, [x1, w0, uxtw]550; SDAG-NEXT: ret551;552; FAST-LABEL: load_breg_and_offreg_1:553; FAST: ; %bb.0:554; FAST-NEXT: ldrb w8, [x1, w0, uxtw]555; FAST-NEXT: uxtb w0, w8556; FAST-NEXT: ret557 %1 = and i64 %a, 4294967295558 %2 = add i64 %1, %b559 %3 = inttoptr i64 %2 to ptr560 %4 = load i8, ptr %3561 ret i8 %4562}563 564define zeroext i16 @load_breg_and_offreg_2(i64 %a, i64 %b) {565; SDAG-LABEL: load_breg_and_offreg_2:566; SDAG: ; %bb.0:567; SDAG-NEXT: ldrh w0, [x1, w0, uxtw #1]568; SDAG-NEXT: ret569;570; FAST-LABEL: load_breg_and_offreg_2:571; FAST: ; %bb.0:572; FAST-NEXT: ldrh w8, [x1, w0, uxtw #1]573; FAST-NEXT: uxth w0, w8574; FAST-NEXT: ret575 %1 = and i64 %a, 4294967295576 %2 = shl i64 %1, 1577 %3 = add i64 %2, %b578 %4 = inttoptr i64 %3 to ptr579 %5 = load i16, ptr %4580 ret i16 %5581}582 583define i32 @load_breg_and_offreg_3(i64 %a, i64 %b) {584; CHECK-LABEL: load_breg_and_offreg_3:585; CHECK: ; %bb.0:586; CHECK-NEXT: ldr w0, [x1, w0, uxtw #2]587; CHECK-NEXT: ret588 %1 = and i64 %a, 4294967295589 %2 = shl i64 %1, 2590 %3 = add i64 %2, %b591 %4 = inttoptr i64 %3 to ptr592 %5 = load i32, ptr %4593 ret i32 %5594}595 596define i64 @load_breg_and_offreg_4(i64 %a, i64 %b) {597; CHECK-LABEL: load_breg_and_offreg_4:598; CHECK: ; %bb.0:599; CHECK-NEXT: ldr x0, [x1, w0, uxtw #3]600; CHECK-NEXT: ret601 %1 = and i64 %a, 4294967295602 %2 = shl i64 %1, 3603 %3 = add i64 %2, %b604 %4 = inttoptr i64 %3 to ptr605 %5 = load i64, ptr %4606 ret i64 %5607}608 609; Not all 'and' instructions have immediates.610define i64 @load_breg_and_offreg_5(i64 %a, i64 %b, i64 %c) {611; CHECK-LABEL: load_breg_and_offreg_5:612; CHECK: ; %bb.0:613; CHECK-NEXT: and x8, x0, x2614; CHECK-NEXT: ldr x0, [x8, x1]615; CHECK-NEXT: ret616 %1 = and i64 %a, %c617 %2 = add i64 %1, %b618 %3 = inttoptr i64 %2 to ptr619 %4 = load i64, ptr %3620 ret i64 %4621}622 623define i64 @load_breg_and_offreg_6(i64 %a, i64 %b, i64 %c) {624; CHECK-LABEL: load_breg_and_offreg_6:625; CHECK: ; %bb.0:626; CHECK-NEXT: and x8, x0, x2627; CHECK-NEXT: ldr x0, [x1, x8, lsl #3]628; CHECK-NEXT: ret629 %1 = and i64 %a, %c630 %2 = shl i64 %1, 3631 %3 = add i64 %2, %b632 %4 = inttoptr i64 %3 to ptr633 %5 = load i64, ptr %4634 ret i64 %5635}636 637; Load Base Register + Scaled Register Offset + Sign/Zero extension638define i32 @load_breg_zext_shift_offreg_1(i32 %a, i64 %b) {639; CHECK-LABEL: load_breg_zext_shift_offreg_1:640; CHECK: ; %bb.0:641; CHECK-NEXT: ldr w0, [x1, w0, uxtw #2]642; CHECK-NEXT: ret643 %1 = zext i32 %a to i64644 %2 = shl i64 %1, 2645 %3 = add i64 %2, %b646 %4 = inttoptr i64 %3 to ptr647 %5 = load i32, ptr %4648 ret i32 %5649}650 651define i32 @load_breg_zext_shift_offreg_2(i32 %a, i64 %b) {652; CHECK-LABEL: load_breg_zext_shift_offreg_2:653; CHECK: ; %bb.0:654; CHECK-NEXT: ldr w0, [x1, w0, uxtw #2]655; CHECK-NEXT: ret656 %1 = zext i32 %a to i64657 %2 = shl i64 %1, 2658 %3 = add i64 %b, %2659 %4 = inttoptr i64 %3 to ptr660 %5 = load i32, ptr %4661 ret i32 %5662}663 664define i32 @load_breg_zext_mul_offreg_1(i32 %a, i64 %b) {665; CHECK-LABEL: load_breg_zext_mul_offreg_1:666; CHECK: ; %bb.0:667; CHECK-NEXT: ldr w0, [x1, w0, uxtw #2]668; CHECK-NEXT: ret669 %1 = zext i32 %a to i64670 %2 = mul i64 %1, 4671 %3 = add i64 %2, %b672 %4 = inttoptr i64 %3 to ptr673 %5 = load i32, ptr %4674 ret i32 %5675}676 677define i32 @load_breg_sext_shift_offreg_1(i32 %a, i64 %b) {678; CHECK-LABEL: load_breg_sext_shift_offreg_1:679; CHECK: ; %bb.0:680; CHECK-NEXT: ldr w0, [x1, w0, sxtw #2]681; CHECK-NEXT: ret682 %1 = sext i32 %a to i64683 %2 = shl i64 %1, 2684 %3 = add i64 %2, %b685 %4 = inttoptr i64 %3 to ptr686 %5 = load i32, ptr %4687 ret i32 %5688}689 690define i32 @load_breg_sext_shift_offreg_2(i32 %a, i64 %b) {691; CHECK-LABEL: load_breg_sext_shift_offreg_2:692; CHECK: ; %bb.0:693; CHECK-NEXT: ldr w0, [x1, w0, sxtw #2]694; CHECK-NEXT: ret695 %1 = sext i32 %a to i64696 %2 = shl i64 %1, 2697 %3 = add i64 %b, %2698 %4 = inttoptr i64 %3 to ptr699 %5 = load i32, ptr %4700 ret i32 %5701}702 703; Make sure that we don't drop the first 'add' instruction.704define i32 @load_breg_sext_shift_offreg_3(i32 %a, i64 %b) {705; CHECK-LABEL: load_breg_sext_shift_offreg_3:706; CHECK: ; %bb.0:707; CHECK-NEXT: add w8, w0, #4708; CHECK-NEXT: ldr w0, [x1, w8, sxtw #2]709; CHECK-NEXT: ret710 %1 = add i32 %a, 4711 %2 = sext i32 %1 to i64712 %3 = shl i64 %2, 2713 %4 = add i64 %b, %3714 %5 = inttoptr i64 %4 to ptr715 %6 = load i32, ptr %5716 ret i32 %6717}718 719 720define i32 @load_breg_sext_mul_offreg_1(i32 %a, i64 %b) {721; CHECK-LABEL: load_breg_sext_mul_offreg_1:722; CHECK: ; %bb.0:723; CHECK-NEXT: ldr w0, [x1, w0, sxtw #2]724; CHECK-NEXT: ret725 %1 = sext i32 %a to i64726 %2 = mul i64 %1, 4727 %3 = add i64 %2, %b728 %4 = inttoptr i64 %3 to ptr729 %5 = load i32, ptr %4730 ret i32 %5731}732 733; Load Scaled Register Offset + Immediate Offset + Sign/Zero extension734define i64 @load_sext_shift_offreg_imm1(i32 %a) {735; CHECK-LABEL: load_sext_shift_offreg_imm1:736; CHECK: ; %bb.0:737; CHECK-NEXT: ; kill: def $w0 killed $w0 def $x0738; CHECK-NEXT: sbfiz x8, x0, #3, #32739; CHECK-NEXT: ldr x0, [x8, #8]740; CHECK-NEXT: ret741 %1 = sext i32 %a to i64742 %2 = shl i64 %1, 3743 %3 = add i64 %2, 8744 %4 = inttoptr i64 %3 to ptr745 %5 = load i64, ptr %4746 ret i64 %5747}748 749; Load Base Register + Scaled Register Offset + Immediate Offset + Sign/Zero extension750define i64 @load_breg_sext_shift_offreg_imm1(i32 %a, i64 %b) {751; CHECK-LABEL: load_breg_sext_shift_offreg_imm1:752; CHECK: ; %bb.0:753; CHECK-NEXT: add x8, x1, w0, sxtw #3754; CHECK-NEXT: ldr x0, [x8, #8]755; CHECK-NEXT: ret756 %1 = sext i32 %a to i64757 %2 = shl i64 %1, 3758 %3 = add i64 %b, %2759 %4 = add i64 %3, 8760 %5 = inttoptr i64 %4 to ptr761 %6 = load i64, ptr %5762 ret i64 %6763}764 765; Test that the kill flag is not set - the machine instruction verifier does that for us.766define i64 @kill_reg(i64 %a) {767; SDAG-LABEL: kill_reg:768; SDAG: ; %bb.0:769; SDAG-NEXT: ldr x8, [x0, #88]!770; SDAG-NEXT: add x0, x0, x8771; SDAG-NEXT: ret772;773; FAST-LABEL: kill_reg:774; FAST: ; %bb.0:775; FAST-NEXT: sub x8, x0, #8776; FAST-NEXT: ldr x9, [x0, #88]777; FAST-NEXT: add x8, x8, #96778; FAST-NEXT: add x0, x8, x9779; FAST-NEXT: ret780 %1 = sub i64 %a, 8781 %2 = add i64 %1, 96782 %3 = inttoptr i64 %2 to ptr783 %4 = load i64, ptr %3784 %5 = add i64 %2, %4785 ret i64 %5786}787 788define void @store_fi(i64 %i) {789; CHECK-LABEL: store_fi:790; CHECK: ; %bb.0:791; CHECK-NEXT: sub sp, sp, #32792; CHECK-NEXT: .cfi_def_cfa_offset 32793; CHECK-NEXT: mov x8, sp794; CHECK-NEXT: mov w9, #47 ; =0x2f795; CHECK-NEXT: str w9, [x8, x0, lsl #2]796; CHECK-NEXT: add sp, sp, #32797; CHECK-NEXT: ret798 %1 = alloca [8 x i32]799 %2 = ptrtoint ptr %1 to i64800 %3 = mul i64 %i, 4801 %4 = add i64 %2, %3802 %5 = inttoptr i64 %4 to ptr803 store i32 47, ptr %5, align 4804 ret void805}806 807define i32 @load_fi(i64 %i) {808; CHECK-LABEL: load_fi:809; CHECK: ; %bb.0:810; CHECK-NEXT: sub sp, sp, #32811; CHECK-NEXT: .cfi_def_cfa_offset 32812; CHECK-NEXT: mov x8, sp813; CHECK-NEXT: ldr w0, [x8, x0, lsl #2]814; CHECK-NEXT: add sp, sp, #32815; CHECK-NEXT: ret816 %1 = alloca [8 x i32]817 %2 = ptrtoint ptr %1 to i64818 %3 = mul i64 %i, 4819 %4 = add i64 %2, %3820 %5 = inttoptr i64 %4 to ptr821 %6 = load i32, ptr %5, align 4822 ret i32 %6823}824 825