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