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 6 7define void @test2(ptr noalias %P) { 8; CHECK-LABEL: @test2( 9; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]] 10; CHECK: bb1: 11; CHECK-NEXT: br label [[BB3:%.*]] 12; CHECK: bb2: 13; CHECK-NEXT: br label [[BB3]] 14; CHECK: bb3: 15; CHECK-NEXT: store i32 0, ptr [[P:%.*]], align 4 16; CHECK-NEXT: ret void 17; 18 store i32 1, ptr %P 19 br i1 true, label %bb1, label %bb2 20bb1: 21 br label %bb3 22bb2: 23 br label %bb3 24bb3: 25 store i32 0, ptr %P 26 ret void 27} 28 29define void @test3(ptr noalias %P) { 30; CHECK-LABEL: @test3( 31; CHECK-NEXT: store i32 0, ptr [[P:%.*]], align 4 32; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]] 33; CHECK: bb1: 34; CHECK-NEXT: br label [[BB3:%.*]] 35; CHECK: bb2: 36; CHECK-NEXT: store i32 1, ptr [[P]], align 4 37; CHECK-NEXT: br label [[BB3]] 38; CHECK: bb3: 39; CHECK-NEXT: ret void 40; 41 store i32 0, ptr %P 42 br i1 true, label %bb1, label %bb2 43bb1: 44 br label %bb3 45bb2: 46 store i32 1, ptr %P 47 br label %bb3 48bb3: 49 ret void 50} 51 52 53define void @test7(ptr noalias %P, ptr noalias %Q) { 54; CHECK-LABEL: @test7( 55; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]] 56; CHECK: bb1: 57; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[P:%.*]], align 4 58; CHECK-NEXT: br label [[BB3:%.*]] 59; CHECK: bb2: 60; CHECK-NEXT: br label [[BB3]] 61; CHECK: bb3: 62; CHECK-NEXT: store i32 0, ptr [[Q:%.*]], align 4 63; CHECK-NEXT: store i32 0, ptr [[P]], align 4 64; CHECK-NEXT: ret void 65; 66 store i32 1, ptr %Q 67 br i1 true, label %bb1, label %bb2 68bb1: 69 load i32, ptr %P 70 br label %bb3 71bb2: 72 br label %bb3 73bb3: 74 store i32 0, ptr %Q 75 store i32 0, ptr %P 76 ret void 77} 78 79define i32 @test22(ptr %P, ptr noalias %Q, ptr %R) { 80; CHECK-LABEL: @test22( 81; CHECK-NEXT: store i32 2, ptr [[P:%.*]], align 4 82; CHECK-NEXT: store i32 3, ptr [[Q:%.*]], align 4 83; CHECK-NEXT: [[L:%.*]] = load i32, ptr [[R:%.*]], align 4 84; CHECK-NEXT: ret i32 [[L]] 85; 86 store i32 1, ptr %Q 87 store i32 2, ptr %P 88 store i32 3, ptr %Q 89 %l = load i32, ptr %R 90 ret i32 %l 91} 92 93define void @test9(ptr noalias %P) { 94; CHECK-LABEL: @test9( 95; CHECK-NEXT: store i32 0, ptr [[P:%.*]], align 4 96; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]] 97; CHECK: bb1: 98; CHECK-NEXT: br label [[BB3:%.*]] 99; CHECK: bb2: 100; CHECK-NEXT: ret void 101; CHECK: bb3: 102; CHECK-NEXT: store i32 1, ptr [[P]], align 4 103; CHECK-NEXT: ret void 104; 105 store i32 0, ptr %P 106 br i1 true, label %bb1, label %bb2 107bb1: 108 br label %bb3 109bb2: 110 ret void 111bb3: 112 store i32 1, ptr %P 113 ret void 114} 115 116; We cannot eliminate `store i32 0, ptr %P`, as it is read by the later load. 117; Make sure that we check the uses of `store i32 1, ptr %P.1 which does not 118; alias %P. Note that uses point to the *first* def that may alias. 119define void @overlapping_read(ptr %P) { 120; CHECK-LABEL: @overlapping_read( 121; CHECK-NEXT: store i32 0, ptr [[P:%.*]], align 4 122; CHECK-NEXT: [[P_1:%.*]] = getelementptr i32, ptr [[P]], i32 1 123; CHECK-NEXT: store i32 1, ptr [[P_1]], align 4 124; CHECK-NEXT: [[LV:%.*]] = load i64, ptr [[P]], align 8 125; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]] 126; CHECK: bb1: 127; CHECK-NEXT: br label [[BB3:%.*]] 128; CHECK: bb2: 129; CHECK-NEXT: br label [[BB3]] 130; CHECK: bb3: 131; CHECK-NEXT: store i32 2, ptr [[P]], align 4 132; CHECK-NEXT: ret void 133; 134 store i32 0, ptr %P 135 %P.1 = getelementptr i32, ptr %P, i32 1 136 store i32 1, ptr %P.1 137 138 %lv = load i64, ptr %P 139 br i1 true, label %bb1, label %bb2 140bb1: 141 br label %bb3 142bb2: 143 br label %bb3 144bb3: 145 store i32 2, ptr %P 146 ret void 147} 148 149define void @test10(ptr %P) { 150; CHECK-LABEL: @test10( 151; CHECK-NEXT: store i32 0, ptr [[P:%.*]], align 4 152; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]] 153; CHECK: bb1: 154; CHECK-NEXT: store i32 1, ptr [[P]], align 4 155; CHECK-NEXT: br label [[BB3:%.*]] 156; CHECK: bb2: 157; CHECK-NEXT: ret void 158; CHECK: bb3: 159; CHECK-NEXT: ret void 160; 161 store i32 0, ptr %P 162 br i1 true, label %bb1, label %bb2 163bb1: 164 store i32 1, ptr %P 165 br label %bb3 166bb2: 167 ret void 168bb3: 169 ret void 170} 171 172 173define void @test11() { 174; CHECK-LABEL: @test11( 175; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]] 176; CHECK: bb1: 177; CHECK-NEXT: br label [[BB3:%.*]] 178; CHECK: bb2: 179; CHECK-NEXT: ret void 180; CHECK: bb3: 181; CHECK-NEXT: ret void 182; 183 %P = alloca i32 184 store i32 0, ptr %P 185 br i1 true, label %bb1, label %bb2 186bb1: 187 store i32 0, ptr %P 188 br label %bb3 189bb2: 190 ret void 191bb3: 192 ret void 193} 194 195 196define void @test12(ptr %P) { 197; CHECK-LABEL: @test12( 198; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]] 199; CHECK: bb1: 200; CHECK-NEXT: store i32 1, ptr [[P:%.*]], align 4 201; CHECK-NEXT: br label [[BB3:%.*]] 202; CHECK: bb2: 203; CHECK-NEXT: store i32 1, ptr [[P]], align 4 204; CHECK-NEXT: ret void 205; CHECK: bb3: 206; CHECK-NEXT: ret void 207; 208 store i32 0, ptr %P 209 br i1 true, label %bb1, label %bb2 210bb1: 211 store i32 1, ptr %P 212 br label %bb3 213bb2: 214 store i32 1, ptr %P 215 ret void 216bb3: 217 ret void 218} 219 220 221define void @test13(ptr %P) { 222; CHECK-LABEL: @test13( 223; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]] 224; CHECK: bb1: 225; CHECK-NEXT: store i32 1, ptr [[P:%.*]], align 4 226; CHECK-NEXT: br label [[BB3:%.*]] 227; CHECK: bb2: 228; CHECK-NEXT: store i32 1, ptr [[P]], align 4 229; CHECK-NEXT: br label [[BB3]] 230; CHECK: bb3: 231; CHECK-NEXT: ret void 232; 233 store i32 0, ptr %P 234 br i1 true, label %bb1, label %bb2 235bb1: 236 store i32 1, ptr %P 237 br label %bb3 238bb2: 239 store i32 1, ptr %P 240 br label %bb3 241bb3: 242 ret void 243} 244