[llvm] 4184b2e - [DSE, MSSA] Add additional test cases for multi-path elimination (NFC).

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 8 07:27:02 PDT 2020


Author: Florian Hahn
Date: 2020-04-08T15:26:26+01:00
New Revision: 4184b2e03401ad3818de9e1751d4e2897e8fcf71

URL: https://github.com/llvm/llvm-project/commit/4184b2e03401ad3818de9e1751d4e2897e8fcf71
DIFF: https://github.com/llvm/llvm-project/commit/4184b2e03401ad3818de9e1751d4e2897e8fcf71.diff

LOG: [DSE,MSSA] Add additional test cases for multi-path elimination (NFC).

This adds additional test cases for more scenarios and also with objects
that are accessible after the functions return and allocas.

Added: 
    

Modified: 
    llvm/test/Transforms/DeadStoreElimination/MSSA/multiblock-memintrinsics.ll
    llvm/test/Transforms/DeadStoreElimination/MSSA/multiblock-multipath.ll

Removed: 
    


################################################################################
diff  --git a/llvm/test/Transforms/DeadStoreElimination/MSSA/multiblock-memintrinsics.ll b/llvm/test/Transforms/DeadStoreElimination/MSSA/multiblock-memintrinsics.ll
index 535bcd75a69a..af45ec2fb710 100644
--- a/llvm/test/Transforms/DeadStoreElimination/MSSA/multiblock-memintrinsics.ll
+++ b/llvm/test/Transforms/DeadStoreElimination/MSSA/multiblock-memintrinsics.ll
@@ -6,13 +6,16 @@ declare void @unknown_func()
 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1) nounwind
 declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind
 
