403 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=memcpyopt -S -verify-memoryssa | FileCheck %s3 4; All the stores in this example should be merged into a single memset.5 6target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"7target triple = "i386-apple-darwin8"8 9define void @test1(i8 signext %c) nounwind {10; CHECK-LABEL: @test1(11; CHECK-NEXT: entry:12; CHECK-NEXT: [[X:%.*]] = alloca [19 x i8], align 113; CHECK-NEXT: [[TMP:%.*]] = getelementptr [19 x i8], ptr [[X]], i32 0, i32 014; CHECK-NEXT: [[TMP5:%.*]] = getelementptr [19 x i8], ptr [[X]], i32 0, i32 115; CHECK-NEXT: [[TMP9:%.*]] = getelementptr [19 x i8], ptr [[X]], i32 0, i32 216; CHECK-NEXT: [[TMP13:%.*]] = getelementptr [19 x i8], ptr [[X]], i32 0, i32 317; CHECK-NEXT: [[TMP17:%.*]] = getelementptr [19 x i8], ptr [[X]], i32 0, i32 418; CHECK-NEXT: [[TMP21:%.*]] = getelementptr [19 x i8], ptr [[X]], i32 0, i32 519; CHECK-NEXT: [[TMP25:%.*]] = getelementptr [19 x i8], ptr [[X]], i32 0, i32 620; CHECK-NEXT: [[TMP29:%.*]] = getelementptr [19 x i8], ptr [[X]], i32 0, i32 721; CHECK-NEXT: [[TMP33:%.*]] = getelementptr [19 x i8], ptr [[X]], i32 0, i32 822; CHECK-NEXT: [[TMP37:%.*]] = getelementptr [19 x i8], ptr [[X]], i32 0, i32 923; CHECK-NEXT: [[TMP41:%.*]] = getelementptr [19 x i8], ptr [[X]], i32 0, i32 1024; CHECK-NEXT: [[TMP45:%.*]] = getelementptr [19 x i8], ptr [[X]], i32 0, i32 1125; CHECK-NEXT: [[TMP49:%.*]] = getelementptr [19 x i8], ptr [[X]], i32 0, i32 1226; CHECK-NEXT: [[TMP53:%.*]] = getelementptr [19 x i8], ptr [[X]], i32 0, i32 1327; CHECK-NEXT: [[TMP57:%.*]] = getelementptr [19 x i8], ptr [[X]], i32 0, i32 1428; CHECK-NEXT: [[TMP61:%.*]] = getelementptr [19 x i8], ptr [[X]], i32 0, i32 1529; CHECK-NEXT: [[TMP65:%.*]] = getelementptr [19 x i8], ptr [[X]], i32 0, i32 1630; CHECK-NEXT: [[TMP69:%.*]] = getelementptr [19 x i8], ptr [[X]], i32 0, i32 1731; CHECK-NEXT: [[TMP73:%.*]] = getelementptr [19 x i8], ptr [[X]], i32 0, i32 1832; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[TMP]], i8 [[C:%.*]], i64 19, i1 false)33; CHECK-NEXT: [[TMP76:%.*]] = call i32 (...) @bar(ptr [[X]]) #[[ATTR0:[0-9]+]]34; CHECK-NEXT: ret void35;36entry:37 %x = alloca [19 x i8] ; <ptr> [#uses=20]38 %tmp = getelementptr [19 x i8], ptr %x, i32 0, i32 0 ; <ptr> [#uses=1]39 store i8 %c, ptr %tmp, align 140 %tmp5 = getelementptr [19 x i8], ptr %x, i32 0, i32 1 ; <ptr> [#uses=1]41 store i8 %c, ptr %tmp5, align 142 %tmp9 = getelementptr [19 x i8], ptr %x, i32 0, i32 2 ; <ptr> [#uses=1]43 store i8 %c, ptr %tmp9, align 144 %tmp13 = getelementptr [19 x i8], ptr %x, i32 0, i32 3 ; <ptr> [#uses=1]45 store i8 %c, ptr %tmp13, align 146 %tmp17 = getelementptr [19 x i8], ptr %x, i32 0, i32 4 ; <ptr> [#uses=1]47 store i8 %c, ptr %tmp17, align 148 %tmp21 = getelementptr [19 x i8], ptr %x, i32 0, i32 5 ; <ptr> [#uses=1]49 store i8 %c, ptr %tmp21, align 150 %tmp25 = getelementptr [19 x i8], ptr %x, i32 0, i32 6 ; <ptr> [#uses=1]51 store i8 %c, ptr %tmp25, align 152 %tmp29 = getelementptr [19 x i8], ptr %x, i32 0, i32 7 ; <ptr> [#uses=1]53 store i8 %c, ptr %tmp29, align 154 %tmp33 = getelementptr [19 x i8], ptr %x, i32 0, i32 8 ; <ptr> [#uses=1]55 store i8 %c, ptr %tmp33, align 156 %tmp37 = getelementptr [19 x i8], ptr %x, i32 0, i32 9 ; <ptr> [#uses=1]57 store i8 %c, ptr %tmp37, align 158 %tmp41 = getelementptr [19 x i8], ptr %x, i32 0, i32 10 ; <ptr> [#uses=1]59 store i8 %c, ptr %tmp41, align 160 %tmp45 = getelementptr [19 x i8], ptr %x, i32 0, i32 11 ; <ptr> [#uses=1]61 store i8 %c, ptr %tmp45, align 162 %tmp49 = getelementptr [19 x i8], ptr %x, i32 0, i32 12 ; <ptr> [#uses=1]63 store i8 %c, ptr %tmp49, align 164 %tmp53 = getelementptr [19 x i8], ptr %x, i32 0, i32 13 ; <ptr> [#uses=1]65 store i8 %c, ptr %tmp53, align 166 %tmp57 = getelementptr [19 x i8], ptr %x, i32 0, i32 14 ; <ptr> [#uses=1]67 store i8 %c, ptr %tmp57, align 168 %tmp61 = getelementptr [19 x i8], ptr %x, i32 0, i32 15 ; <ptr> [#uses=1]69 store i8 %c, ptr %tmp61, align 170 %tmp65 = getelementptr [19 x i8], ptr %x, i32 0, i32 16 ; <ptr> [#uses=1]71 store i8 %c, ptr %tmp65, align 172 %tmp69 = getelementptr [19 x i8], ptr %x, i32 0, i32 17 ; <ptr> [#uses=1]73 store i8 %c, ptr %tmp69, align 174 %tmp73 = getelementptr [19 x i8], ptr %x, i32 0, i32 18 ; <ptr> [#uses=1]75 store i8 %c, ptr %tmp73, align 176 %tmp76 = call i32 (...) @bar( ptr %x ) nounwind77 ret void78}79 80declare i32 @bar(...)81 82%struct.MV = type { i16, i16 }83 84 85define void @test2() nounwind {86; CHECK-LABEL: @test2(87; CHECK-NEXT: entry:88; CHECK-NEXT: [[REF_IDX:%.*]] = alloca [8 x i8], align 189; CHECK-NEXT: [[LEFT_MVD:%.*]] = alloca [8 x %struct.MV], align 890; CHECK-NEXT: [[UP_MVD:%.*]] = alloca [8 x %struct.MV], align 891; CHECK-NEXT: [[TMP20:%.*]] = getelementptr [8 x i8], ptr [[REF_IDX]], i32 0, i32 792; CHECK-NEXT: [[TMP23:%.*]] = getelementptr [8 x i8], ptr [[REF_IDX]], i32 0, i32 693; CHECK-NEXT: [[TMP26:%.*]] = getelementptr [8 x i8], ptr [[REF_IDX]], i32 0, i32 594; CHECK-NEXT: [[TMP29:%.*]] = getelementptr [8 x i8], ptr [[REF_IDX]], i32 0, i32 495; CHECK-NEXT: [[TMP32:%.*]] = getelementptr [8 x i8], ptr [[REF_IDX]], i32 0, i32 396; CHECK-NEXT: [[TMP35:%.*]] = getelementptr [8 x i8], ptr [[REF_IDX]], i32 0, i32 297; CHECK-NEXT: [[TMP38:%.*]] = getelementptr [8 x i8], ptr [[REF_IDX]], i32 0, i32 198; CHECK-NEXT: [[TMP41:%.*]] = getelementptr [8 x i8], ptr [[REF_IDX]], i32 0, i32 099; CHECK-NEXT: [[TMP43:%.*]] = getelementptr [8 x %struct.MV], ptr [[UP_MVD]], i32 0, i32 7, i32 0100; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[TMP41]], i8 -1, i64 8, i1 false)101; CHECK-NEXT: [[TMP46:%.*]] = getelementptr [8 x %struct.MV], ptr [[UP_MVD]], i32 0, i32 7, i32 1102; CHECK-NEXT: [[TMP57:%.*]] = getelementptr [8 x %struct.MV], ptr [[UP_MVD]], i32 0, i32 6, i32 0103; CHECK-NEXT: [[TMP60:%.*]] = getelementptr [8 x %struct.MV], ptr [[UP_MVD]], i32 0, i32 6, i32 1104; CHECK-NEXT: [[TMP71:%.*]] = getelementptr [8 x %struct.MV], ptr [[UP_MVD]], i32 0, i32 5, i32 0105; CHECK-NEXT: [[TMP74:%.*]] = getelementptr [8 x %struct.MV], ptr [[UP_MVD]], i32 0, i32 5, i32 1106; CHECK-NEXT: [[TMP85:%.*]] = getelementptr [8 x %struct.MV], ptr [[UP_MVD]], i32 0, i32 4, i32 0107; CHECK-NEXT: [[TMP88:%.*]] = getelementptr [8 x %struct.MV], ptr [[UP_MVD]], i32 0, i32 4, i32 1108; CHECK-NEXT: [[TMP99:%.*]] = getelementptr [8 x %struct.MV], ptr [[UP_MVD]], i32 0, i32 3, i32 0109; CHECK-NEXT: [[TMP102:%.*]] = getelementptr [8 x %struct.MV], ptr [[UP_MVD]], i32 0, i32 3, i32 1110; CHECK-NEXT: [[TMP113:%.*]] = getelementptr [8 x %struct.MV], ptr [[UP_MVD]], i32 0, i32 2, i32 0111; CHECK-NEXT: [[TMP116:%.*]] = getelementptr [8 x %struct.MV], ptr [[UP_MVD]], i32 0, i32 2, i32 1112; CHECK-NEXT: [[TMP127:%.*]] = getelementptr [8 x %struct.MV], ptr [[UP_MVD]], i32 0, i32 1, i32 0113; CHECK-NEXT: [[TMP130:%.*]] = getelementptr [8 x %struct.MV], ptr [[UP_MVD]], i32 0, i32 1, i32 1114; CHECK-NEXT: [[TMP141:%.*]] = getelementptr [8 x %struct.MV], ptr [[UP_MVD]], i32 0, i32 0, i32 0115; CHECK-NEXT: [[TMP144:%.*]] = getelementptr [8 x %struct.MV], ptr [[UP_MVD]], i32 0, i32 0, i32 1116; CHECK-NEXT: [[TMP148:%.*]] = getelementptr [8 x %struct.MV], ptr [[LEFT_MVD]], i32 0, i32 7, i32 0117; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP141]], i8 0, i64 32, i1 false)118; CHECK-NEXT: [[TMP151:%.*]] = getelementptr [8 x %struct.MV], ptr [[LEFT_MVD]], i32 0, i32 7, i32 1119; CHECK-NEXT: [[TMP162:%.*]] = getelementptr [8 x %struct.MV], ptr [[LEFT_MVD]], i32 0, i32 6, i32 0120; CHECK-NEXT: [[TMP165:%.*]] = getelementptr [8 x %struct.MV], ptr [[LEFT_MVD]], i32 0, i32 6, i32 1121; CHECK-NEXT: [[TMP176:%.*]] = getelementptr [8 x %struct.MV], ptr [[LEFT_MVD]], i32 0, i32 5, i32 0122; CHECK-NEXT: [[TMP179:%.*]] = getelementptr [8 x %struct.MV], ptr [[LEFT_MVD]], i32 0, i32 5, i32 1123; CHECK-NEXT: [[TMP190:%.*]] = getelementptr [8 x %struct.MV], ptr [[LEFT_MVD]], i32 0, i32 4, i32 0124; CHECK-NEXT: [[TMP193:%.*]] = getelementptr [8 x %struct.MV], ptr [[LEFT_MVD]], i32 0, i32 4, i32 1125; CHECK-NEXT: [[TMP204:%.*]] = getelementptr [8 x %struct.MV], ptr [[LEFT_MVD]], i32 0, i32 3, i32 0126; CHECK-NEXT: [[TMP207:%.*]] = getelementptr [8 x %struct.MV], ptr [[LEFT_MVD]], i32 0, i32 3, i32 1127; CHECK-NEXT: [[TMP218:%.*]] = getelementptr [8 x %struct.MV], ptr [[LEFT_MVD]], i32 0, i32 2, i32 0128; CHECK-NEXT: [[TMP221:%.*]] = getelementptr [8 x %struct.MV], ptr [[LEFT_MVD]], i32 0, i32 2, i32 1129; CHECK-NEXT: [[TMP232:%.*]] = getelementptr [8 x %struct.MV], ptr [[LEFT_MVD]], i32 0, i32 1, i32 0130; CHECK-NEXT: [[TMP235:%.*]] = getelementptr [8 x %struct.MV], ptr [[LEFT_MVD]], i32 0, i32 1, i32 1131; CHECK-NEXT: [[TMP246:%.*]] = getelementptr [8 x %struct.MV], ptr [[LEFT_MVD]], i32 0, i32 0, i32 0132; CHECK-NEXT: [[TMP249:%.*]] = getelementptr [8 x %struct.MV], ptr [[LEFT_MVD]], i32 0, i32 0, i32 1133; CHECK-NEXT: [[UP_MVD252:%.*]] = getelementptr [8 x %struct.MV], ptr [[UP_MVD]], i32 0, i32 0134; CHECK-NEXT: [[LEFT_MVD253:%.*]] = getelementptr [8 x %struct.MV], ptr [[LEFT_MVD]], i32 0, i32 0135; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP246]], i8 0, i64 32, i1 false)136; CHECK-NEXT: call void @foo(ptr [[UP_MVD252]], ptr [[LEFT_MVD253]], ptr [[TMP41]]) #[[ATTR0]]137; CHECK-NEXT: ret void138;139entry:140 %ref_idx = alloca [8 x i8] ; <ptr> [#uses=8]141 %left_mvd = alloca [8 x %struct.MV] ; <ptr> [#uses=17]142 %up_mvd = alloca [8 x %struct.MV] ; <ptr> [#uses=17]143 %tmp20 = getelementptr [8 x i8], ptr %ref_idx, i32 0, i32 7 ; <ptr> [#uses=1]144 store i8 -1, ptr %tmp20, align 1145 %tmp23 = getelementptr [8 x i8], ptr %ref_idx, i32 0, i32 6 ; <ptr> [#uses=1]146 store i8 -1, ptr %tmp23, align 1147 %tmp26 = getelementptr [8 x i8], ptr %ref_idx, i32 0, i32 5 ; <ptr> [#uses=1]148 store i8 -1, ptr %tmp26, align 1149 %tmp29 = getelementptr [8 x i8], ptr %ref_idx, i32 0, i32 4 ; <ptr> [#uses=1]150 store i8 -1, ptr %tmp29, align 1151 %tmp32 = getelementptr [8 x i8], ptr %ref_idx, i32 0, i32 3 ; <ptr> [#uses=1]152 store i8 -1, ptr %tmp32, align 1153 %tmp35 = getelementptr [8 x i8], ptr %ref_idx, i32 0, i32 2 ; <ptr> [#uses=1]154 store i8 -1, ptr %tmp35, align 1155 %tmp38 = getelementptr [8 x i8], ptr %ref_idx, i32 0, i32 1 ; <ptr> [#uses=1]156 store i8 -1, ptr %tmp38, align 1157 %tmp41 = getelementptr [8 x i8], ptr %ref_idx, i32 0, i32 0 ; <ptr> [#uses=2]158 store i8 -1, ptr %tmp41, align 1159 %tmp43 = getelementptr [8 x %struct.MV], ptr %up_mvd, i32 0, i32 7, i32 0 ; <ptr> [#uses=1]160 store i16 0, ptr %tmp43, align 2161 %tmp46 = getelementptr [8 x %struct.MV], ptr %up_mvd, i32 0, i32 7, i32 1 ; <ptr> [#uses=1]162 store i16 0, ptr %tmp46, align 2163 %tmp57 = getelementptr [8 x %struct.MV], ptr %up_mvd, i32 0, i32 6, i32 0 ; <ptr> [#uses=1]164 store i16 0, ptr %tmp57, align 2165 %tmp60 = getelementptr [8 x %struct.MV], ptr %up_mvd, i32 0, i32 6, i32 1 ; <ptr> [#uses=1]166 store i16 0, ptr %tmp60, align 2167 %tmp71 = getelementptr [8 x %struct.MV], ptr %up_mvd, i32 0, i32 5, i32 0 ; <ptr> [#uses=1]168 store i16 0, ptr %tmp71, align 2169 %tmp74 = getelementptr [8 x %struct.MV], ptr %up_mvd, i32 0, i32 5, i32 1 ; <ptr> [#uses=1]170 store i16 0, ptr %tmp74, align 2171 %tmp85 = getelementptr [8 x %struct.MV], ptr %up_mvd, i32 0, i32 4, i32 0 ; <ptr> [#uses=1]172 store i16 0, ptr %tmp85, align 2173 %tmp88 = getelementptr [8 x %struct.MV], ptr %up_mvd, i32 0, i32 4, i32 1 ; <ptr> [#uses=1]174 store i16 0, ptr %tmp88, align 2175 %tmp99 = getelementptr [8 x %struct.MV], ptr %up_mvd, i32 0, i32 3, i32 0 ; <ptr> [#uses=1]176 store i16 0, ptr %tmp99, align 2177 %tmp102 = getelementptr [8 x %struct.MV], ptr %up_mvd, i32 0, i32 3, i32 1 ; <ptr> [#uses=1]178 store i16 0, ptr %tmp102, align 2179 %tmp113 = getelementptr [8 x %struct.MV], ptr %up_mvd, i32 0, i32 2, i32 0 ; <ptr> [#uses=1]180 store i16 0, ptr %tmp113, align 2181 %tmp116 = getelementptr [8 x %struct.MV], ptr %up_mvd, i32 0, i32 2, i32 1 ; <ptr> [#uses=1]182 store i16 0, ptr %tmp116, align 2183 %tmp127 = getelementptr [8 x %struct.MV], ptr %up_mvd, i32 0, i32 1, i32 0 ; <ptr> [#uses=1]184 store i16 0, ptr %tmp127, align 2185 %tmp130 = getelementptr [8 x %struct.MV], ptr %up_mvd, i32 0, i32 1, i32 1 ; <ptr> [#uses=1]186 store i16 0, ptr %tmp130, align 2187 %tmp141 = getelementptr [8 x %struct.MV], ptr %up_mvd, i32 0, i32 0, i32 0 ; <ptr> [#uses=1]188 store i16 0, ptr %tmp141, align 8189 %tmp144 = getelementptr [8 x %struct.MV], ptr %up_mvd, i32 0, i32 0, i32 1 ; <ptr> [#uses=1]190 store i16 0, ptr %tmp144, align 2191 %tmp148 = getelementptr [8 x %struct.MV], ptr %left_mvd, i32 0, i32 7, i32 0 ; <ptr> [#uses=1]192 store i16 0, ptr %tmp148, align 2193 %tmp151 = getelementptr [8 x %struct.MV], ptr %left_mvd, i32 0, i32 7, i32 1 ; <ptr> [#uses=1]194 store i16 0, ptr %tmp151, align 2195 %tmp162 = getelementptr [8 x %struct.MV], ptr %left_mvd, i32 0, i32 6, i32 0 ; <ptr> [#uses=1]196 store i16 0, ptr %tmp162, align 2197 %tmp165 = getelementptr [8 x %struct.MV], ptr %left_mvd, i32 0, i32 6, i32 1 ; <ptr> [#uses=1]198 store i16 0, ptr %tmp165, align 2199 %tmp176 = getelementptr [8 x %struct.MV], ptr %left_mvd, i32 0, i32 5, i32 0 ; <ptr> [#uses=1]200 store i16 0, ptr %tmp176, align 2201 %tmp179 = getelementptr [8 x %struct.MV], ptr %left_mvd, i32 0, i32 5, i32 1 ; <ptr> [#uses=1]202 store i16 0, ptr %tmp179, align 2203 %tmp190 = getelementptr [8 x %struct.MV], ptr %left_mvd, i32 0, i32 4, i32 0 ; <ptr> [#uses=1]204 store i16 0, ptr %tmp190, align 2205 %tmp193 = getelementptr [8 x %struct.MV], ptr %left_mvd, i32 0, i32 4, i32 1 ; <ptr> [#uses=1]206 store i16 0, ptr %tmp193, align 2207 %tmp204 = getelementptr [8 x %struct.MV], ptr %left_mvd, i32 0, i32 3, i32 0 ; <ptr> [#uses=1]208 store i16 0, ptr %tmp204, align 2209 %tmp207 = getelementptr [8 x %struct.MV], ptr %left_mvd, i32 0, i32 3, i32 1 ; <ptr> [#uses=1]210 store i16 0, ptr %tmp207, align 2211 %tmp218 = getelementptr [8 x %struct.MV], ptr %left_mvd, i32 0, i32 2, i32 0 ; <ptr> [#uses=1]212 store i16 0, ptr %tmp218, align 2213 %tmp221 = getelementptr [8 x %struct.MV], ptr %left_mvd, i32 0, i32 2, i32 1 ; <ptr> [#uses=1]214 store i16 0, ptr %tmp221, align 2215 %tmp232 = getelementptr [8 x %struct.MV], ptr %left_mvd, i32 0, i32 1, i32 0 ; <ptr> [#uses=1]216 store i16 0, ptr %tmp232, align 2217 %tmp235 = getelementptr [8 x %struct.MV], ptr %left_mvd, i32 0, i32 1, i32 1 ; <ptr> [#uses=1]218 store i16 0, ptr %tmp235, align 2219 %tmp246 = getelementptr [8 x %struct.MV], ptr %left_mvd, i32 0, i32 0, i32 0 ; <ptr> [#uses=1]220 store i16 0, ptr %tmp246, align 8221 %tmp249 = getelementptr [8 x %struct.MV], ptr %left_mvd, i32 0, i32 0, i32 1 ; <ptr> [#uses=1]222 store i16 0, ptr %tmp249, align 2223 %up_mvd252 = getelementptr [8 x %struct.MV], ptr %up_mvd, i32 0, i32 0 ; <ptr> [#uses=1]224 %left_mvd253 = getelementptr [8 x %struct.MV], ptr %left_mvd, i32 0, i32 0 ; <ptr> [#uses=1]225 call void @foo( ptr %up_mvd252, ptr %left_mvd253, ptr %tmp41 ) nounwind226 ret void227 228}229 230declare void @foo(ptr, ptr, ptr)231 232 233; Store followed by memset.234define void @test3(ptr nocapture %P) nounwind ssp {235; CHECK-LABEL: @test3(236; CHECK-NEXT: entry:237; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 1238; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 2239; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[ARRAYIDX]], i8 0, i64 15, i1 false)240; CHECK-NEXT: ret void241;242entry:243 %arrayidx = getelementptr inbounds i32, ptr %P, i64 1244 store i32 0, ptr %arrayidx, align 4245 %add.ptr = getelementptr inbounds i32, ptr %P, i64 2246 tail call void @llvm.memset.p0.i64(ptr %add.ptr, i8 0, i64 11, i1 false)247 ret void248}249 250; store followed by memset, different offset scenario251define void @test4(ptr nocapture %P) nounwind ssp {252; CHECK-LABEL: @test4(253; CHECK-NEXT: entry:254; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 1255; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[P]], i8 0, i64 15, i1 false)256; CHECK-NEXT: ret void257;258entry:259 store i32 0, ptr %P, align 4260 %add.ptr = getelementptr inbounds i32, ptr %P, i64 1261 tail call void @llvm.memset.p0.i64(ptr %add.ptr, i8 0, i64 11, i1 false)262 ret void263}264 265declare void @llvm.memset.p0.i64(ptr nocapture, i8, i64, i1) nounwind266 267; Memset followed by store.268define void @test5(ptr nocapture %P) nounwind ssp {269; CHECK-LABEL: @test5(270; CHECK-NEXT: entry:271; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 2272; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 1273; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[ARRAYIDX]], i8 0, i64 15, i1 false)274; CHECK-NEXT: ret void275;276entry:277 %add.ptr = getelementptr inbounds i32, ptr %P, i64 2278 tail call void @llvm.memset.p0.i64(ptr %add.ptr, i8 0, i64 11, i1 false)279 %arrayidx = getelementptr inbounds i32, ptr %P, i64 1280 store i32 0, ptr %arrayidx, align 4281 ret void282}283 284;; Memset followed by memset.285define void @test6(ptr nocapture %P) nounwind ssp {286; CHECK-LABEL: @test6(287; CHECK-NEXT: entry:288; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 3289; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr [[P]], i8 0, i64 24, i1 false)290; CHECK-NEXT: ret void291;292entry:293 tail call void @llvm.memset.p0.i64(ptr %P, i8 0, i64 12, i1 false)294 %add.ptr = getelementptr inbounds i32, ptr %P, i64 3295 tail call void @llvm.memset.p0.i64(ptr %add.ptr, i8 0, i64 12, i1 false)296 ret void297}298 299; More aggressive heuristic300; rdar://9892684301define void @test7(ptr nocapture %c) nounwind optsize {302; CHECK-LABEL: @test7(303; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[C:%.*]], i32 1304; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 2305; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 3306; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 4307; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[C]], i8 -1, i64 20, i1 false)308; CHECK-NEXT: ret void309;310 store i32 -1, ptr %c, align 4311 %1 = getelementptr inbounds i32, ptr %c, i32 1312 store i32 -1, ptr %1, align 4313 %2 = getelementptr inbounds i32, ptr %c, i32 2314 store i32 -1, ptr %2, align 4315 %3 = getelementptr inbounds i32, ptr %c, i32 3316 store i32 -1, ptr %3, align 4317 %4 = getelementptr inbounds i32, ptr %c, i32 4318 store i32 -1, ptr %4, align 4319 ret void320}321 322%struct.test8 = type { [4 x i32] }323 324define void @test8() {325; CHECK-LABEL: @test8(326; CHECK-NEXT: entry:327; CHECK-NEXT: [[MEMTMP:%.*]] = alloca [[STRUCT_TEST8:%.*]], align 16328; CHECK-NEXT: store <4 x i32> splat (i32 -1), ptr [[MEMTMP]], align 16329; CHECK-NEXT: ret void330;331entry:332 %memtmp = alloca %struct.test8, align 16333 store <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, ptr %memtmp, align 16334 ret void335}336 337@test9buf = internal unnamed_addr global [16 x i64] zeroinitializer, align 16338 339define void @test9() nounwind {340; CHECK-LABEL: @test9(341; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 16 @test9buf, i8 -1, i64 16, i1 false)342; CHECK-NEXT: ret void343;344 store i8 -1, ptr @test9buf, align 16345 store i8 -1, ptr getelementptr (i8, ptr @test9buf, i64 1), align 1346 store i8 -1, ptr getelementptr (i8, ptr @test9buf, i64 2), align 2347 store i8 -1, ptr getelementptr (i8, ptr @test9buf, i64 3), align 1348 store i8 -1, ptr getelementptr (i8, ptr @test9buf, i64 4), align 4349 store i8 -1, ptr getelementptr (i8, ptr @test9buf, i64 5), align 1350 store i8 -1, ptr getelementptr (i8, ptr @test9buf, i64 6), align 2351 store i8 -1, ptr getelementptr (i8, ptr @test9buf, i64 7), align 1352 store i8 -1, ptr getelementptr inbounds ([16 x i64], ptr @test9buf, i64 0, i64 1), align 8353 store i8 -1, ptr getelementptr (i8, ptr @test9buf, i64 9), align 1354 store i8 -1, ptr getelementptr (i8, ptr @test9buf, i64 10), align 2355 store i8 -1, ptr getelementptr (i8, ptr @test9buf, i64 11), align 1356 store i8 -1, ptr getelementptr (i8, ptr @test9buf, i64 12), align 4357 store i8 -1, ptr getelementptr (i8, ptr @test9buf, i64 13), align 1358 store i8 -1, ptr getelementptr (i8, ptr @test9buf, i64 14), align 2359 store i8 -1, ptr getelementptr (i8, ptr @test9buf, i64 15), align 1360 ret void361}362 363; PR19092364define void @test10(ptr nocapture %P) nounwind {365; CHECK-LABEL: @test10(366; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr [[P:%.*]], i8 0, i64 42, i1 false)367; CHECK-NEXT: ret void368;369 tail call void @llvm.memset.p0.i64(ptr %P, i8 0, i64 42, i1 false)370 tail call void @llvm.memset.p0.i64(ptr %P, i8 0, i64 23, i1 false)371 ret void372}373 374; Memset followed by odd store.375define void @test11(ptr nocapture %P) nounwind ssp {376; CHECK-LABEL: @test11(377; CHECK-NEXT: entry:378; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 3379; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[P]], i8 1, i64 23, i1 false)380; CHECK-NEXT: ret void381;382entry:383 %add.ptr = getelementptr inbounds i32, ptr %P, i64 3384 tail call void @llvm.memset.p0.i64(ptr %add.ptr, i8 1, i64 11, i1 false)385 store i96 310698676526526814092329217, ptr %P, align 4386 ret void387}388 389; Alignment should be preserved when there is a store with default align390define void @test12(ptr nocapture %P) nounwind ssp {391; CHECK-LABEL: @test12(392; CHECK-NEXT: entry:393; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 1394; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[P]], i8 0, i64 15, i1 false)395; CHECK-NEXT: ret void396;397entry:398 store i32 0, ptr %P399 %add.ptr = getelementptr inbounds i32, ptr %P, i64 1400 tail call void @llvm.memset.p0.i64(ptr %add.ptr, i8 0, i64 11, i1 false)401 ret void402}403