1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=dse -S | FileCheck %s 3 4target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64" 5 6declare void @readnone_may_throw() readnone 7 8declare void @use(ptr) 9 10; Tests where the pointer/object is accessible after the function returns. 11 12; Cannot remove the store from the entry block, because the call in bb2 may throw. 13define void @accessible_after_return_1(ptr noalias %P, i1 %c1) { 14; CHECK-LABEL: @accessible_after_return_1( 15; CHECK-NEXT: store i32 1, ptr [[P:%.*]], align 4 16; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] 17; CHECK: bb1: 18; CHECK-NEXT: store i32 0, ptr [[P]], align 4 19; CHECK-NEXT: br label [[BB5:%.*]] 20; CHECK: bb2: 21; CHECK-NEXT: call void @readnone_may_throw() 22; CHECK-NEXT: store i32 3, ptr [[P]], align 4 23; CHECK-NEXT: br label [[BB5]] 24; CHECK: bb5: 25; CHECK-NEXT: call void @use(ptr [[P]]) 26; CHECK-NEXT: ret void 27; 28 store i32 1, ptr %P 29 br i1 %c1, label %bb1, label %bb2 30 31bb1: 32 store i32 0, ptr %P 33 br label %bb5 34 35bb2: 36 call void @readnone_may_throw() 37 store i32 3, ptr %P 38 br label %bb5 39 40bb5: 41 call void @use(ptr %P) 42 ret void 43} 44 45; Cannot remove the store from the entry block, because the call in bb3 may throw. 46define void @accessible_after_return6(ptr %P, i1 %c.1, i1 %c.2) { 47; CHECK-LABEL: @accessible_after_return6( 48; CHECK-NEXT: entry: 49; CHECK-NEXT: store i32 0, ptr [[P:%.*]], align 4 50; CHECK-NEXT: br i1 [[C_1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] 51; CHECK: bb1: 52; CHECK-NEXT: br i1 [[C_2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]] 53; CHECK: bb2: 54; CHECK-NEXT: store i32 1, ptr [[P]], align 4 55; CHECK-NEXT: ret void 56; CHECK: bb3: 57; CHECK-NEXT: call void @readnone_may_throw() 58; CHECK-NEXT: store i32 2, ptr [[P]], align 4 59; CHECK-NEXT: ret void 60; CHECK: bb4: 61; CHECK-NEXT: store i32 3, ptr [[P]], align 4 62; CHECK-NEXT: ret void 63; 64entry: 65 store i32 0, ptr %P 66 br i1 %c.1, label %bb1, label %bb2 67 68bb1: 69 br i1 %c.2, label %bb3, label %bb4 70 71bb2: 72 store i32 1, ptr %P 73 ret void 74 75bb3: 76 call void @readnone_may_throw() 77 store i32 2, ptr %P 78 ret void 79 80bb4: 81 store i32 3, ptr %P 82 ret void 83} 84 85; Tests where the pointer/object is *NOT* accessible after the function returns. 86 87; The store in the entry block can be eliminated, because it is overwritten 88; on all paths to the exit. As the location is not visible to the caller, the 89; call in bb2 (which may throw) can be ignored. 90define void @alloca_1(i1 %c1) { 91; CHECK-LABEL: @alloca_1( 92; CHECK-NEXT: entry: 93; CHECK-NEXT: [[P:%.*]] = alloca i32 94; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] 95; CHECK: bb1: 96; CHECK-NEXT: store i32 0, ptr [[P]], align 4 97; CHECK-NEXT: br label [[BB5:%.*]] 98; CHECK: bb2: 99; CHECK-NEXT: call void @readnone_may_throw() 100; CHECK-NEXT: store i32 3, ptr [[P]], align 4 101; CHECK-NEXT: br label [[BB5]] 102; CHECK: bb5: 103; CHECK-NEXT: call void @use(ptr [[P]]) 104; CHECK-NEXT: ret void 105; 106entry: 107 %P = alloca i32 108 store i32 1, ptr %P 109 br i1 %c1, label %bb1, label %bb2 110 111bb1: 112 store i32 0, ptr %P 113 br label %bb5 114 115bb2: 116 call void @readnone_may_throw() 117 store i32 3, ptr %P 118 br label %bb5 119 120bb5: 121 call void @use(ptr %P) 122 ret void 123} 124 125; The store in the entry block can be eliminated, because it is overwritten 126; on all paths to the exit. As the location is not visible to the caller, the 127; call in bb3 (which may throw) can be ignored. 128define void @alloca_2(i1 %c.1, i1 %c.2) { 129; CHECK-LABEL: @alloca_2( 130; CHECK-NEXT: [[P:%.*]] = alloca i32 131; CHECK-NEXT: br i1 [[C_1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] 132; CHECK: bb1: 133; CHECK-NEXT: store i32 0, ptr [[P]], align 4 134; CHECK-NEXT: br label [[BB5:%.*]] 135; CHECK: bb2: 136; CHECK-NEXT: br i1 [[C_2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]] 137; CHECK: bb3: 138; CHECK-NEXT: call void @readnone_may_throw() 139; CHECK-NEXT: store i32 3, ptr [[P]], align 4 140; CHECK-NEXT: br label [[BB5]] 141; CHECK: bb4: 142; CHECK-NEXT: store i32 5, ptr [[P]], align 4 143; CHECK-NEXT: br label [[BB5]] 144; CHECK: bb5: 145; CHECK-NEXT: call void @use(ptr [[P]]) 146; CHECK-NEXT: ret void 147; 148 %P = alloca i32 149 store i32 1, ptr %P 150 br i1 %c.1, label %bb1, label %bb2 151 152bb1: 153 store i32 0, ptr %P 154 br label %bb5 155 156bb2: 157 br i1 %c.2, label %bb3, label %bb4 158 159bb3: 160 call void @readnone_may_throw() 161 store i32 3, ptr %P 162 br label %bb5 163 164bb4: 165 store i32 5, ptr %P 166 br label %bb5 167 168bb5: 169 call void @use(ptr %P) 170 ret void 171} 172