222 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=dse -S | FileCheck %s3 4target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"5declare void @unknown_func()6declare void @llvm.memcpy.p0.p0.i64(ptr nocapture, ptr nocapture, i64, i1) nounwind7declare void @llvm.memset.p0.i64(ptr nocapture, i8, i64, i32, i1) nounwind8 9; Tests where the pointer/object is accessible after the function returns.10 11; Overwriting store along one path to the exit.12define void @accessible_after_return_1(ptr noalias %P, i1 %c) {13; CHECK-LABEL: @accessible_after_return_1(14; CHECK-NEXT: entry:15; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 116; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[ARRAYIDX0]], i8 0, i64 28, i1 false)17; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]18; CHECK: bb1:19; CHECK-NEXT: br label [[BB3:%.*]]20; CHECK: bb2:21; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 122; CHECK-NEXT: store i32 1, ptr [[ARRAYIDX1]], align 423; CHECK-NEXT: br label [[BB3]]24; CHECK: bb3:25; CHECK-NEXT: ret void26;27entry:28 %arrayidx0 = getelementptr inbounds i32, ptr %P, i64 129 call void @llvm.memset.p0.i64(ptr %arrayidx0, i8 0, i64 28, i32 4, i1 false)30 br i1 %c, label %bb1, label %bb231 32bb1:33 br label %bb334 35bb2:36 %arrayidx1 = getelementptr inbounds i32, ptr %P, i64 137 store i32 1, ptr %arrayidx1, align 438 br label %bb339 40bb3:41 ret void42}43 44; Post-dominating store.45; TODO: The memset can be shortened.46define void @accessible_after_return_2(ptr noalias %P, i1 %c) {47; CHECK-LABEL: @accessible_after_return_2(48; CHECK-NEXT: entry:49; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 150; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[ARRAYIDX0]], i8 0, i64 28, i1 false)51; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]52; CHECK: bb1:53; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 154; CHECK-NEXT: store i32 1, ptr [[ARRAYIDX1]], align 455; CHECK-NEXT: br label [[BB3:%.*]]56; CHECK: bb2:57; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 158; CHECK-NEXT: store i32 1, ptr [[ARRAYIDX2]], align 459; CHECK-NEXT: br label [[BB3]]60; CHECK: bb3:61; CHECK-NEXT: ret void62;63entry:64 %arrayidx0 = getelementptr inbounds i32, ptr %P, i64 165 call void @llvm.memset.p0.i64(ptr %arrayidx0, i8 0, i64 28, i32 4, i1 false)66 br i1 %c, label %bb1, label %bb267 68bb1:69 %arrayidx1 = getelementptr inbounds i32, ptr %P, i64 170 store i32 1, ptr %arrayidx1, align 471 br label %bb372 73bb2:74 %arrayidx2 = getelementptr inbounds i32, ptr %P, i64 175 store i32 1, ptr %arrayidx2, align 476 br label %bb377 78bb3:79 ret void80}81 82; Stores along both exit paths.83define void @accessible_after_return_3(ptr noalias %P, i1 %c) {84; CHECK-LABEL: @accessible_after_return_3(85; CHECK-NEXT: entry:86; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 187; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[ARRAYIDX0]], i64 488; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[TMP0]], i8 0, i64 24, i1 false)89; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]90; CHECK: bb1:91; CHECK-NEXT: br label [[BB3:%.*]]92; CHECK: bb2:93; CHECK-NEXT: br label [[BB3]]94; CHECK: bb3:95; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 196; CHECK-NEXT: store i32 1, ptr [[ARRAYIDX1]], align 497; CHECK-NEXT: ret void98;99entry:100 %arrayidx0 = getelementptr inbounds i32, ptr %P, i64 1101 call void @llvm.memset.p0.i64(ptr %arrayidx0, i8 0, i64 28, i32 4, i1 false)102 br i1 %c, label %bb1, label %bb2103 104bb1:105 br label %bb3106 107bb2:108 br label %bb3109 110bb3:111 %arrayidx1 = getelementptr inbounds i32, ptr %P, i64 1112 store i32 1, ptr %arrayidx1, align 4113 ret void114}115 116 117declare void @readonly_use(ptr nocapture) readonly118 119; Tests where the pointer/object is *NOT* accessible after the function returns.120 121; Overwriting store along one path to the exit.122define void @alloca_1(i1 %c) {123; CHECK-LABEL: @alloca_1(124; CHECK-NEXT: entry:125; CHECK-NEXT: [[P_ALLOCA:%.*]] = alloca [32 x i32], align 4126; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, ptr [[P_ALLOCA]], i64 1127; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[ARRAYIDX0]], i8 0, i64 28, i1 false)128; CHECK-NEXT: call void @readonly_use(ptr [[P_ALLOCA]])129; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]130; CHECK: bb1:131; CHECK-NEXT: br label [[BB3:%.*]]132; CHECK: bb2:133; CHECK-NEXT: br label [[BB3]]134; CHECK: bb3:135; CHECK-NEXT: ret void136;137entry:138 %P.alloca = alloca [32 x i32]139 %arrayidx0 = getelementptr inbounds i32, ptr %P.alloca, i64 1140 call void @llvm.memset.p0.i64(ptr %arrayidx0, i8 0, i64 28, i32 4, i1 false)141 call void @readonly_use(ptr %P.alloca)142 br i1 %c, label %bb1, label %bb2143 144bb1:145 br label %bb3146 147bb2:148 %arrayidx1 = getelementptr inbounds i32, ptr %P.alloca, i64 1149 store i32 1, ptr %arrayidx1, align 4150 br label %bb3151 152bb3:153 ret void154}155 156; Post-dominating store.157define void @alloca_2(i1 %c) {158; CHECK-LABEL: @alloca_2(159; CHECK-NEXT: entry:160; CHECK-NEXT: [[P_ALLOCA:%.*]] = alloca [32 x i32], align 4161; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, ptr [[P_ALLOCA]], i64 1162; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[ARRAYIDX0]], i8 0, i64 28, i1 false)163; CHECK-NEXT: call void @readonly_use(ptr [[P_ALLOCA]])164; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]165; CHECK: bb1:166; CHECK-NEXT: br label [[BB3:%.*]]167; CHECK: bb2:168; CHECK-NEXT: br label [[BB3]]169; CHECK: bb3:170; CHECK-NEXT: ret void171;172entry:173 %P.alloca = alloca [32 x i32]174 %arrayidx0 = getelementptr inbounds i32, ptr %P.alloca, i64 1175 call void @llvm.memset.p0.i64(ptr %arrayidx0, i8 0, i64 28, i32 4, i1 false)176 call void @readonly_use(ptr %P.alloca)177 br i1 %c, label %bb1, label %bb2178 179bb1:180 %arrayidx1 = getelementptr inbounds i32, ptr %P.alloca, i64 1181 store i32 1, ptr %arrayidx1, align 4182 br label %bb3183 184bb2:185 %arrayidx2 = getelementptr inbounds i32, ptr %P.alloca, i64 1186 store i32 1, ptr %arrayidx2, align 4187 br label %bb3188 189bb3:190 ret void191}192 193; Stores along both exit paths.194define void @alloca_3(i1 %c) {195; CHECK-LABEL: @alloca_3(196; CHECK-NEXT: entry:197; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]198; CHECK: bb1:199; CHECK-NEXT: br label [[BB3:%.*]]200; CHECK: bb2:201; CHECK-NEXT: br label [[BB3]]202; CHECK: bb3:203; CHECK-NEXT: ret void204;205entry:206 %P.alloca = alloca [32 x i32]207 %arrayidx0 = getelementptr inbounds i32, ptr %P.alloca, i64 1208 call void @llvm.memset.p0.i64(ptr %arrayidx0, i8 0, i64 28, i32 4, i1 false)209 br i1 %c, label %bb1, label %bb2210 211bb1:212 br label %bb3213 214bb2:215 br label %bb3216 217bb3:218 %arrayidx1 = getelementptr inbounds i32, ptr %P.alloca, i64 1219 store i32 1, ptr %arrayidx1, align 4220 ret void221}222