; 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> <i64 0, i64 0>, ptr %bigoffset
%addr2 = getelementptr <2 x i64>, ptr %p, i64 1001
store <2 x i64> <i64 0, i64 0>, ptr %addr2
%addr3 = getelementptr <2 x i64>, ptr %p, i64 1002
store <2 x i64> <i64 0, i64 0>, ptr %addr3
%addr4 = getelementptr <2 x i64>, ptr %p, i64 1003
store <2 x i64> <i64 0, i64 0>, ptr %addr4
%addr5 = getelementptr <2 x i64>, ptr %p, i64 1004
store <2 x i64> <i64 0, i64 0>, ptr %addr5
%addr6 = getelementptr <2 x i64>, ptr %p, i64 1005
store <2 x i64> <i64 0, i64 0>, ptr %addr6
%addr7 = getelementptr <2 x i64>, ptr %p, i64 1006
store <2 x i64> <i64 0, i64 0>, ptr %addr7
%addr8 = getelementptr <2 x i64>, ptr %p, i64 1007
store <2 x i64> <i64 0, i64 0>, 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
}