; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 ; RUN: llc -mtriple=aarch64-apple-ios -verify-machineinstrs -global-isel -aarch64-enable-sink-fold=true -aarch64-postlegalizer-consecutive-memops=0 < %s | FileCheck %s --check-prefix=CHECK-NO-SPLIT ; RUN: llc -mtriple=aarch64-apple-ios -verify-machineinstrs -global-isel -aarch64-enable-sink-fold=true < %s | FileCheck %s --check-prefix=CHECK-SPLIT define void @basic_split(ptr %p) { ; CHECK-NO-SPLIT-LABEL: basic_split: ; CHECK-NO-SPLIT: ; %bb.0: ; CHECK-NO-SPLIT-NEXT: str xzr, [x0, #8000] ; CHECK-NO-SPLIT-NEXT: str xzr, [x0, #8008] ; CHECK-NO-SPLIT-NEXT: str xzr, [x0, #8016] ; CHECK-NO-SPLIT-NEXT: str xzr, [x0, #8024] ; CHECK-NO-SPLIT-NEXT: str xzr, [x0, #8032] ; CHECK-NO-SPLIT-NEXT: str xzr, [x0, #8040] ; CHECK-NO-SPLIT-NEXT: ret ; ; CHECK-SPLIT-LABEL: basic_split: ; CHECK-SPLIT: ; %bb.0: ; CHECK-SPLIT-NEXT: mov w8, #8000 ; =0x1f40 ; CHECK-SPLIT-NEXT: add x8, x0, x8 ; CHECK-SPLIT-NEXT: stp xzr, xzr, [x8] ; CHECK-SPLIT-NEXT: stp xzr, xzr, [x8, #16] ; CHECK-SPLIT-NEXT: stp xzr, xzr, [x8, #32] ; CHECK-SPLIT-NEXT: ret %bigoffset = getelementptr i64, ptr %p, i64 1000 store i64 0, ptr %bigoffset %addr2 = getelementptr i64, ptr %p, i64 1001 store i64 0, ptr %addr2 %addr3 = getelementptr i64, ptr %p, i64 1002 store i64 0, ptr %addr3 %addr4 = getelementptr i64, ptr %p, i64 1003 store i64 0, ptr %addr4 %addr5 = getelementptr i64, ptr %p, i64 1004 store i64 0, ptr %addr5 %addr6 = getelementptr i64, ptr %p, i64 1005 store i64 0, ptr %addr6 ret void } define void @basic_multi_use_ptr(ptr %p, ptr %p2) { ; CHECK-NO-SPLIT-LABEL: basic_multi_use_ptr: ; CHECK-NO-SPLIT: ; %bb.0: ; CHECK-NO-SPLIT-NEXT: mov w8, #8008 ; =0x1f48 ; CHECK-NO-SPLIT-NEXT: str xzr, [x0, #8000] ; CHECK-NO-SPLIT-NEXT: add x8, x0, x8 ; CHECK-NO-SPLIT-NEXT: str xzr, [x0, #8008] ; CHECK-NO-SPLIT-NEXT: str xzr, [x0, #8016] ; CHECK-NO-SPLIT-NEXT: str xzr, [x0, #8024] ; CHECK-NO-SPLIT-NEXT: str x8, [x1] ; CHECK-NO-SPLIT-NEXT: ret ; ; CHECK-SPLIT-LABEL: basic_multi_use_ptr: ; CHECK-SPLIT: ; %bb.0: ; CHECK-SPLIT-NEXT: mov w8, #8008 ; =0x1f48 ; CHECK-SPLIT-NEXT: str xzr, [x0, #8000] ; CHECK-SPLIT-NEXT: add x8, x0, x8 ; CHECK-SPLIT-NEXT: str xzr, [x0, #8008] ; CHECK-SPLIT-NEXT: str xzr, [x0, #8016] ; CHECK-SPLIT-NEXT: str xzr, [x0, #8024] ; CHECK-SPLIT-NEXT: str x8, [x1] ; CHECK-SPLIT-NEXT: ret %bigoffset = getelementptr i64, ptr %p, i64 1000 store i64 0, ptr %bigoffset %addr2 = getelementptr i64, ptr %p, i64 1001 store i64 0, ptr %addr2 %addr3 = getelementptr i64, ptr %p, i64 1002 store i64 0, ptr %addr3 %addr4 = getelementptr i64, ptr %p, i64 1003 store i64 0, ptr %addr4 ; multiuse of %addr2 store ptr %addr2, ptr %p2 ret void } define void @not_consecutive(ptr %p) { ; CHECK-NO-SPLIT-LABEL: not_consecutive: ; CHECK-NO-SPLIT: ; %bb.0: ; CHECK-NO-SPLIT-NEXT: str xzr, [x0, #8000] ; CHECK-NO-SPLIT-NEXT: str xzr, [x0, #8008] ; CHECK-NO-SPLIT-NEXT: str xzr, [x0, #8024] ; CHECK-NO-SPLIT-NEXT: str xzr, [x0, #8032] ; CHECK-NO-SPLIT-NEXT: ret ; ; CHECK-SPLIT-LABEL: not_consecutive: ; CHECK-SPLIT: ; %bb.0: ; CHECK-SPLIT-NEXT: str xzr, [x0, #8000] ; CHECK-SPLIT-NEXT: str xzr, [x0, #8008] ; CHECK-SPLIT-NEXT: str xzr, [x0, #8024] ; CHECK-SPLIT-NEXT: str xzr, [x0, #8032] ; CHECK-SPLIT-NEXT: ret %bigoffset = getelementptr i64, ptr %p, i64 1000 store i64 0, ptr %bigoffset %addr2 = getelementptr i64, ptr %p, i64 1001 store i64 0, ptr %addr2 %addr3 = getelementptr i64, ptr %p, i64 1003 store i64 0, ptr %addr3 %addr4 = getelementptr i64, ptr %p, i64 1004 store i64 0, ptr %addr4 ret void } define void @early_store_is_invalid_but_split_rest(ptr %p) { ; CHECK-NO-SPLIT-LABEL: early_store_is_invalid_but_split_rest: ; CHECK-NO-SPLIT: ; %bb.0: ; CHECK-NO-SPLIT-NEXT: str xzr, [x0, #8000] ; CHECK-NO-SPLIT-NEXT: str xzr, [x0, #8080] ; CHECK-NO-SPLIT-NEXT: str xzr, [x0, #8016] ; CHECK-NO-SPLIT-NEXT: str xzr, [x0, #8024] ; CHECK-NO-SPLIT-NEXT: str xzr, [x0, #8032] ; CHECK-NO-SPLIT-NEXT: str xzr, [x0, #8040] ; CHECK-NO-SPLIT-NEXT: str xzr, [x0, #8048] ; CHECK-NO-SPLIT-NEXT: str xzr, [x0, #8056] ; CHECK-NO-SPLIT-NEXT: ret ; ; CHECK-SPLIT-LABEL: early_store_is_invalid_but_split_rest: ; CHECK-SPLIT: ; %bb.0: ; CHECK-SPLIT-NEXT: mov w8, #8016 ; =0x1f50 ; CHECK-SPLIT-NEXT: str xzr, [x0, #8000] ; CHECK-SPLIT-NEXT: add x8, x0, x8 ; CHECK-SPLIT-NEXT: str xzr, [x0, #8080] ; CHECK-SPLIT-NEXT: stp xzr, xzr, [x8] ; CHECK-SPLIT-NEXT: stp xzr, xzr, [x8, #16] ; CHECK-SPLIT-NEXT: stp xzr, xzr, [x8, #32] ; CHECK-SPLIT-NEXT: ret %bigoffset = getelementptr i64, ptr %p, i64 1000 store i64 0, ptr %bigoffset %addr2 = getelementptr i64, ptr %p, i64 1010 store i64 0, ptr %addr2 %addr3 = getelementptr i64, ptr %p, i64 1002 store i64 0, ptr %addr3 %addr4 = getelementptr i64, ptr %p, i64 1003 store i64 0, ptr %addr4 %addr5 = getelementptr i64, ptr %p, i64 1004 store i64 0, ptr %addr5 %addr6 = getelementptr i64, ptr %p, i64 1005 store i64 0, ptr %addr6 %addr7 = getelementptr i64, ptr %p, i64 1006 store i64 0, ptr %addr7 %addr8 = getelementptr i64, ptr %p, i64 1007 store i64 0, ptr %addr8 ret void } define void @vector(ptr %p) { ; CHECK-NO-SPLIT-LABEL: vector: ; CHECK-NO-SPLIT: ; %bb.0: ; CHECK-NO-SPLIT-NEXT: movi.2d v0, #0000000000000000 ; CHECK-NO-SPLIT-NEXT: str q0, [x0, #16000] ; CHECK-NO-SPLIT-NEXT: str q0, [x0, #16016] ; CHECK-NO-SPLIT-NEXT: str q0, [x0, #16032] ; CHECK-NO-SPLIT-NEXT: str q0, [x0, #16048] ; CHECK-NO-SPLIT-NEXT: str q0, [x0, #16064] ; CHECK-NO-SPLIT-NEXT: str q0, [x0, #16080] ; CHECK-NO-SPLIT-NEXT: str q0, [x0, #16096] ; CHECK-NO-SPLIT-NEXT: str q0, [x0, #16112] ; CHECK-NO-SPLIT-NEXT: ret ; ; CHECK-SPLIT-LABEL: vector: ; CHECK-SPLIT: ; %bb.0: ; CHECK-SPLIT-NEXT: movi.2d v0, #0000000000000000 ; CHECK-SPLIT-NEXT: mov w8, #16000 ; =0x3e80 ; CHECK-SPLIT-NEXT: add x8, x0, x8 ; CHECK-SPLIT-NEXT: stp q0, q0, [x8] ; CHECK-SPLIT-NEXT: stp q0, q0, [x8, #32] ; CHECK-SPLIT-NEXT: stp q0, q0, [x8, #64] ; CHECK-SPLIT-NEXT: stp q0, q0, [x8, #96] ; CHECK-SPLIT-NEXT: ret %bigoffset = getelementptr <2 x i64>, ptr %p, i64 1000 store <2 x i64> , ptr %bigoffset %addr2 = getelementptr <2 x i64>, ptr %p, i64 1001 store <2 x i64> , ptr %addr2 %addr3 = getelementptr <2 x i64>, ptr %p, i64 1002 store <2 x i64> , ptr %addr3 %addr4 = getelementptr <2 x i64>, ptr %p, i64 1003 store <2 x i64> , ptr %addr4 %addr5 = getelementptr <2 x i64>, ptr %p, i64 1004 store <2 x i64> , ptr %addr5 %addr6 = getelementptr <2 x i64>, ptr %p, i64 1005 store <2 x i64> , ptr %addr6 %addr7 = getelementptr <2 x i64>, ptr %p, i64 1006 store <2 x i64> , ptr %addr7 %addr8 = getelementptr <2 x i64>, ptr %p, i64 1007 store <2 x i64> , ptr %addr8 ret void } define void @can_already_form_stp(ptr %p) { ; CHECK-NO-SPLIT-LABEL: can_already_form_stp: ; CHECK-NO-SPLIT: ; %bb.0: ; CHECK-NO-SPLIT-NEXT: stp xzr, xzr, [x0, #80] ; CHECK-NO-SPLIT-NEXT: stp xzr, xzr, [x0, #96] ; CHECK-NO-SPLIT-NEXT: stp xzr, xzr, [x0, #112] ; CHECK-NO-SPLIT-NEXT: ret ; ; CHECK-SPLIT-LABEL: can_already_form_stp: ; CHECK-SPLIT: ; %bb.0: ; CHECK-SPLIT-NEXT: stp xzr, xzr, [x0, #80] ; CHECK-SPLIT-NEXT: stp xzr, xzr, [x0, #96] ; CHECK-SPLIT-NEXT: stp xzr, xzr, [x0, #112] ; CHECK-SPLIT-NEXT: ret %bigoffset = getelementptr i64, ptr %p, i64 10 store i64 0, ptr %bigoffset %addr2 = getelementptr i64, ptr %p, i64 11 store i64 0, ptr %addr2 %addr3 = getelementptr i64, ptr %p, i64 12 store i64 0, ptr %addr3 %addr4 = getelementptr i64, ptr %p, i64 13 store i64 0, ptr %addr4 %addr5 = getelementptr i64, ptr %p, i64 14 store i64 0, ptr %addr5 %addr6 = getelementptr i64, ptr %p, i64 15 store i64 0, ptr %addr6 ret void } define void @use_of_load_in_between(ptr %p, ptr %ldptr, ptr %ldptr2) { ; CHECK-NO-SPLIT-LABEL: use_of_load_in_between: ; CHECK-NO-SPLIT: ; %bb.0: ; CHECK-NO-SPLIT-NEXT: str xzr, [x0, #8000] ; CHECK-NO-SPLIT-NEXT: ldr x8, [x1] ; CHECK-NO-SPLIT-NEXT: str xzr, [x0, #8016] ; CHECK-NO-SPLIT-NEXT: str x8, [x0, #8008] ; CHECK-NO-SPLIT-NEXT: ldr x8, [x2] ; CHECK-NO-SPLIT-NEXT: str xzr, [x0, #8032] ; CHECK-NO-SPLIT-NEXT: str xzr, [x0, #8040] ; CHECK-NO-SPLIT-NEXT: str x8, [x0, #8024] ; CHECK-NO-SPLIT-NEXT: ret ; ; CHECK-SPLIT-LABEL: use_of_load_in_between: ; CHECK-SPLIT: ; %bb.0: ; CHECK-SPLIT-NEXT: str xzr, [x0, #8000] ; CHECK-SPLIT-NEXT: ldr x8, [x1] ; CHECK-SPLIT-NEXT: str xzr, [x0, #8016] ; CHECK-SPLIT-NEXT: str x8, [x0, #8008] ; CHECK-SPLIT-NEXT: ldr x8, [x2] ; CHECK-SPLIT-NEXT: str xzr, [x0, #8032] ; CHECK-SPLIT-NEXT: str xzr, [x0, #8040] ; CHECK-SPLIT-NEXT: str x8, [x0, #8024] ; CHECK-SPLIT-NEXT: ret %bigoffset = getelementptr i64, ptr %p, i64 1000 store i64 0, ptr %bigoffset %addr2 = getelementptr i64, ptr %p, i64 1001 %ld = load i64, ptr %ldptr store i64 %ld, ptr %addr2 %addr3 = getelementptr i64, ptr %p, i64 1002 store i64 0, ptr %addr3 %addr4 = getelementptr i64, ptr %p, i64 1003 %ld2 = load i64, ptr %ldptr2 store i64 %ld2, ptr %addr4 %addr5 = getelementptr i64, ptr %p, i64 1004 store i64 0, ptr %addr5 %addr6 = getelementptr i64, ptr %p, i64 1005 store i64 0, ptr %addr6 ret void } define void @offset_legal_for_add_imm(ptr %p) { ; CHECK-NO-SPLIT-LABEL: offset_legal_for_add_imm: ; CHECK-NO-SPLIT: ; %bb.0: ; CHECK-NO-SPLIT-NEXT: str xzr, [x0, #3200] ; CHECK-NO-SPLIT-NEXT: str xzr, [x0, #3208] ; CHECK-NO-SPLIT-NEXT: str xzr, [x0, #3216] ; CHECK-NO-SPLIT-NEXT: ret ; ; CHECK-SPLIT-LABEL: offset_legal_for_add_imm: ; CHECK-SPLIT: ; %bb.0: ; CHECK-SPLIT-NEXT: add x8, x0, #3200 ; CHECK-SPLIT-NEXT: stp xzr, xzr, [x8] ; CHECK-SPLIT-NEXT: str xzr, [x8, #16] ; CHECK-SPLIT-NEXT: ret %bigoffset = getelementptr i64, ptr %p, i64 400 store i64 0, ptr %bigoffset %addr2 = getelementptr i64, ptr %p, i64 401 store i64 0, ptr %addr2 %addr3 = getelementptr i64, ptr %p, i64 402 store i64 0, ptr %addr3 ret void } define void @offset_illegal_for_add_imm(ptr %p) { ; CHECK-NO-SPLIT-LABEL: offset_illegal_for_add_imm: ; CHECK-NO-SPLIT: ; %bb.0: ; CHECK-NO-SPLIT-NEXT: str xzr, [x0, #8000] ; CHECK-NO-SPLIT-NEXT: str xzr, [x0, #8008] ; CHECK-NO-SPLIT-NEXT: str xzr, [x0, #8016] ; CHECK-NO-SPLIT-NEXT: ret ; ; CHECK-SPLIT-LABEL: offset_illegal_for_add_imm: ; CHECK-SPLIT: ; %bb.0: ; CHECK-SPLIT-NEXT: str xzr, [x0, #8000] ; CHECK-SPLIT-NEXT: str xzr, [x0, #8008] ; CHECK-SPLIT-NEXT: str xzr, [x0, #8016] ; CHECK-SPLIT-NEXT: ret %bigoffset = getelementptr i64, ptr %p, i64 1000 store i64 0, ptr %bigoffset %addr2 = getelementptr i64, ptr %p, i64 1001 store i64 0, ptr %addr2 %addr3 = getelementptr i64, ptr %p, i64 1002 store i64 0, ptr %addr3 ret void } define void @offset_legal_for_add_imm_4_stores(ptr %p) { ; CHECK-NO-SPLIT-LABEL: offset_legal_for_add_imm_4_stores: ; CHECK-NO-SPLIT: ; %bb.0: ; CHECK-NO-SPLIT-NEXT: str xzr, [x0, #3200] ; CHECK-NO-SPLIT-NEXT: str xzr, [x0, #3208] ; CHECK-NO-SPLIT-NEXT: str xzr, [x0, #3216] ; CHECK-NO-SPLIT-NEXT: str xzr, [x0, #3224] ; CHECK-NO-SPLIT-NEXT: ret ; ; CHECK-SPLIT-LABEL: offset_legal_for_add_imm_4_stores: ; CHECK-SPLIT: ; %bb.0: ; CHECK-SPLIT-NEXT: add x8, x0, #3200 ; CHECK-SPLIT-NEXT: stp xzr, xzr, [x8] ; CHECK-SPLIT-NEXT: stp xzr, xzr, [x8, #16] ; CHECK-SPLIT-NEXT: ret %bigoffset = getelementptr i64, ptr %p, i64 400 store i64 0, ptr %bigoffset %addr2 = getelementptr i64, ptr %p, i64 401 store i64 0, ptr %addr2 %addr3 = getelementptr i64, ptr %p, i64 402 store i64 0, ptr %addr3 %addr4 = getelementptr i64, ptr %p, i64 403 store i64 0, ptr %addr4 ret void } define void @offset_illegal_for_add_imm_4_stores(ptr %p) { ; CHECK-NO-SPLIT-LABEL: offset_illegal_for_add_imm_4_stores: ; CHECK-NO-SPLIT: ; %bb.0: ; CHECK-NO-SPLIT-NEXT: str xzr, [x0, #8000] ; CHECK-NO-SPLIT-NEXT: str xzr, [x0, #8008] ; CHECK-NO-SPLIT-NEXT: str xzr, [x0, #8016] ; CHECK-NO-SPLIT-NEXT: str xzr, [x0, #8024] ; CHECK-NO-SPLIT-NEXT: ret ; ; CHECK-SPLIT-LABEL: offset_illegal_for_add_imm_4_stores: ; CHECK-SPLIT: ; %bb.0: ; CHECK-SPLIT-NEXT: mov w8, #8000 ; =0x1f40 ; CHECK-SPLIT-NEXT: add x8, x0, x8 ; CHECK-SPLIT-NEXT: stp xzr, xzr, [x8] ; CHECK-SPLIT-NEXT: stp xzr, xzr, [x8, #16] ; CHECK-SPLIT-NEXT: ret %bigoffset = getelementptr i64, ptr %p, i64 1000 store i64 0, ptr %bigoffset %addr2 = getelementptr i64, ptr %p, i64 1001 store i64 0, ptr %addr2 %addr3 = getelementptr i64, ptr %p, i64 1002 store i64 0, ptr %addr3 %addr4 = getelementptr i64, ptr %p, i64 1003 store i64 0, ptr %addr4 ret void }