| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py |
| ; RUN: opt -dse %s -S | FileCheck --check-prefixes=CHECK %s |
| |
| |
| %struct.ham = type { [3 x double], [3 x double]} |
| |
| declare void @may_throw() |
| declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i1 immarg) |
| |
| ; We miss this case, because of an aggressive limit of partial overlap analysis. |
| ; With a larger partial store limit, we remove the memset. |
| define void @overlap1(%struct.ham* %arg, i1 %cond) { |
| ; CHECK-LABEL: @overlap1( |
| ; CHECK-NEXT: bb: |
| ; CHECK-NEXT: [[TMP:%.*]] = getelementptr inbounds [[STRUCT_HAM:%.*]], %struct.ham* [[ARG:%.*]], i64 0, i32 0, i64 2 |
| ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT_HAM]], %struct.ham* [[ARG]], i64 0, i32 0, i64 1 |
| ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT_HAM]], %struct.ham* [[ARG]], i64 0, i32 0, i64 0 |
| ; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds [[STRUCT_HAM]], %struct.ham* [[ARG]], i64 0, i32 1, i64 2 |
| ; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds [[STRUCT_HAM]], %struct.ham* [[ARG]], i64 0, i32 1, i64 1 |
| ; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT_HAM]], %struct.ham* [[ARG]], i64 0, i32 1, i32 0 |
| ; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB7:%.*]], label [[BB8:%.*]] |
| ; CHECK: bb7: |
| ; CHECK-NEXT: br label [[BB9:%.*]] |
| ; CHECK: bb8: |
| ; CHECK-NEXT: br label [[BB9]] |
| ; CHECK: bb9: |
| ; CHECK-NEXT: store double 1.000000e+00, double* [[TMP2]], align 8 |
| ; CHECK-NEXT: store double 2.000000e+00, double* [[TMP1]], align 8 |
| ; CHECK-NEXT: store double 3.000000e+00, double* [[TMP]], align 8 |
| ; CHECK-NEXT: store double 4.000000e+00, double* [[TMP5]], align 8 |
| ; CHECK-NEXT: store double 5.000000e+00, double* [[TMP4]], align 8 |
| ; CHECK-NEXT: store double 6.000000e+00, double* [[TMP3]], align 8 |
| ; CHECK-NEXT: ret void |
| ; |
| bb: |
| %tmp = getelementptr inbounds %struct.ham, %struct.ham* %arg, i64 0, i32 0, i64 2 |
| %tmp1 = getelementptr inbounds %struct.ham, %struct.ham* %arg, i64 0, i32 0, i64 1 |
| %tmp2 = getelementptr inbounds %struct.ham, %struct.ham* %arg, i64 0, i32 0, i64 0 |
| %tmp3 = getelementptr inbounds %struct.ham, %struct.ham* %arg, i64 0,i32 1, i64 2 |
| %tmp4 = getelementptr inbounds %struct.ham, %struct.ham* %arg, i64 0, i32 1, i64 1 |
| %tmp5 = getelementptr inbounds %struct.ham, %struct.ham* %arg, i64 0, i32 1, i32 0 |
| %tmp6 = bitcast double* %tmp2 to i8* |
| call void @llvm.memset.p0i8.i64(i8* nonnull align 8 dereferenceable(48) %tmp6, i8 0, i64 48, i1 false) |
| br i1 %cond, label %bb7, label %bb8 |
| |
| bb7: ; preds = %bb |
| br label %bb9 |
| |
| bb8: ; preds = %bb |
| br label %bb9 |
| |
| bb9: ; preds = %bb8, %bb7 |
| store double 1.0, double* %tmp2, align 8 |
| store double 2.0, double* %tmp1, align 8 |
| store double 3.0, double* %tmp, align 8 |
| store double 4.0, double* %tmp5, align 8 |
| store double 5.0, double* %tmp4, align 8 |
| store double 6.0, double* %tmp3, align 8 |
| ret void |
| } |
| |
| define void @overlap2(%struct.ham* %arg, i1 %cond) { |
| ; CHECK-LABEL: @overlap2( |
| ; CHECK-NEXT: bb: |
| ; CHECK-NEXT: [[TMP:%.*]] = getelementptr inbounds [[STRUCT_HAM:%.*]], %struct.ham* [[ARG:%.*]], i64 0, i32 0, i64 2 |
| ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT_HAM]], %struct.ham* [[ARG]], i64 0, i32 0, i64 1 |
| ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT_HAM]], %struct.ham* [[ARG]], i64 0, i32 0, i64 0 |
| ; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds [[STRUCT_HAM]], %struct.ham* [[ARG]], i64 0, i32 1, i64 2 |
| ; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds [[STRUCT_HAM]], %struct.ham* [[ARG]], i64 0, i32 1, i64 1 |
| ; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT_HAM]], %struct.ham* [[ARG]], i64 0, i32 1, i32 0 |
| ; CHECK-NEXT: [[TMP6:%.*]] = bitcast double* [[TMP2]] to i8* |
| ; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull align 8 dereferenceable(48) [[TMP6]], i8 0, i64 48, i1 false) |
| ; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB7:%.*]], label [[BB8:%.*]] |
| ; CHECK: bb7: |
| ; CHECK-NEXT: call void @may_throw() |
| ; CHECK-NEXT: br label [[BB9:%.*]] |
| ; CHECK: bb8: |
| ; CHECK-NEXT: br label [[BB9]] |
| ; CHECK: bb9: |
| ; CHECK-NEXT: store double 1.000000e+00, double* [[TMP2]], align 8 |
| ; CHECK-NEXT: store double 2.000000e+00, double* [[TMP1]], align 8 |
| ; CHECK-NEXT: store double 3.000000e+00, double* [[TMP]], align 8 |
| ; CHECK-NEXT: store double 4.000000e+00, double* [[TMP5]], align 8 |
| ; CHECK-NEXT: store double 5.000000e+00, double* [[TMP4]], align 8 |
| ; CHECK-NEXT: store double 6.000000e+00, double* [[TMP3]], align 8 |
| ; CHECK-NEXT: ret void |
| ; |
| bb: |
| %tmp = getelementptr inbounds %struct.ham, %struct.ham* %arg, i64 0, i32 0, i64 2 |
| %tmp1 = getelementptr inbounds %struct.ham, %struct.ham* %arg, i64 0, i32 0, i64 1 |
| %tmp2 = getelementptr inbounds %struct.ham, %struct.ham* %arg, i64 0, i32 0, i64 0 |
| %tmp3 = getelementptr inbounds %struct.ham, %struct.ham* %arg, i64 0,i32 1, i64 2 |
| %tmp4 = getelementptr inbounds %struct.ham, %struct.ham* %arg, i64 0, i32 1, i64 1 |
| %tmp5 = getelementptr inbounds %struct.ham, %struct.ham* %arg, i64 0, i32 1, i32 0 |
| %tmp6 = bitcast double* %tmp2 to i8* |
| call void @llvm.memset.p0i8.i64(i8* nonnull align 8 dereferenceable(48) %tmp6, i8 0, i64 48, i1 false) |
| br i1 %cond, label %bb7, label %bb8 |
| |
| bb7: ; preds = %bb |
| call void @may_throw() |
| br label %bb9 |
| |
| bb8: ; preds = %bb |
| br label %bb9 |
| |
| bb9: ; preds = %bb8, %bb7 |
| store double 1.0, double* %tmp2, align 8 |
| store double 2.0, double* %tmp1, align 8 |
| store double 3.0, double* %tmp, align 8 |
| store double 4.0, double* %tmp5, align 8 |
| store double 5.0, double* %tmp4, align 8 |
| store double 6.0, double* %tmp3, align 8 |
| ret void |
| } |
| |
| ; Test case from PR46513. Make sure we do not crash. |
| ; TODO: we should be able to shorten store i32 844283136, i32* %cast.i32 to a |
| ; store of i16. |
| define void @overlap_no_dominance([4 x i8]* %arg, i1 %c) { |
| ; CHECK-LABEL: @overlap_no_dominance( |
| ; CHECK-NEXT: bb: |
| ; CHECK-NEXT: br i1 [[C:%.*]], label [[BB13:%.*]], label [[BB9:%.*]] |
| ; CHECK: bb9: |
| ; CHECK-NEXT: [[CAST_I32:%.*]] = bitcast [4 x i8]* [[ARG:%.*]] to i32* |
| ; CHECK-NEXT: store i32 844283136, i32* [[CAST_I32]], align 4 |
| ; CHECK-NEXT: br label [[BB13]] |
| ; CHECK: bb13: |
| ; CHECK-NEXT: [[CAST_I16:%.*]] = bitcast [4 x i8]* [[ARG]] to i16* |
| ; CHECK-NEXT: store i16 0, i16* [[CAST_I16]], align 4 |
| ; CHECK-NEXT: ret void |
| ; |
| bb: |
| br i1 %c, label %bb13, label %bb9 |
| |
| bb9: ; preds = %bb |
| %cast.i32 = bitcast [4 x i8]* %arg to i32* |
| store i32 844283136, i32* %cast.i32, align 4 |
| br label %bb13 |
| |
| bb13: ; preds = %bb9, %bb |
| %cast.i16 = bitcast [4 x i8]* %arg to i16* |
| store i16 0, i16* %cast.i16, align 4 |
| ret void |
| } |