1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=aarch64-apple-ios \ 3; RUN: -aarch64-enable-collect-loh=false -aarch64-enable-global-merge \ 4; RUN: -global-merge-group-by-use -global-merge-ignore-single-use=false %s \ 5; RUN: -o - | FileCheck %s 6 7; We assume that globals of the same size aren't reordered inside a set. 8 9; Check that we create two MergedGlobal instances for two functions using 10; disjoint sets of globals 11 12@m1 = internal global i32 0, align 4 13@n1 = internal global i32 0, align 4 14 15define void @f1(i32 %a1, i32 %a2) #0 { 16; CHECK-LABEL: f1: 17; CHECK: ; %bb.0: 18; CHECK-NEXT: adrp x8, __MergedGlobals.2@PAGE 19; CHECK-NEXT: add x8, x8, __MergedGlobals.2@PAGEOFF 20; CHECK-NEXT: stp w0, w1, [x8] 21; CHECK-NEXT: ret 22 store i32 %a1, ptr @m1, align 4 23 store i32 %a2, ptr @n1, align 4 24 ret void 25} 26 27@m2 = internal global i32 0, align 4 28@n2 = internal global i32 0, align 4 29@o2 = internal global i32 0, align 4 30 31define void @f2(i32 %a1, i32 %a2, i32 %a3) #0 { 32; CHECK-LABEL: f2: 33; CHECK: ; %bb.0: 34; CHECK-NEXT: adrp x8, __MergedGlobals.1@PAGE 35; CHECK-NEXT: add x8, x8, __MergedGlobals.1@PAGEOFF 36; CHECK-NEXT: stp w0, w1, [x8] 37; CHECK-NEXT: str w2, [x8, #8] 38; CHECK-NEXT: ret 39 store i32 %a1, ptr @m2, align 4 40 store i32 %a2, ptr @n2, align 4 41 store i32 %a3, ptr @o2, align 4 42 ret void 43} 44 45; Sanity-check (don't worry about cost models) that we pick the biggest subset 46; of all global used "together" directly or indirectly. Here, that means 47; merging n3, m4, and n4 together, but ignoring m3. 48 49@m3 = internal global i32 0, align 4 50@n3 = internal global i32 0, align 4 51 52define void @f3(i32 %a1, i32 %a2) #0 { 53; CHECK-LABEL: f3: 54; CHECK: ; %bb.0: 55; CHECK-NEXT: adrp x8, _m3@PAGE 56; CHECK-NEXT: adrp x9, __MergedGlobals@PAGE 57; CHECK-NEXT: str w0, [x8, _m3@PAGEOFF] 58; CHECK-NEXT: str w1, [x9, __MergedGlobals@PAGEOFF] 59; CHECK-NEXT: ret 60 store i32 %a1, ptr @m3, align 4 61 store i32 %a2, ptr @n3, align 4 62 ret void 63} 64 65@m4 = internal global i32 0, align 4 66@n4 = internal global i32 0, align 4 67 68define void @f4(i32 %a1, i32 %a2, i32 %a3) #0 { 69; CHECK-LABEL: f4: 70; CHECK: ; %bb.0: 71; CHECK-NEXT: adrp x8, __MergedGlobals@PAGE 72; CHECK-NEXT: add x8, x8, __MergedGlobals@PAGEOFF 73; CHECK-NEXT: stp w0, w1, [x8, #4] 74; CHECK-NEXT: str w2, [x8] 75; CHECK-NEXT: ret 76 store i32 %a1, ptr @m4, align 4 77 store i32 %a2, ptr @n4, align 4 78 store i32 %a3, ptr @n3, align 4 79 ret void 80} 81 82; Finally, check that we don't do anything with one-element global sets. 83@o5 = internal global i32 0, align 4 84 85define void @f5(i32 %a1) #0 { 86; CHECK-LABEL: f5: 87; CHECK: ; %bb.0: 88; CHECK-NEXT: adrp x8, _o5@PAGE 89; CHECK-NEXT: str w0, [x8, _o5@PAGEOFF] 90; CHECK-NEXT: ret 91 store i32 %a1, ptr @o5, align 4 92 ret void 93} 94 95; CHECK-DAG: .zerofill __DATA,__bss,_o5,4,2 96 97; CHECK-DAG: .zerofill __DATA,__bss,__MergedGlobals.2,8,2 98; CHECK-DAG: .zerofill __DATA,__bss,__MergedGlobals.1,12,2 99; CHECK-DAG: .zerofill __DATA,__bss,__MergedGlobals,12,2 100 101attributes #0 = { nounwind } 102