1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes=dse %s -S | FileCheck --check-prefixes=CHECK %s 3 4 5%struct.ham = type { [3 x double], [3 x double]} 6 7declare void @may_throw() 8declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1 immarg) 9 10; We miss this case, because of an aggressive limit of partial overlap analysis. 11; With a larger partial store limit, we remove the memset. 12define void @overlap1(ptr %arg, i1 %cond) { 13; CHECK-LABEL: @overlap1( 14; CHECK-NEXT: bb: 15; CHECK-NEXT: [[TMP:%.*]] = getelementptr inbounds [[STRUCT_HAM:%.*]], ptr [[ARG:%.*]], i64 0, i32 0, i64 2 16; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT_HAM]], ptr [[ARG]], i64 0, i32 0, i64 1 17; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds [[STRUCT_HAM]], ptr [[ARG]], i64 0, i32 1, i64 2 18; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds [[STRUCT_HAM]], ptr [[ARG]], i64 0, i32 1, i64 1 19; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT_HAM]], ptr [[ARG]], i64 0, i32 1, i32 0 20; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB7:%.*]], label [[BB8:%.*]] 21; CHECK: bb7: 22; CHECK-NEXT: br label [[BB9:%.*]] 23; CHECK: bb8: 24; CHECK-NEXT: br label [[BB9]] 25; CHECK: bb9: 26; CHECK-NEXT: store double 1.000000e+00, ptr [[ARG]], align 8 27; CHECK-NEXT: store double 2.000000e+00, ptr [[TMP1]], align 8 28; CHECK-NEXT: store double 3.000000e+00, ptr [[TMP]], align 8 29; CHECK-NEXT: store double 4.000000e+00, ptr [[TMP5]], align 8 30; CHECK-NEXT: store double 5.000000e+00, ptr [[TMP4]], align 8 31; CHECK-NEXT: store double 6.000000e+00, ptr [[TMP3]], align 8 32; CHECK-NEXT: ret void 33; 34bb: 35 %tmp = getelementptr inbounds %struct.ham, ptr %arg, i64 0, i32 0, i64 2 36 %tmp1 = getelementptr inbounds %struct.ham, ptr %arg, i64 0, i32 0, i64 1 37 %tmp3 = getelementptr inbounds %struct.ham, ptr %arg, i64 0,i32 1, i64 2 38 %tmp4 = getelementptr inbounds %struct.ham, ptr %arg, i64 0, i32 1, i64 1 39 %tmp5 = getelementptr inbounds %struct.ham, ptr %arg, i64 0, i32 1, i32 0 40 call void @llvm.memset.p0.i64(ptr nonnull align 8 dereferenceable(48) %arg, i8 0, i64 48, i1 false) 41 br i1 %cond, label %bb7, label %bb8 42 43bb7: ; preds = %bb 44 br label %bb9 45 46bb8: ; preds = %bb 47 br label %bb9 48 49bb9: ; preds = %bb8, %bb7 50 store double 1.0, ptr %arg, align 8 51 store double 2.0, ptr %tmp1, align 8 52 store double 3.0, ptr %tmp, align 8 53 store double 4.0, ptr %tmp5, align 8 54 store double 5.0, ptr %tmp4, align 8 55 store double 6.0, ptr %tmp3, align 8 56 ret void 57} 58 59define void @overlap2(ptr %arg, i1 %cond) { 60; CHECK-LABEL: @overlap2( 61; CHECK-NEXT: bb: 62; CHECK-NEXT: [[TMP:%.*]] = getelementptr inbounds [[STRUCT_HAM:%.*]], ptr [[ARG:%.*]], i64 0, i32 0, i64 2 63; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT_HAM]], ptr [[ARG]], i64 0, i32 0, i64 1 64; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds [[STRUCT_HAM]], ptr [[ARG]], i64 0, i32 1, i64 2 65; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds [[STRUCT_HAM]], ptr [[ARG]], i64 0, i32 1, i64 1 66; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT_HAM]], ptr [[ARG]], i64 0, i32 1, i32 0 67; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr nonnull align 8 dereferenceable(48) [[ARG]], i8 0, i64 48, i1 false) 68; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB7:%.*]], label [[BB8:%.*]] 69; CHECK: bb7: 70; CHECK-NEXT: call void @may_throw() 71; CHECK-NEXT: br label [[BB9:%.*]] 72; CHECK: bb8: 73; CHECK-NEXT: br label [[BB9]] 74; CHECK: bb9: 75; CHECK-NEXT: store double 1.000000e+00, ptr [[ARG]], align 8 76; CHECK-NEXT: store double 2.000000e+00, ptr [[TMP1]], align 8 77; CHECK-NEXT: store double 3.000000e+00, ptr [[TMP]], align 8 78; CHECK-NEXT: store double 4.000000e+00, ptr [[TMP5]], align 8 79; CHECK-NEXT: store double 5.000000e+00, ptr [[TMP4]], align 8 80; CHECK-NEXT: store double 6.000000e+00, ptr [[TMP3]], align 8 81; CHECK-NEXT: ret void 82; 83bb: 84 %tmp = getelementptr inbounds %struct.ham, ptr %arg, i64 0, i32 0, i64 2 85 %tmp1 = getelementptr inbounds %struct.ham, ptr %arg, i64 0, i32 0, i64 1 86 %tmp3 = getelementptr inbounds %struct.ham, ptr %arg, i64 0,i32 1, i64 2 87 %tmp4 = getelementptr inbounds %struct.ham, ptr %arg, i64 0, i32 1, i64 1 88 %tmp5 = getelementptr inbounds %struct.ham, ptr %arg, i64 0, i32 1, i32 0 89 call void @llvm.memset.p0.i64(ptr nonnull align 8 dereferenceable(48) %arg, i8 0, i64 48, i1 false) 90 br i1 %cond, label %bb7, label %bb8 91 92bb7: ; preds = %bb 93 call void @may_throw() 94 br label %bb9 95 96bb8: ; preds = %bb 97 br label %bb9 98 99bb9: ; preds = %bb8, %bb7 100 store double 1.0, ptr %arg, align 8 101 store double 2.0, ptr %tmp1, align 8 102 store double 3.0, ptr %tmp, align 8 103 store double 4.0, ptr %tmp5, align 8 104 store double 5.0, ptr %tmp4, align 8 105 store double 6.0, ptr %tmp3, align 8 106 ret void 107} 108 109; Test case from PR46513. Make sure we do not crash. 110; TODO: we should be able to shorten store i32 844283136, ptr %cast.i32 to a 111; store of i16. 112define void @overlap_no_dominance(ptr %arg, i1 %c) { 113; CHECK-LABEL: @overlap_no_dominance( 114; CHECK-NEXT: bb: 115; CHECK-NEXT: br i1 [[C:%.*]], label [[BB13:%.*]], label [[BB9:%.*]] 116; CHECK: bb9: 117; CHECK-NEXT: store i32 844283136, ptr [[ARG:%.*]], align 4 118; CHECK-NEXT: br label [[BB13]] 119; CHECK: bb13: 120; CHECK-NEXT: store i16 0, ptr [[ARG]], align 4 121; CHECK-NEXT: ret void 122; 123bb: 124 br i1 %c, label %bb13, label %bb9 125 126bb9: ; preds = %bb 127 store i32 844283136, ptr %arg, align 4 128 br label %bb13 129 130bb13: ; preds = %bb9, %bb 131 store i16 0, ptr %arg, align 4 132 ret void 133} 134