1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals 2; RUN: opt -S -passes=globalopt < %s | FileCheck %s 3 4target datalayout = "p1:32:32" 5 6@llvm.global_ctors = appending global [11 x { i32, ptr, ptr }] [ 7 { i32, ptr, ptr } { i32 65535, ptr @ctor0, ptr null }, 8 { i32, ptr, ptr } { i32 65535, ptr @ctor1, ptr null }, 9 { i32, ptr, ptr } { i32 65535, ptr @ctor2, ptr null }, 10 { i32, ptr, ptr } { i32 65535, ptr @ctor3, ptr null }, 11 { i32, ptr, ptr } { i32 65535, ptr @ctor4, ptr null }, 12 { i32, ptr, ptr } { i32 65535, ptr @ctor5, ptr null }, 13 { i32, ptr, ptr } { i32 65535, ptr @ctor6, ptr null }, 14 { i32, ptr, ptr } { i32 65535, ptr @ctor7, ptr null }, 15 { i32, ptr, ptr } { i32 65535, ptr @ctor8, ptr null }, 16 { i32, ptr, ptr } { i32 65535, ptr @ctor9, ptr null }, 17 { i32, ptr, ptr } { i32 65535, ptr @ctor10, ptr null } 18] 19 20 21; memset of all-zero global 22@g0 = global { i32, i32 } zeroinitializer 23;. 24; CHECK: @[[LLVM_GLOBAL_CTORS:[a-zA-Z0-9_$"\\.-]+]] = appending global [4 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr @ctor3, ptr null }, { i32, ptr, ptr } { i32 65535, ptr @ctor4, ptr null }, { i32, ptr, ptr } { i32 65535, ptr @ctor7, ptr null }, { i32, ptr, ptr } { i32 65535, ptr @ctor10, ptr null }] 25; CHECK: @[[G0:[a-zA-Z0-9_$"\\.-]+]] = local_unnamed_addr global { i32, i32 } zeroinitializer 26; CHECK: @[[G1:[a-zA-Z0-9_$"\\.-]+]] = local_unnamed_addr global { i32, i32, i32 } { i32 0, i32 0, i32 1 } 27; CHECK: @[[G2:[a-zA-Z0-9_$"\\.-]+]] = local_unnamed_addr global { i32, i32, i32 } { i32 1, i32 0, i32 0 } 28; CHECK: @[[G3:[a-zA-Z0-9_$"\\.-]+]] = local_unnamed_addr global { i32, i32 } { i32 0, i32 1 } 29; CHECK: @[[G4:[a-zA-Z0-9_$"\\.-]+]] = local_unnamed_addr global { i32, i32 } { i32 0, i32 undef } 30; CHECK: @[[G5:[a-zA-Z0-9_$"\\.-]+]] = local_unnamed_addr global { i16, i32 } { i16 0, i32 1 } 31; CHECK: @[[G6:[a-zA-Z0-9_$"\\.-]+]] = local_unnamed_addr global { i32, i32 } { i32 -1, i32 -1 } 32; CHECK: @[[G7:[a-zA-Z0-9_$"\\.-]+]] = local_unnamed_addr global { i32, i32 } { i32 -1, i32 1 } 33; CHECK: @[[G8:[a-zA-Z0-9_$"\\.-]+]] = local_unnamed_addr addrspace(1) global { i32, i32 } zeroinitializer 34; CHECK: @[[G9:[a-zA-Z0-9_$"\\.-]+]] = local_unnamed_addr global [100000000 x i32] zeroinitializer 35; CHECK: @[[G10:[a-zA-Z0-9_$"\\.-]+]] = local_unnamed_addr global { [99999999 x i32], i32 } { [99999999 x i32] zeroinitializer, i32 1 } 36;. 37define internal void @ctor0() { 38 call void @llvm.memset.p0.i64(ptr @g0, i8 0, i64 8, i1 false) 39 ret void 40} 41 42; memset of zero prefix 43@g1 = global { i32, i32, i32 } { i32 0, i32 0, i32 1 } 44 45define internal void @ctor1() { 46 call void @llvm.memset.p0.i64(ptr @g1, i8 0, i64 8, i1 false) 47 ret void 48} 49 50; memset of zero suffix 51@g2 = global { i32, i32, i32 } { i32 1, i32 0, i32 0 } 52 53define internal void @ctor2() { 54 call void @llvm.memset.p0.i64(ptr getelementptr (i32, ptr @g2, i64 1), i8 0, i64 8, i1 false) 55 ret void 56} 57 58; memset of some non-zero bytes 59@g3 = global { i32, i32 } { i32 0, i32 1 } 60 61define internal void @ctor3() { 62; CHECK-LABEL: @ctor3( 63; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr @g3, i8 0, i64 8, i1 false) 64; CHECK-NEXT: ret void 65; 66 call void @llvm.memset.p0.i64(ptr @g3, i8 0, i64 8, i1 false) 67 ret void 68} 69 70; memset of some undef bytes 71@g4 = global { i32, i32 } { i32 0, i32 undef } 72 73define internal void @ctor4() { 74; CHECK-LABEL: @ctor4( 75; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr @g4, i8 0, i64 8, i1 false) 76; CHECK-NEXT: ret void 77; 78 call void @llvm.memset.p0.i64(ptr @g4, i8 0, i64 8, i1 false) 79 ret void 80} 81 82; memset including padding bytes 83; FIXME: We still incorrectly optimize the memset away here, even though code 84; might access the padding. 85@g5 = global { i16, i32 } { i16 0, i32 1 } 86 87define internal void @ctor5() { 88 call void @llvm.memset.p0.i64(ptr @g5, i8 0, i64 4, i1 false) 89 ret void 90} 91 92; memset of non-zero value (matching initializer) 93@g6 = global { i32, i32 } { i32 -1, i32 -1 } 94 95define internal void @ctor6() { 96 call void @llvm.memset.p0.i64(ptr @g6, i8 -1, i64 8, i1 false) 97 ret void 98} 99 100; memset of non-zero value (not matching initializer) 101@g7 = global { i32, i32 } { i32 -1, i32 1 } 102 103define internal void @ctor7() { 104; CHECK-LABEL: @ctor7( 105; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr @g7, i8 -1, i64 8, i1 false) 106; CHECK-NEXT: ret void 107; 108 call void @llvm.memset.p0.i64(ptr @g7, i8 -1, i64 8, i1 false) 109 ret void 110} 111 112; memset of zero value in differently-sized address space 113@g8 = addrspace(1) global { i32, i32 } zeroinitializer 114 115define internal void @ctor8() { 116 call void @llvm.memset.p0.i64(ptr addrspacecast (ptr addrspace(1) @g8 to ptr), i8 0, i64 8, i1 false) 117 ret void 118} 119 120@g9 = global [100000000 x i32] zeroinitializer 121 122define internal void @ctor9() { 123 call void @llvm.memset.p0.i64(ptr @g9, i8 0, i64 100000000, i1 false) 124 ret void 125} 126 127@g10 = global { [99999999 x i32], i32 } { [99999999 x i32 ] zeroinitializer, i32 1 } 128 129define internal void @ctor10() { 130; CHECK-LABEL: @ctor10( 131; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr @g10, i8 0, i64 100000000, i1 false) 132; CHECK-NEXT: ret void 133; 134 call void @llvm.memset.p0.i64(ptr @g10, i8 0, i64 100000000, i1 false) 135 ret void 136} 137 138declare void @llvm.memset.p0.i64(ptr, i8, i64, i1) 139;. 140; CHECK: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: write) } 141;. 142