-define void @test19(i32* noalias %P) {
-; CHECK-LABEL: @test19(
+; Tests where the pointer/object is accessible after the function returns.
+
+; Overwriting store along one path to the exit.
+define void @accessible_after_return_1(i32* noalias %P, i1 %c) {
+; CHECK-LABEL: @accessible_after_return_1(
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1
 ; CHECK-NEXT:    [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8*
 ; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 4 [[P3]], i8 0, i64 28, i1 false)
-; CHECK-NEXT:    br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
+; CHECK-NEXT:    br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
 ; CHECK:       bb1:
 ; CHECK-NEXT:    br label [[BB3:%.*]]
 ; CHECK:       bb2:
@@ -26,7 +29,7 @@ entry:
   %arrayidx0 = getelementptr inbounds i32, i32* %P, i64 1
   %p3 = bitcast i32* %arrayidx0 to i8*
   call void @llvm.memset.p0i8.i64(i8* %p3, i8 0, i64 28, i32 4, i1 false)
-  br i1 true, label %bb1, label %bb2
+  br i1 %c, label %bb1, label %bb2
 bb1:
   br label %bb3
 bb2:
@@ -37,15 +40,174 @@ bb3:
   ret void
 }
 
+; Post-dominating store.
+define void @accessible_after_return_2(i32* noalias %P, i1 %c) {
+; CHECK-LABEL: @accessible_after_return_2(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1
+; CHECK-NEXT:    [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8*
+; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 4 [[P3]], i8 0, i64 28, i1 false)
+; CHECK-NEXT:    br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
+; CHECK:       bb1:
+; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 1
+; CHECK-NEXT:    store i32 1, i32* [[ARRAYIDX1]], align 4
+; CHECK-NEXT:    br label [[BB3:%.*]]
+; CHECK:       bb2:
+; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 1
+; CHECK-NEXT:    store i32 1, i32* [[ARRAYIDX2]], align 4
+; CHECK-NEXT:    br label [[BB3]]
+; CHECK:       bb3:
+; CHECK-NEXT:    ret void
+;
+entry:
+  %arrayidx0 = getelementptr inbounds i32, i32* %P, i64 1
+  %p3 = bitcast i32* %arrayidx0 to i8*
+  call void @llvm.memset.p0i8.i64(i8* %p3, i8 0, i64 28, i32 4, i1 false)
+  br i1 %c, label %bb1, label %bb2
+
+bb1:
+  %arrayidx1 = getelementptr inbounds i32, i32* %P, i64 1
+  store i32 1, i32* %arrayidx1, align 4
+  br label %bb3
+
+bb2:
+  %arrayidx2 = getelementptr inbounds i32, i32* %P, i64 1
+  store i32 1, i32* %arrayidx2, align 4
+  br label %bb3
+
+bb3:
+  ret void
+}
 
-define void @test20(i32* noalias %P) {
-; CHECK-LABEL: @test20(
+; Stores along  both exit paths.
+define void @accessible_after_return_3(i32* noalias %P, i1 %c) {
+; CHECK-LABEL: @accessible_after_return_3(
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1
 ; CHECK-NEXT:    [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8*
 ; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P3]], i64 4
 ; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 4 [[TMP0]], i8 0, i64 24, i1 false)
-; CHECK-NEXT:    br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
+; CHECK-NEXT:    br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
+; CHECK:       bb1:
+; CHECK-NEXT:    br label [[BB3:%.*]]
+; CHECK:       bb2:
+; CHECK-NEXT:    br label [[BB3]]
+; CHECK:       bb3:
+; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 1
+; CHECK-NEXT:    store i32 1, i32* [[ARRAYIDX1]], align 4
+; CHECK-NEXT:    ret void
+;
+entry:
+  %arrayidx0 = getelementptr inbounds i32, i32* %P, i64 1
+  %p3 = bitcast i32* %arrayidx0 to i8*
+  call void @llvm.memset.p0i8.i64(i8* %p3, i8 0, i64 28, i32 4, i1 false)
+  br i1 %c, label %bb1, label %bb2
+
+bb1:
+  br label %bb3
+
+bb2:
+  br label %bb3
+
+bb3:
+  %arrayidx1 = getelementptr inbounds i32, i32* %P, i64 1
+  store i32 1, i32* %arrayidx1, align 4
+  ret void
+}
+
+
+; Tests where the pointer/object is *NOT* accessible after the function returns.
+
+; Overwriting store along one path to the exit.
+define void @alloca_1(i1 %c) {
+; CHECK-LABEL: @alloca_1(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[P_ALLOCA:%.*]] = alloca [32 x i32]
+; CHECK-NEXT:    [[P:%.*]] = bitcast [32 x i32]* [[P_ALLOCA]] to i32*
+; CHECK-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 1
+; CHECK-NEXT:    [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8*
+; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 4 [[P3]], i8 0, i64 28, i1 false)
+; CHECK-NEXT:    br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
+; CHECK:       bb1:
+; CHECK-NEXT:    br label [[BB3:%.*]]
+; CHECK:       bb2:
+; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 1
+; CHECK-NEXT:    store i32 1, i32* [[ARRAYIDX1]], align 4
+; CHECK-NEXT:    br label [[BB3]]
+; CHECK:       bb3:
+; CHECK-NEXT:    ret void
+;
+entry:
+  %P.alloca = alloca [32 x i32]
+  %P = bitcast [32 x i32]* %P.alloca to i32*
+  %arrayidx0 = getelementptr inbounds i32, i32* %P, i64 1
+  %p3 = bitcast i32* %arrayidx0 to i8*
+  call void @llvm.memset.p0i8.i64(i8* %p3, i8 0, i64 28, i32 4, i1 false)
+  br i1 %c, label %bb1, label %bb2
+bb1:
+  br label %bb3
+bb2:
+  %arrayidx1 = getelementptr inbounds i32, i32* %P, i64 1
+  store i32 1, i32* %arrayidx1, align 4
+  br label %bb3
+bb3:
+  ret void
+}
+
+; Post-dominating store.
+define void @alloca_2(i1 %c) {
+; CHECK-LABEL: @alloca_2(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[P_ALLOCA:%.*]] = alloca [32 x i32]
+; CHECK-NEXT:    [[P:%.*]] = bitcast [32 x i32]* [[P_ALLOCA]] to i32*
+; CHECK-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 1
+; CHECK-NEXT:    [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8*
+; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 4 [[P3]], i8 0, i64 28, i1 false)
+; CHECK-NEXT:    br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
+; CHECK:       bb1:
+; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 1
+; CHECK-NEXT:    store i32 1, i32* [[ARRAYIDX1]], align 4
+; CHECK-NEXT:    br label [[BB3:%.*]]
+; CHECK:       bb2:
+; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 1
+; CHECK-NEXT:    store i32 1, i32* [[ARRAYIDX2]], align 4
+; CHECK-NEXT:    br label [[BB3]]
+; CHECK:       bb3:
+; CHECK-NEXT:    ret void
+;
+entry:
+  %P.alloca = alloca [32 x i32]
+  %P = bitcast [32 x i32]* %P.alloca to i32*
+  %arrayidx0 = getelementptr inbounds i32, i32* %P, i64 1
+  %p3 = bitcast i32* %arrayidx0 to i8*
+  call void @llvm.memset.p0i8.i64(i8* %p3, i8 0, i64 28, i32 4, i1 false)
+  br i1 %c, label %bb1, label %bb2
+
+bb1:
+  %arrayidx1 = getelementptr inbounds i32, i32* %P, i64 1
+  store i32 1, i32* %arrayidx1, align 4
+  br label %bb3
+
+bb2:
+  %arrayidx2 = getelementptr inbounds i32, i32* %P, i64 1
+  store i32 1, i32* %arrayidx2, align 4
+  br label %bb3
+
+bb3:
+  ret void
+}
+
+; Stores along  both exit paths.
+define void @alloca_3(i1 %c) {
+; CHECK-LABEL: @alloca_3(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[P_ALLOCA:%.*]] = alloca [32 x i32]
+; CHECK-NEXT:    [[P:%.*]] = bitcast [32 x i32]* [[P_ALLOCA]] to i32*
+; CHECK-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 1
+; CHECK-NEXT:    [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8*
+; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P3]], i64 4
+; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 4 [[TMP0]], i8 0, i64 24, i1 false)
+; CHECK-NEXT:    br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
 ; CHECK:       bb1:
 ; CHECK-NEXT:    br label [[BB3:%.*]]
 ; CHECK:       bb2:
@@ -56,14 +218,19 @@ define void @test20(i32* noalias %P) {
 ; CHECK-NEXT:    ret void
 ;
 entry:
+  %P.alloca = alloca [32 x i32]
+  %P = bitcast [32 x i32]* %P.alloca to i32*
   %arrayidx0 = getelementptr inbounds i32, i32* %P, i64 1
   %p3 = bitcast i32* %arrayidx0 to i8*
   call void @llvm.memset.p0i8.i64(i8* %p3, i8 0, i64 28, i32 4, i1 false)
-  br i1 true, label %bb1, label %bb2
+  br i1 %c, label %bb1, label %bb2
+
 bb1:
   br label %bb3
+
 bb2:
   br label %bb3
+
 bb3:
   %arrayidx1 = getelementptr inbounds i32, i32* %P, i64 1
   store i32 1, i32* %arrayidx1, align 4

diff  --git a/llvm/test/Transforms/DeadStoreElimination/MSSA/multiblock-multipath.ll b/llvm/test/Transforms/DeadStoreElimination/MSSA/multiblock-multipath.ll
index a24ecd293773..a5d7b24c8a81 100644
--- a/llvm/test/Transforms/DeadStoreElimination/MSSA/multiblock-multipath.ll
+++ b/llvm/test/Transforms/DeadStoreElimination/MSSA/multiblock-multipath.ll
@@ -5,8 +5,10 @@ target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
 
 declare void @use(i32 *)
 
-define void @test4(i32* noalias %P, i1 %c1) {
-; CHECK-LABEL: @test4(
+; Tests where the pointer/object is accessible after the function returns.
+
+define void @accessible_after_return_1(i32* noalias %P, i1 %c1) {
+; CHECK-LABEL: @accessible_after_return_1(
 ; CHECK-NEXT:    store i32 1, i32* [[P:%.*]]
 ; CHECK-NEXT:    br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
 ; CHECK:       bb1:
@@ -34,15 +36,15 @@ bb5:
   ret void
 }
 
-define void @test5(i32* noalias %P) {
-; CHECK-LABEL: @test5(
+define void @accessible_after_return_2(i32* noalias %P, i1 %c.1, i1 %c.2) {
+; CHECK-LABEL: @accessible_after_return_2(
 ; CHECK-NEXT:    store i32 1, i32* [[P:%.*]]
-; CHECK-NEXT:    br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
+; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
 ; CHECK:       bb1:
 ; CHECK-NEXT:    store i32 0, i32* [[P]]
 ; CHECK-NEXT:    br label [[BB5:%.*]]
 ; CHECK:       bb2:
-; CHECK-NEXT:    br i1 undef, label [[BB3:%.*]], label [[BB4:%.*]]
+; CHECK-NEXT:    br i1 [[C_2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]]
 ; CHECK:       bb3:
 ; CHECK-NEXT:    store i32 3, i32* [[P]]
 ; CHECK-NEXT:    br label [[BB5]]
@@ -54,13 +56,13 @@ define void @test5(i32* noalias %P) {
 ; CHECK-NEXT:    ret void
 ;
   store i32 1, i32* %P
-  br i1 true, label %bb1, label %bb2
+  br i1 %c.1, label %bb1, label %bb2
 bb1:
   store i32 0, i32* %P
   br label %bb5
 
 bb2:
-  br i1 undef, label %bb3, label %bb4
+  br i1 %c.2, label %bb3, label %bb4
 
 bb3:
   store i32 3, i32* %P
@@ -74,3 +76,196 @@ bb5:
   call void @use(i32* %P)
   ret void
 }
+
+define void @accessible_after_return_3(i32* noalias %P, i1 %c1) {
+; CHECK-LABEL: @accessible_after_return_3(
+; CHECK-NEXT:    store i32 1, i32* [[P:%.*]]
+; CHECK-NEXT:    br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
+; CHECK:       bb1:
+; CHECK-NEXT:    store i32 0, i32* [[P]]
+; CHECK-NEXT:    br label [[BB5:%.*]]
+; CHECK:       bb2:
+; CHECK-NEXT:    br label [[BB5]]
+; CHECK:       bb5:
+; CHECK-NEXT:    call void @use(i32* [[P]])
+; CHECK-NEXT:    ret void
+;
+  store i32 1, i32* %P
+  br i1 %c1, label %bb1, label %bb2
+
+bb1:
+  store i32 0, i32* %P
+  br label %bb5
+
+bb2:
+  br label %bb5
+
+bb5:
+  call void @use(i32* %P)
+  ret void
+}
+
+define void @accessible_after_return_4(i32* noalias %P, i1 %c1) {
+; CHECK-LABEL: @accessible_after_return_4(
+; CHECK-NEXT:    store i32 1, i32* [[P:%.*]]
+; CHECK-NEXT:    br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
+; CHECK:       bb1:
+; CHECK-NEXT:    store i32 0, i32* [[P]]
+; CHECK-NEXT:    call void @use(i32* [[P]])
+; CHECK-NEXT:    br label [[BB5:%.*]]
+; CHECK:       bb2:
+; CHECK-NEXT:    br label [[BB5]]
+; CHECK:       bb5:
+; CHECK-NEXT:    ret void
+;
+  store i32 1, i32* %P
+  br i1 %c1, label %bb1, label %bb2
+
+bb1:
+  store i32 0, i32* %P
+  call void @use(i32* %P)
+  br label %bb5
+
+bb2:
+  br label %bb5
+
+bb5:
+  ret void
+}
+
+
+; Tests where the pointer/object is *NOT* accessible after the function returns.
+
+define void @alloca_1(i1 %c1) {
+; CHECK-LABEL: @alloca_1(
+; CHECK-NEXT:    [[P:%.*]] = alloca i32
+; CHECK-NEXT:    store i32 1, i32* [[P]]
+; CHECK-NEXT:    br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
+; CHECK:       bb1:
+; CHECK-NEXT:    store i32 0, i32* [[P]]
+; CHECK-NEXT:    br label [[BB5:%.*]]
+; CHECK:       bb2:
+; CHECK-NEXT:    store i32 3, i32* [[P]]
+; CHECK-NEXT:    br label [[BB5]]
+; CHECK:       bb5:
+; CHECK-NEXT:    call void @use(i32* [[P]])
+; CHECK-NEXT:    ret void
+;
+  %P = alloca i32
+  store i32 1, i32* %P
+  br i1 %c1, label %bb1, label %bb2
+
+bb1:
+  store i32 0, i32* %P
+  br label %bb5
+bb2:
+  store i32 3, i32* %P
+  br label %bb5
+
+bb5:
+  call void @use(i32* %P)
+  ret void
+}
+
+define void @alloca_2(i1 %c.1, i1 %c.2) {
+; CHECK-LABEL: @alloca_2(
+; CHECK-NEXT:    [[P:%.*]] = alloca i32
+; CHECK-NEXT:    store i32 1, i32* [[P]]
+; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
+; CHECK:       bb1:
+; CHECK-NEXT:    store i32 0, i32* [[P]]
+; CHECK-NEXT:    br label [[BB5:%.*]]
+; CHECK:       bb2:
+; CHECK-NEXT:    br i1 [[C_2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]]
+; CHECK:       bb3:
+; CHECK-NEXT:    store i32 3, i32* [[P]]
+; CHECK-NEXT:    br label [[BB5]]
+; CHECK:       bb4:
+; CHECK-NEXT:    store i32 5, i32* [[P]]
+; CHECK-NEXT:    br label [[BB5]]
+; CHECK:       bb5:
+; CHECK-NEXT:    call void @use(i32* [[P]])
+; CHECK-NEXT:    ret void
+;
+  %P = alloca i32
+  store i32 1, i32* %P
+  br i1 %c.1, label %bb1, label %bb2
+
+bb1:
+  store i32 0, i32* %P
+  br label %bb5
+
+bb2:
+  br i1 %c.2, label %bb3, label %bb4
+
+bb3:
+  store i32 3, i32* %P
+  br label %bb5
+
+bb4:
+  store i32 5, i32* %P
+  br label %bb5
+
+bb5:
+  call void @use(i32* %P)
+  ret void
+}
+
+define void @alloca_3(i1 %c1) {
+; CHECK-LABEL: @alloca_3(
+; CHECK-NEXT:    [[P:%.*]] = alloca i32
+; CHECK-NEXT:    store i32 1, i32* [[P]]
+; CHECK-NEXT:    br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
+; CHECK:       bb1:
+; CHECK-NEXT:    store i32 0, i32* [[P]]
+; CHECK-NEXT:    br label [[BB5:%.*]]
+; CHECK:       bb2:
+; CHECK-NEXT:    br label [[BB5]]
+; CHECK:       bb5:
+; CHECK-NEXT:    call void @use(i32* [[P]])
+; CHECK-NEXT:    ret void
+;
+  %P = alloca i32
+  store i32 1, i32* %P
+  br i1 %c1, label %bb1, label %bb2
+
+bb1:
+  store i32 0, i32* %P
+  br label %bb5
+bb2:
+  br label %bb5
+
+bb5:
+  call void @use(i32* %P)
+  ret void
+}
+
+define void @alloca_4(i1 %c1) {
+; CHECK-LABEL: @alloca_4(
+; CHECK-NEXT:    [[P:%.*]] = alloca i32
+; CHECK-NEXT:    store i32 1, i32* [[P]]
+; CHECK-NEXT:    br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
+; CHECK:       bb1:
+; CHECK-NEXT:    store i32 0, i32* [[P]]
+; CHECK-NEXT:    call void @use(i32* [[P]])
+; CHECK-NEXT:    br label [[BB5:%.*]]
+; CHECK:       bb2:
+; CHECK-NEXT:    br label [[BB5]]
+; CHECK:       bb5:
+; CHECK-NEXT:    ret void
+;
+  %P = alloca i32
+  store i32 1, i32* %P
+  br i1 %c1, label %bb1, label %bb2
+
+bb1:
+  store i32 0, i32* %P
+  call void @use(i32* %P)
+  br label %bb5
+
+bb2:
+  br label %bb5
+
+bb5:
+  ret void
+}


        


More information about the llvm-commits mailing list