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" 5declare void @llvm.memset.p0.i64(ptr nocapture, i8, i64, i32, i1) nounwind 6 7define void @test13(ptr noalias %P) { 8; CHECK-LABEL: @test13( 9; CHECK-NEXT: entry: 10; CHECK-NEXT: br label [[FOR:%.*]] 11; CHECK: for: 12; CHECK-NEXT: store i32 0, ptr [[P:%.*]], align 4 13; CHECK-NEXT: br i1 false, label [[FOR]], label [[END:%.*]] 14; CHECK: end: 15; CHECK-NEXT: ret void 16; 17entry: 18 br label %for 19for: 20 store i32 0, ptr %P 21 br i1 false, label %for, label %end 22end: 23 ret void 24} 25 26 27define void @test14(ptr noalias %P) { 28; CHECK-LABEL: @test14( 29; CHECK-NEXT: entry: 30; CHECK-NEXT: br label [[FOR:%.*]] 31; CHECK: for: 32; CHECK-NEXT: store i32 0, ptr [[P:%.*]], align 4 33; CHECK-NEXT: br i1 false, label [[FOR]], label [[END:%.*]] 34; CHECK: end: 35; CHECK-NEXT: ret void 36; 37entry: 38 store i32 1, ptr %P 39 br label %for 40for: 41 store i32 0, ptr %P 42 br i1 false, label %for, label %end 43end: 44 ret void 45} 46 47define void @test18(ptr noalias %P) { 48; CHECK-LABEL: @test18( 49; CHECK-NEXT: entry: 50; CHECK-NEXT: store i32 0, ptr [[P:%.*]], align 4 51; CHECK-NEXT: br label [[FOR:%.*]] 52; CHECK: for: 53; CHECK-NEXT: store i8 1, ptr [[P]], align 1 54; CHECK-NEXT: [[X:%.*]] = load i32, ptr [[P]], align 4 55; CHECK-NEXT: store i8 2, ptr [[P]], align 1 56; CHECK-NEXT: br i1 false, label [[FOR]], label [[END:%.*]] 57; CHECK: end: 58; CHECK-NEXT: ret void 59; 60entry: 61 store i32 0, ptr %P 62 br label %for 63for: 64 store i8 1, ptr %P 65 %x = load i32, ptr %P 66 store i8 2, ptr %P 67 br i1 false, label %for, label %end 68end: 69 ret void 70} 71 72define void @test21(ptr noalias %P) { 73; CHECK-LABEL: @test21( 74; CHECK-NEXT: entry: 75; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 1 76; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[ARRAYIDX0]], i64 4 77; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[TMP0]], i8 0, i64 24, i1 false) 78; CHECK-NEXT: br label [[FOR:%.*]] 79; CHECK: for: 80; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 1 81; CHECK-NEXT: store i32 1, ptr [[ARRAYIDX1]], align 4 82; CHECK-NEXT: br i1 false, label [[FOR]], label [[END:%.*]] 83; CHECK: end: 84; CHECK-NEXT: ret void 85; 86entry: 87 %arrayidx0 = getelementptr inbounds i32, ptr %P, i64 1 88 call void @llvm.memset.p0.i64(ptr %arrayidx0, i8 0, i64 28, i32 4, i1 false) 89 br label %for 90for: 91 %arrayidx1 = getelementptr inbounds i32, ptr %P, i64 1 92 store i32 1, ptr %arrayidx1, align 4 93 br i1 false, label %for, label %end 94end: 95 ret void 96} 97 98define void @test_loop(i32 %N, ptr noalias nocapture readonly %A, ptr noalias nocapture readonly %x, ptr noalias nocapture %b) local_unnamed_addr { 99; CHECK-LABEL: @test_loop( 100; CHECK-NEXT: entry: 101; CHECK-NEXT: [[CMP27:%.*]] = icmp sgt i32 [[N:%.*]], 0 102; CHECK-NEXT: br i1 [[CMP27]], label [[FOR_BODY4_LR_PH_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]] 103; CHECK: for.body4.lr.ph.preheader: 104; CHECK-NEXT: br label [[FOR_BODY4_LR_PH:%.*]] 105; CHECK: for.cond.cleanup: 106; CHECK-NEXT: ret void 107; CHECK: for.body4.lr.ph: 108; CHECK-NEXT: [[I_028:%.*]] = phi i32 [ [[INC11:%.*]], [[FOR_COND_CLEANUP3:%.*]] ], [ 0, [[FOR_BODY4_LR_PH_PREHEADER]] ] 109; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[B:%.*]], i32 [[I_028]] 110; CHECK-NEXT: [[MUL:%.*]] = mul nsw i32 [[I_028]], [[N]] 111; CHECK-NEXT: br label [[FOR_BODY4:%.*]] 112; CHECK: for.body4: 113; CHECK-NEXT: [[TMP0:%.*]] = phi i32 [ 0, [[FOR_BODY4_LR_PH]] ], [ [[ADD9:%.*]], [[FOR_BODY4]] ] 114; CHECK-NEXT: [[J_026:%.*]] = phi i32 [ 0, [[FOR_BODY4_LR_PH]] ], [ [[INC:%.*]], [[FOR_BODY4]] ] 115; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[J_026]], [[MUL]] 116; CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[ADD]] 117; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX5]], align 4 118; CHECK-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds i32, ptr [[X:%.*]], i32 [[J_026]] 119; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX6]], align 4 120; CHECK-NEXT: [[MUL7:%.*]] = mul nsw i32 [[TMP2]], [[TMP1]] 121; CHECK-NEXT: [[ADD9]] = add nsw i32 [[MUL7]], [[TMP0]] 122; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[J_026]], 1 123; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INC]], [[N]] 124; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP3]], label [[FOR_BODY4]] 125; CHECK: for.cond.cleanup3: 126; CHECK-NEXT: store i32 [[ADD9]], ptr [[ARRAYIDX]], align 4 127; CHECK-NEXT: [[INC11]] = add nuw nsw i32 [[I_028]], 1 128; CHECK-NEXT: [[EXITCOND29:%.*]] = icmp eq i32 [[INC11]], [[N]] 129; CHECK-NEXT: br i1 [[EXITCOND29]], label [[FOR_COND_CLEANUP]], label [[FOR_BODY4_LR_PH]] 130; 131entry: 132 %cmp27 = icmp sgt i32 %N, 0 133 br i1 %cmp27, label %for.body4.lr.ph.preheader, label %for.cond.cleanup 134 135for.body4.lr.ph.preheader: ; preds = %entry 136 br label %for.body4.lr.ph 137 138for.cond.cleanup: ; preds = %for.cond.cleanup3, %entry 139 ret void 140 141for.body4.lr.ph: ; preds = %for.body4.lr.ph.preheader, %for.cond.cleanup3 142 %i.028 = phi i32 [ %inc11, %for.cond.cleanup3 ], [ 0, %for.body4.lr.ph.preheader ] 143 %arrayidx = getelementptr inbounds i32, ptr %b, i32 %i.028 144 store i32 0, ptr %arrayidx, align 4 145 %mul = mul nsw i32 %i.028, %N 146 br label %for.body4 147 148for.body4: ; preds = %for.body4, %for.body4.lr.ph 149 %0 = phi i32 [ 0, %for.body4.lr.ph ], [ %add9, %for.body4 ] 150 %j.026 = phi i32 [ 0, %for.body4.lr.ph ], [ %inc, %for.body4 ] 151 %add = add nsw i32 %j.026, %mul 152 %arrayidx5 = getelementptr inbounds i32, ptr %A, i32 %add 153 %1 = load i32, ptr %arrayidx5, align 4 154 %arrayidx6 = getelementptr inbounds i32, ptr %x, i32 %j.026 155 %2 = load i32, ptr %arrayidx6, align 4 156 %mul7 = mul nsw i32 %2, %1 157 %add9 = add nsw i32 %mul7, %0 158 %inc = add nuw nsw i32 %j.026, 1 159 %exitcond = icmp eq i32 %inc, %N 160 br i1 %exitcond, label %for.cond.cleanup3, label %for.body4 161 162for.cond.cleanup3: ; preds = %for.body4 163 store i32 %add9, ptr %arrayidx, align 4 164 %inc11 = add nuw nsw i32 %i.028, 1 165 %exitcond29 = icmp eq i32 %inc11, %N 166 br i1 %exitcond29, label %for.cond.cleanup, label %for.body4.lr.ph 167} 168 169define i32 @test_if(i1 %c, ptr %p, i32 %i) { 170; CHECK-LABEL: @test_if( 171; CHECK-NEXT: entry: 172; CHECK-NEXT: br label [[BB1:%.*]] 173; CHECK: bb1: 174; CHECK-NEXT: [[PH:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[BB3:%.*]] ] 175; CHECK-NEXT: [[INC]] = add i32 [[PH]], 1 176; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i32 [[PH]] 177; CHECK-NEXT: br i1 [[C:%.*]], label [[BB2:%.*]], label [[BB3]] 178; CHECK: bb2: 179; CHECK-NEXT: br label [[BB3]] 180; CHECK: bb3: 181; CHECK-NEXT: store i32 2, ptr [[GEP]], align 4 182; CHECK-NEXT: [[C1:%.*]] = icmp slt i32 [[PH]], 10 183; CHECK-NEXT: br i1 [[C1]], label [[BB1]], label [[EXIT:%.*]] 184; CHECK: exit: 185; CHECK-NEXT: ret i32 0 186; 187entry: 188 br label %bb1 189bb1: 190 %ph = phi i32 [ 0, %entry ], [ %inc, %bb3 ] 191 %inc = add i32 %ph, 1 192 %gep = getelementptr inbounds i32, ptr %p, i32 %ph 193 store i32 %i, ptr %gep, align 4 194 br i1 %c, label %bb2, label %bb3 195bb2: 196 br label %bb3 197bb3: 198 store i32 2, ptr %gep, align 4 199 %c1 = icmp slt i32 %ph, 10 200 br i1 %c1, label %bb1, label %exit 201exit: 202 ret i32 0 203} 204 205define i32 @test_if2(i1 %c, ptr %p, i32 %i) { 206; CHECK-LABEL: @test_if2( 207; CHECK-NEXT: entry: 208; CHECK-NEXT: br label [[BB1:%.*]] 209; CHECK: bb1: 210; CHECK-NEXT: [[PH:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[BB2:%.*]] ], [ [[INC]], [[BB3:%.*]] ] 211; CHECK-NEXT: [[INC]] = add i32 [[PH]], 1 212; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i32 [[PH]] 213; CHECK-NEXT: br i1 [[C:%.*]], label [[BB2]], label [[BB3]] 214; CHECK: bb2: 215; CHECK-NEXT: store i32 2, ptr [[GEP]], align 4 216; CHECK-NEXT: [[C1:%.*]] = icmp slt i32 [[PH]], 10 217; CHECK-NEXT: br i1 [[C1]], label [[BB1]], label [[EXIT:%.*]] 218; CHECK: bb3: 219; CHECK-NEXT: store i32 3, ptr [[GEP]], align 4 220; CHECK-NEXT: [[C2:%.*]] = icmp slt i32 [[PH]], 5 221; CHECK-NEXT: br i1 [[C2]], label [[BB1]], label [[EXIT]] 222; CHECK: exit: 223; CHECK-NEXT: ret i32 0 224; 225entry: 226 br label %bb1 227bb1: 228 %ph = phi i32 [ 0, %entry ], [ %inc, %bb2 ], [ %inc, %bb3 ] 229 %inc = add i32 %ph, 1 230 %gep = getelementptr inbounds i32, ptr %p, i32 %ph 231 store i32 %i, ptr %gep, align 4 232 br i1 %c, label %bb2, label %bb3 233bb2: 234 store i32 2, ptr %gep, align 4 235 %c1 = icmp slt i32 %ph, 10 236 br i1 %c1, label %bb1, label %exit 237bb3: 238 store i32 3, ptr %gep, align 4 239 %c2 = icmp slt i32 %ph, 5 240 br i1 %c2, label %bb1, label %exit 241exit: 242 ret i32 0 243} 244 245define i32 @test_if3(i1 %c, ptr %p, i32 %i) { 246; CHECK-LABEL: @test_if3( 247; CHECK-NEXT: entry: 248; CHECK-NEXT: br label [[BB1:%.*]] 249; CHECK: bb1: 250; CHECK-NEXT: [[PH:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[BB3:%.*]] ] 251; CHECK-NEXT: [[INC]] = add i32 [[PH]], 1 252; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i32 [[PH]] 253; CHECK-NEXT: store i32 [[I:%.*]], ptr [[GEP]], align 4 254; CHECK-NEXT: br i1 [[C:%.*]], label [[BB2:%.*]], label [[BB3]] 255; CHECK: bb2: 256; CHECK-NEXT: store i32 2, ptr [[GEP]], align 4 257; CHECK-NEXT: br label [[BB3]] 258; CHECK: bb3: 259; CHECK-NEXT: [[C1:%.*]] = icmp slt i32 [[PH]], 10 260; CHECK-NEXT: br i1 [[C1]], label [[BB1]], label [[EXIT:%.*]] 261; CHECK: exit: 262; CHECK-NEXT: ret i32 0 263; 264entry: 265 br label %bb1 266bb1: 267 %ph = phi i32 [ 0, %entry ], [ %inc, %bb3 ] 268 %inc = add i32 %ph, 1 269 %gep = getelementptr inbounds i32, ptr %p, i32 %ph 270 store i32 %i, ptr %gep, align 4 271 br i1 %c, label %bb2, label %bb3 272bb2: 273 store i32 2, ptr %gep, align 4 274 br label %bb3 275bb3: 276 %c1 = icmp slt i32 %ph, 10 277 br i1 %c1, label %bb1, label %exit 278exit: 279 ret i32 0 280} 281 282define i32 @test_if4(i1 %c, ptr %p, i32 %i) { 283; CHECK-LABEL: @test_if4( 284; CHECK-NEXT: entry: 285; CHECK-NEXT: br label [[BB1:%.*]] 286; CHECK: bb1: 287; CHECK-NEXT: [[PH:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[BB1]] ], [ [[INC]], [[BB2:%.*]] ] 288; CHECK-NEXT: [[INC]] = add i32 [[PH]], 1 289; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i32 [[PH]] 290; CHECK-NEXT: store i32 [[I:%.*]], ptr [[GEP]], align 4 291; CHECK-NEXT: br i1 [[C:%.*]], label [[BB2]], label [[BB1]] 292; CHECK: bb2: 293; CHECK-NEXT: store i32 2, ptr [[GEP]], align 4 294; CHECK-NEXT: [[C1:%.*]] = icmp slt i32 [[PH]], 10 295; CHECK-NEXT: br i1 [[C1]], label [[BB1]], label [[EXIT:%.*]] 296; CHECK: exit: 297; CHECK-NEXT: ret i32 0 298; 299entry: 300 br label %bb1 301bb1: 302 %ph = phi i32 [ 0, %entry ], [ %inc, %bb1 ], [ %inc, %bb2 ] 303 %inc = add i32 %ph, 1 304 %gep = getelementptr inbounds i32, ptr %p, i32 %ph 305 store i32 %i, ptr %gep, align 4 306 br i1 %c, label %bb2, label %bb1 307bb2: 308 store i32 2, ptr %gep, align 4 309 %c1 = icmp slt i32 %ph, 10 310 br i1 %c1, label %bb1, label %exit 311exit: 312 ret i32 0 313} 314 315declare void @clobber() 316define i32 @test_self(i1 %c, ptr %p, i32 %i) { 317; CHECK-LABEL: @test_self( 318; CHECK-NEXT: entry: 319; CHECK-NEXT: br label [[BB1:%.*]] 320; CHECK: bb1: 321; CHECK-NEXT: [[PH:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[BB1]] ], [ [[INC]], [[BB2:%.*]] ] 322; CHECK-NEXT: [[INC]] = add i32 [[PH]], 1 323; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i32 [[PH]] 324; CHECK-NEXT: store i32 1, ptr [[GEP]], align 4 325; CHECK-NEXT: call void @clobber() 326; CHECK-NEXT: store i32 2, ptr [[GEP]], align 4 327; CHECK-NEXT: br i1 [[C:%.*]], label [[BB2]], label [[BB1]] 328; CHECK: bb2: 329; CHECK-NEXT: store i32 3, ptr [[GEP]], align 4 330; CHECK-NEXT: [[C1:%.*]] = icmp slt i32 [[PH]], 10 331; CHECK-NEXT: br i1 [[C1]], label [[BB1]], label [[EXIT:%.*]] 332; CHECK: exit: 333; CHECK-NEXT: ret i32 0 334; 335entry: 336 br label %bb1 337bb1: 338 %ph = phi i32 [ 0, %entry ], [ %inc, %bb1 ], [ %inc, %bb2 ] 339 %inc = add i32 %ph, 1 340 %gep = getelementptr inbounds i32, ptr %p, i32 %ph 341 store i32 1, ptr %gep, align 4 342 call void @clobber() 343 store i32 2, ptr %gep, align 4 344 br i1 %c, label %bb2, label %bb1 345bb2: 346 store i32 3, ptr %gep, align 4 347 %c1 = icmp slt i32 %ph, 10 348 br i1 %c1, label %bb1, label %exit 349exit: 350 ret i32 0 351} 352 353define i32 @test_selfalloca(i1 %c, i32 %i) { 354; CHECK-LABEL: @test_selfalloca( 355; CHECK-NEXT: entry: 356; CHECK-NEXT: [[P:%.*]] = alloca i32, align 4 357; CHECK-NEXT: br label [[BB1:%.*]] 358; CHECK: bb1: 359; CHECK-NEXT: [[PH:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[BB1]] ], [ [[INC]], [[BB2:%.*]] ] 360; CHECK-NEXT: [[INC]] = add i32 [[PH]], 1 361; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[P]], i32 [[PH]] 362; CHECK-NEXT: call void @clobber() 363; CHECK-NEXT: store i32 2, ptr [[GEP]], align 4 364; CHECK-NEXT: br i1 [[C:%.*]], label [[BB2]], label [[BB1]] 365; CHECK: bb2: 366; CHECK-NEXT: store i32 3, ptr [[GEP]], align 4 367; CHECK-NEXT: [[C1:%.*]] = icmp slt i32 [[PH]], 10 368; CHECK-NEXT: br i1 [[C1]], label [[BB1]], label [[EXIT:%.*]] 369; CHECK: exit: 370; CHECK-NEXT: [[PG:%.*]] = getelementptr inbounds i32, ptr [[P]], i32 [[I:%.*]] 371; CHECK-NEXT: [[L:%.*]] = load i32, ptr [[PG]], align 4 372; CHECK-NEXT: ret i32 [[L]] 373; 374entry: 375 %p = alloca i32, align 4 376 br label %bb1 377bb1: 378 %ph = phi i32 [ 0, %entry ], [ %inc, %bb1 ], [ %inc, %bb2 ] 379 %inc = add i32 %ph, 1 380 %gep = getelementptr inbounds i32, ptr %p, i32 %ph 381 store i32 1, ptr %gep, align 4 382 call void @clobber() 383 store i32 2, ptr %gep, align 4 384 br i1 %c, label %bb2, label %bb1 385bb2: 386 store i32 3, ptr %gep, align 4 387 %c1 = icmp slt i32 %ph, 10 388 br i1 %c1, label %bb1, label %exit 389exit: 390 %pg = getelementptr inbounds i32, ptr %p, i32 %i 391 %l = load i32, ptr %pg 392 ret i32 %l 393} 394 395declare i1 @cond() readnone nounwind 396 397define void @loop_multiple_def_uses(ptr noalias %P) { 398; CHECK-LABEL: @loop_multiple_def_uses( 399; CHECK-NEXT: entry: 400; CHECK-NEXT: br label [[FOR_HEADER:%.*]] 401; CHECK: for.header: 402; CHECK-NEXT: [[C1:%.*]] = call i1 @cond() 403; CHECK-NEXT: br i1 [[C1]], label [[FOR_BODY:%.*]], label [[END:%.*]] 404; CHECK: for.body: 405; CHECK-NEXT: store i32 2, ptr [[P:%.*]], align 4 406; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[P]], align 4 407; CHECK-NEXT: br label [[FOR_HEADER]] 408; CHECK: end: 409; CHECK-NEXT: store i32 3, ptr [[P]], align 4 410; CHECK-NEXT: ret void 411; 412entry: 413 br label %for.header 414 415for.header: 416 store i32 1, ptr %P, align 4 417 %c1 = call i1 @cond() 418 br i1 %c1, label %for.body, label %end 419 420for.body: 421 store i32 2, ptr %P, align 4 422 %lv = load i32, ptr %P 423 br label %for.header 424 425end: 426 store i32 3, ptr %P, align 4 427 ret void 428} 429 430; We cannot eliminate the store in for.header, as it is only partially 431; overwritten in for.body and read afterwards. 432define void @loop_multiple_def_uses_partial_write(ptr noalias %p) { 433; CHECK-LABEL: @loop_multiple_def_uses_partial_write( 434; CHECK-NEXT: entry: 435; CHECK-NEXT: br label [[FOR_HEADER:%.*]] 436; CHECK: for.header: 437; CHECK-NEXT: store i32 1239297, ptr [[P:%.*]], align 4 438; CHECK-NEXT: [[C1:%.*]] = call i1 @cond() 439; CHECK-NEXT: br i1 [[C1]], label [[FOR_BODY:%.*]], label [[END:%.*]] 440; CHECK: for.body: 441; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[P]], align 4 442; CHECK-NEXT: br label [[FOR_HEADER]] 443; CHECK: end: 444; CHECK-NEXT: store i32 3, ptr [[P]], align 4 445; CHECK-NEXT: ret void 446; 447entry: 448 br label %for.header 449 450for.header: 451 store i32 1239491, ptr %p, align 4 452 %c1 = call i1 @cond() 453 br i1 %c1, label %for.body, label %end 454 455for.body: 456 store i8 1, ptr %p, align 4 457 %lv = load i32, ptr %p 458 br label %for.header 459 460end: 461 store i32 3, ptr %p, align 4 462 ret void 463} 464 465; We cannot eliminate the store in for.header, as the location is not overwritten 466; in for.body and read afterwards. 467define void @loop_multiple_def_uses_mayalias_write(ptr %p, ptr %q) { 468; CHECK-LABEL: @loop_multiple_def_uses_mayalias_write( 469; CHECK-NEXT: entry: 470; CHECK-NEXT: br label [[FOR_HEADER:%.*]] 471; CHECK: for.header: 472; CHECK-NEXT: store i32 1239491, ptr [[P:%.*]], align 4 473; CHECK-NEXT: [[C1:%.*]] = call i1 @cond() 474; CHECK-NEXT: br i1 [[C1]], label [[FOR_BODY:%.*]], label [[END:%.*]] 475; CHECK: for.body: 476; CHECK-NEXT: store i32 1, ptr [[Q:%.*]], align 4 477; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[P]], align 4 478; CHECK-NEXT: br label [[FOR_HEADER]] 479; CHECK: end: 480; CHECK-NEXT: store i32 3, ptr [[P]], align 4 481; CHECK-NEXT: ret void 482; 483entry: 484 br label %for.header 485 486for.header: 487 store i32 1239491, ptr %p, align 4 488 %c1 = call i1 @cond() 489 br i1 %c1, label %for.body, label %end 490 491for.body: 492 store i32 1, ptr %q, align 4 493 %lv = load i32, ptr %p 494 br label %for.header 495 496end: 497 store i32 3, ptr %p, align 4 498 ret void 499} 500 501%struct.hoge = type { i32, i32 } 502 503@global = external local_unnamed_addr global ptr, align 8 504 505define void @widget(ptr %tmp) { 506; CHECK-LABEL: @widget( 507; CHECK-NEXT: bb: 508; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[TMP:%.*]], ptr nonnull align 16 undef, i64 64, i1 false) 509; CHECK-NEXT: br label [[BB1:%.*]] 510; CHECK: bb1: 511; CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr @global, align 8 512; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds [[STRUCT_HOGE:%.*]], ptr [[TMP2]], i64 undef, i32 1 513; CHECK-NEXT: store i32 0, ptr [[TMP3]], align 4 514; CHECK-NEXT: [[TMP4:%.*]] = load ptr, ptr @global, align 8 515; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT_HOGE]], ptr [[TMP4]], i64 undef, i32 1 516; CHECK-NEXT: store i32 10, ptr [[TMP5]], align 4 517; CHECK-NEXT: br label [[BB1]] 518; 519bb: 520 call void @llvm.memcpy.p0.p0.i64(ptr align 1 %tmp, ptr nonnull align 16 undef, i64 64, i1 false) 521 br label %bb1 522 523bb1: ; preds = %bb1, %bb 524 %tmp2 = load ptr, ptr @global, align 8 525 %tmp3 = getelementptr inbounds %struct.hoge, ptr %tmp2, i64 undef, i32 1 526 store i32 0, ptr %tmp3, align 4 527 %tmp4 = load ptr, ptr @global, align 8 528 %tmp5 = getelementptr inbounds %struct.hoge, ptr %tmp4, i64 undef, i32 1 529 store i32 10, ptr %tmp5, align 4 530 br label %bb1 531} 532 533declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) 534 535@x = global [10 x i16] zeroinitializer, align 1 536 537; Make sure we do not eliminate the store in %do.body, because it writes to 538; multiple locations in the loop and the store in %if.end10 only stores to 539; the last one. 540define i16 @test_loop_carried_dep() { 541; CHECK-LABEL: @test_loop_carried_dep( 542; CHECK-NEXT: entry: 543; CHECK-NEXT: br label [[DO_BODY:%.*]] 544; CHECK: do.body: 545; CHECK-NEXT: [[I_0:%.*]] = phi i16 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[IF_END:%.*]] ] 546; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds [10 x i16], ptr @x, i16 0, i16 [[I_0]] 547; CHECK-NEXT: store i16 2, ptr [[ARRAYIDX2]], align 1 548; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i16 [[I_0]], 4 549; CHECK-NEXT: br i1 [[EXITCOND]], label [[IF_END10:%.*]], label [[IF_END]] 550; CHECK: if.end: 551; CHECK-NEXT: [[INC]] = add nuw nsw i16 [[I_0]], 1 552; CHECK-NEXT: br label [[DO_BODY]] 553; CHECK: if.end10: 554; CHECK-NEXT: store i16 1, ptr [[ARRAYIDX2]], align 1 555; CHECK-NEXT: ret i16 0 556; 557entry: 558 br label %do.body 559 560do.body: ; preds = %if.end, %entry 561 %i.0 = phi i16 [ 0, %entry ], [ %inc, %if.end ] 562 %arrayidx2 = getelementptr inbounds [10 x i16], ptr @x, i16 0, i16 %i.0 563 store i16 2, ptr %arrayidx2, align 1 564 %exitcond = icmp eq i16 %i.0, 4 565 br i1 %exitcond, label %if.end10, label %if.end 566 567if.end: ; preds = %do.body 568 %inc = add nuw nsw i16 %i.0, 1 569 br label %do.body 570 571if.end10: ; preds = %do.body 572 store i16 1, ptr %arrayidx2, align 1 573 ret i16 0 574} 575 576; Similar to above, but with an irreducible loop. The stores should not be removed. 577define i16 @irreducible(i1 %c) { 578; CHECK-LABEL: @irreducible( 579; CHECK-NEXT: entry: 580; CHECK-NEXT: br i1 [[C:%.*]], label [[A:%.*]], label [[B:%.*]] 581; CHECK: A: 582; CHECK-NEXT: [[I_0:%.*]] = phi i16 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[B]] ] 583; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds [10 x i16], ptr @x, i16 0, i16 [[I_0]] 584; CHECK-NEXT: br label [[B]] 585; CHECK: B: 586; CHECK-NEXT: [[J_0:%.*]] = phi i16 [ 0, [[ENTRY]] ], [ [[I_0]], [[A]] ] 587; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x i16], ptr @x, i16 0, i16 [[J_0]] 588; CHECK-NEXT: store i16 2, ptr [[ARRAYIDX]], align 1 589; CHECK-NEXT: [[INC]] = add nuw nsw i16 [[J_0]], 1 590; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i16 [[J_0]], 4 591; CHECK-NEXT: br i1 [[EXITCOND]], label [[EXIT:%.*]], label [[A]] 592; CHECK: exit: 593; CHECK-NEXT: store i16 1, ptr [[ARRAYIDX]], align 1 594; CHECK-NEXT: ret i16 0 595; 596entry: 597 br i1 %c, label %A, label %B 598 599A: 600 %i.0 = phi i16 [ 0, %entry ], [ %inc, %B ] 601 %arrayidx2 = getelementptr inbounds [10 x i16], ptr @x, i16 0, i16 %i.0 602 br label %B 603 604B: 605 %j.0 = phi i16 [ 0, %entry ], [ %i.0, %A ] 606 %arrayidx = getelementptr inbounds [10 x i16], ptr @x, i16 0, i16 %j.0 607 store i16 2, ptr %arrayidx, align 1 608 %inc = add nuw nsw i16 %j.0, 1 609 %exitcond = icmp eq i16 %j.0, 4 610 br i1 %exitcond, label %exit, label %A 611 612exit: 613 store i16 1, ptr %arrayidx, align 1 614 ret i16 0 615} 616 617define i16 @irreducible_entryblock_def(i1 %c) { 618; CHECK-LABEL: @irreducible_entryblock_def( 619; CHECK-NEXT: entry: 620; CHECK-NEXT: br i1 [[C:%.*]], label [[A:%.*]], label [[B:%.*]] 621; CHECK: A: 622; CHECK-NEXT: br label [[B]] 623; CHECK: B: 624; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[A]] 625; CHECK: exit: 626; CHECK-NEXT: ret i16 0 627; 628entry: 629 %obj = alloca i32, align 4 630 br i1 %c, label %A, label %B 631 632A: 633 store i32 1, ptr %obj, align 4 634 br label %B 635 636B: 637 br i1 %c, label %exit, label %A 638 639exit: 640 ret i16 0 641} 642 643; An irreducible loop inside another loop. 644define i16 @irreducible_nested() { 645; CHECK-LABEL: @irreducible_nested( 646; CHECK-NEXT: entry: 647; CHECK-NEXT: br label [[OUTER:%.*]] 648; CHECK: outer: 649; CHECK-NEXT: [[X:%.*]] = phi i16 [ 0, [[ENTRY:%.*]] ], [ [[INCX:%.*]], [[OUTERL:%.*]] ] 650; CHECK-NEXT: [[C:%.*]] = icmp sgt i16 [[X]], 2 651; CHECK-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]] 652; CHECK: A: 653; CHECK-NEXT: [[I_0:%.*]] = phi i16 [ 0, [[OUTER]] ], [ [[INC:%.*]], [[B]] ] 654; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds [10 x i16], ptr @x, i16 0, i16 [[I_0]] 655; CHECK-NEXT: br label [[B]] 656; CHECK: B: 657; CHECK-NEXT: [[J_0:%.*]] = phi i16 [ 0, [[OUTER]] ], [ [[I_0]], [[A]] ] 658; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x i16], ptr @x, i16 0, i16 [[J_0]] 659; CHECK-NEXT: store i16 2, ptr [[ARRAYIDX]], align 1 660; CHECK-NEXT: [[INC]] = add nuw nsw i16 [[J_0]], 1 661; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i16 [[J_0]], 4 662; CHECK-NEXT: br i1 [[EXITCOND]], label [[OUTERL]], label [[A]] 663; CHECK: outerl: 664; CHECK-NEXT: store i16 1, ptr [[ARRAYIDX]], align 1 665; CHECK-NEXT: [[INCX]] = add nuw nsw i16 [[X]], 1 666; CHECK-NEXT: [[EXITCONDX:%.*]] = icmp eq i16 [[X]], 4 667; CHECK-NEXT: br i1 [[EXITCONDX]], label [[END:%.*]], label [[OUTER]] 668; CHECK: end: 669; CHECK-NEXT: ret i16 0 670; 671entry: 672 br label %outer 673 674outer: 675 %x = phi i16 [ 0, %entry ], [ %incx, %outerl ] 676 %c = icmp sgt i16 %x, 2 677 br i1 %c, label %A, label %B 678 679A: 680 %i.0 = phi i16 [ 0, %outer ], [ %inc, %B ] 681 %arrayidx2 = getelementptr inbounds [10 x i16], ptr @x, i16 0, i16 %i.0 682 br label %B 683 684B: 685 %j.0 = phi i16 [ 0, %outer ], [ %i.0, %A ] 686 %arrayidx = getelementptr inbounds [10 x i16], ptr @x, i16 0, i16 %j.0 687 store i16 2, ptr %arrayidx, align 1 688 %inc = add nuw nsw i16 %j.0, 1 689 %exitcond = icmp eq i16 %j.0, 4 690 br i1 %exitcond, label %outerl, label %A 691 692outerl: 693 store i16 1, ptr %arrayidx, align 1 694 %incx = add nuw nsw i16 %x, 1 695 %exitcondx = icmp eq i16 %x, 4 696 br i1 %exitcondx, label %end, label %outer 697 698end: 699 ret i16 0 700} 701 702define i16 @multi_overwrite(i1 %cond) { 703; CHECK-LABEL: @multi_overwrite( 704; CHECK-NEXT: entry: 705; CHECK-NEXT: br label [[DO_BODY:%.*]] 706; CHECK: do.body: 707; CHECK-NEXT: [[I_0:%.*]] = phi i16 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[IF_END2:%.*]] ] 708; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds [10 x i16], ptr @x, i16 0, i16 [[I_0]] 709; CHECK-NEXT: store i16 2, ptr [[ARRAYIDX2]], align 1 710; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i16 [[I_0]], 4 711; CHECK-NEXT: br i1 [[EXITCOND]], label [[EXIT:%.*]], label [[IF_END:%.*]] 712; CHECK: if.end: 713; CHECK-NEXT: br i1 [[COND:%.*]], label [[DO_STORE:%.*]], label [[IF_END2]] 714; CHECK: do.store: 715; CHECK-NEXT: store i16 3, ptr [[ARRAYIDX2]], align 1 716; CHECK-NEXT: br label [[IF_END2]] 717; CHECK: if.end2: 718; CHECK-NEXT: [[INC]] = add nuw nsw i16 [[I_0]], 1 719; CHECK-NEXT: br label [[DO_BODY]] 720; CHECK: exit: 721; CHECK-NEXT: store i16 1, ptr [[ARRAYIDX2]], align 1 722; CHECK-NEXT: ret i16 0 723; 724entry: 725 br label %do.body 726 727do.body: 728 %i.0 = phi i16 [ 0, %entry ], [ %inc, %if.end2 ] 729 %arrayidx2 = getelementptr inbounds [10 x i16], ptr @x, i16 0, i16 %i.0 730 store i16 2, ptr %arrayidx2, align 1 731 %exitcond = icmp eq i16 %i.0, 4 732 br i1 %exitcond, label %exit, label %if.end 733 734if.end: 735 br i1 %cond, label %do.store, label %if.end2 736 737do.store: 738 store i16 3, ptr %arrayidx2, align 1 739 br label %if.end2 740 741if.end2: 742 %inc = add nuw nsw i16 %i.0, 1 743 br label %do.body 744 745exit: 746 store i16 1, ptr %arrayidx2, align 1 747 ret i16 0 748} 749 750define void @test(ptr noalias %data1, ptr %data2, ptr %data3, i32 %i1) 751; CHECK-LABEL: @test( 752; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[I1:%.*]], 0 753; CHECK-NEXT: br label [[PH0:%.*]] 754; CHECK: ph0: 755; CHECK-NEXT: br label [[HEADER0:%.*]] 756; CHECK: header0: 757; CHECK-NEXT: [[P1:%.*]] = phi i32 [ 0, [[PH0]] ], [ [[PN1:%.*]], [[END1:%.*]] ] 758; CHECK-NEXT: [[PN1]] = add i32 [[P1]], 1 759; CHECK-NEXT: [[PC1:%.*]] = icmp slt i32 [[PN1]], 5 760; CHECK-NEXT: [[V2:%.*]] = getelementptr [10 x i16], ptr @x, i32 0, i32 [[P1]] 761; CHECK-NEXT: store i16 1, ptr [[V2]], align 2 762; CHECK-NEXT: br i1 [[C]], label [[THEN1:%.*]], label [[ELSE1:%.*]] 763; CHECK: then1: 764; CHECK-NEXT: store i16 2, ptr [[V2]], align 2 765; CHECK-NEXT: br label [[END1]] 766; CHECK: else1: 767; CHECK-NEXT: br label [[END1]] 768; CHECK: end1: 769; CHECK-NEXT: br i1 [[PC1]], label [[HEADER0]], label [[END0:%.*]] 770; CHECK: end0: 771; CHECK-NEXT: br label [[HEADER2:%.*]] 772; CHECK: header2: 773; CHECK-NEXT: [[P3:%.*]] = phi i32 [ 0, [[END0]] ], [ [[PN3:%.*]], [[HEADER2]] ] 774; CHECK-NEXT: [[PN3]] = add i32 [[P3]], 1 775; CHECK-NEXT: [[PC3:%.*]] = icmp slt i32 [[PN3]], 5 776; CHECK-NEXT: store i16 4, ptr [[V2]], align 2 777; CHECK-NEXT: br i1 [[PC3]], label [[HEADER2]], label [[END2:%.*]] 778; CHECK: end2: 779; CHECK-NEXT: ret void 780; 781{ 782 %c = icmp eq i32 %i1, 0 783 br label %ph0 784ph0: 785 br label %header0 786header0: 787 %p1 = phi i32 [0, %ph0], [%pn1, %end1] 788 %pn1 = add i32 %p1, 1 789 %pc1 = icmp slt i32 %pn1, 5 790 %v2 = getelementptr [10 x i16], ptr @x, i32 0, i32 %p1 791 store i16 1, ptr %v2 792 br i1 %c, label %then1, label %else1 793then1: 794 store i16 2, ptr %v2 795 br label %end1 796else1: 797 br label %end1 798end1: 799 br i1 %pc1, label %header0, label %end0 800end0: 801 br label %header2 802header2: 803 %p3 = phi i32 [0, %end0], [%pn3, %header2] 804 %pn3 = add i32 %p3, 1 805 %pc3 = icmp slt i32 %pn3, 5 806 store i16 4, ptr %v2 807 br i1 %pc3, label %header2, label %end2 808end2: 809 ret void 810} 811 812; Similar to above, but with multiple partial overlaps 813define i16 @partial_override_fromloop(i1 %c, i32 %i) { 814; CHECK-LABEL: @partial_override_fromloop( 815; CHECK-NEXT: entry: 816; CHECK-NEXT: br label [[DO_BODY:%.*]] 817; CHECK: do.body: 818; CHECK-NEXT: [[I_0:%.*]] = phi i16 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[IF_END2:%.*]] ] 819; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds [10 x i16], ptr @x, i16 0, i16 [[I_0]] 820; CHECK-NEXT: store i16 2, ptr [[ARRAYIDX2]], align 1 821; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i16 [[I_0]], 4 822; CHECK-NEXT: br i1 [[EXITCOND]], label [[EXIT:%.*]], label [[IF_END:%.*]] 823; CHECK: if.end: 824; CHECK-NEXT: br i1 [[C:%.*]], label [[DO_STORE:%.*]], label [[IF_END2]] 825; CHECK: do.store: 826; CHECK-NEXT: store i16 3, ptr [[ARRAYIDX2]], align 1 827; CHECK-NEXT: br label [[IF_END2]] 828; CHECK: if.end2: 829; CHECK-NEXT: [[INC]] = add nuw nsw i16 [[I_0]], 1 830; CHECK-NEXT: br label [[DO_BODY]] 831; CHECK: exit: 832; CHECK-NEXT: [[BC2:%.*]] = getelementptr inbounds i8, ptr [[ARRAYIDX2]], i32 1 833; CHECK-NEXT: store i8 10, ptr [[ARRAYIDX2]], align 1 834; CHECK-NEXT: store i8 11, ptr [[BC2]], align 1 835; CHECK-NEXT: ret i16 0 836; 837entry: 838 br label %do.body 839 840do.body: 841 %i.0 = phi i16 [ 0, %entry ], [ %inc, %if.end2 ] 842 %arrayidx2 = getelementptr inbounds [10 x i16], ptr @x, i16 0, i16 %i.0 843 store i16 2, ptr %arrayidx2, align 1 844 %exitcond = icmp eq i16 %i.0, 4 845 br i1 %exitcond, label %exit, label %if.end 846 847if.end: 848 br i1 %c, label %do.store, label %if.end2 849 850do.store: 851 store i16 3, ptr %arrayidx2, align 1 852 br label %if.end2 853 854if.end2: 855 %inc = add nuw nsw i16 %i.0, 1 856 br label %do.body 857 858exit: 859 %bc2 = getelementptr inbounds i8, ptr %arrayidx2, i32 1 860 store i8 10, ptr %arrayidx2, align 1 861 store i8 11, ptr %bc2, align 1 862 ret i16 0 863} 864 865 866define i16 @partial_override_overloop(i1 %c, i32 %i) { 867; CHECK-LABEL: @partial_override_overloop( 868; CHECK-NEXT: entry: 869; CHECK-NEXT: br label [[FIRST:%.*]] 870; CHECK: first: 871; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x i16], ptr @x, i16 0, i32 [[I:%.*]] 872; CHECK-NEXT: br label [[DO_BODY:%.*]] 873; CHECK: do.body: 874; CHECK-NEXT: [[I_0:%.*]] = phi i16 [ 0, [[FIRST]] ], [ [[INC:%.*]], [[DO_BODY]] ] 875; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds [10 x i16], ptr @x, i16 0, i16 [[I_0]] 876; CHECK-NEXT: store i16 2, ptr [[ARRAYIDX2]], align 1 877; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i16 [[I_0]], 4 878; CHECK-NEXT: [[INC]] = add nuw nsw i16 [[I_0]], 1 879; CHECK-NEXT: br i1 [[EXITCOND]], label [[EXIT:%.*]], label [[DO_BODY]] 880; CHECK: exit: 881; CHECK-NEXT: [[BC2:%.*]] = getelementptr inbounds i8, ptr [[ARRAYIDX]], i32 1 882; CHECK-NEXT: store i8 10, ptr [[ARRAYIDX]], align 1 883; CHECK-NEXT: store i8 11, ptr [[BC2]], align 1 884; CHECK-NEXT: ret i16 0 885; 886entry: 887 ; Branch to first so MemoryLoc is not in the entry block. 888 br label %first 889 890first: 891 %arrayidx = getelementptr inbounds [10 x i16], ptr @x, i16 0, i32 %i 892 store i16 1, ptr %arrayidx, align 1 893 br label %do.body 894 895do.body: 896 %i.0 = phi i16 [ 0, %first ], [ %inc, %do.body ] 897 %arrayidx2 = getelementptr inbounds [10 x i16], ptr @x, i16 0, i16 %i.0 898 store i16 2, ptr %arrayidx2, align 1 899 %exitcond = icmp eq i16 %i.0, 4 900 %inc = add nuw nsw i16 %i.0, 1 901 br i1 %exitcond, label %exit, label %do.body 902 903exit: 904 %bc2 = getelementptr inbounds i8, ptr %arrayidx, i32 1 905 store i8 10, ptr %arrayidx, align 1 906 store i8 11, ptr %bc2, align 1 907 ret i16 0 908} 909 910define i16 @partial_override_multi(i1 %c, i32 %i) { 911; CHECK-LABEL: @partial_override_multi( 912; CHECK-NEXT: entry: 913; CHECK-NEXT: br label [[DO_BODY:%.*]] 914; CHECK: do.body: 915; CHECK-NEXT: [[I_0:%.*]] = phi i16 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[DO_BODY]] ] 916; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds [10 x i16], ptr @x, i16 0, i16 [[I_0]] 917; CHECK-NEXT: store i16 10, ptr [[ARRAYIDX2]], align 1 918; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i16 [[I_0]], 4 919; CHECK-NEXT: [[INC]] = add nuw nsw i16 [[I_0]], 1 920; CHECK-NEXT: br i1 [[EXITCOND]], label [[EXIT:%.*]], label [[DO_BODY]] 921; CHECK: exit: 922; CHECK-NEXT: [[BC2:%.*]] = getelementptr inbounds i8, ptr [[ARRAYIDX2]], i32 1 923; CHECK-NEXT: store i8 11, ptr [[BC2]], align 1 924; CHECK-NEXT: ret i16 0 925; 926entry: 927 br label %do.body 928 929do.body: 930 %i.0 = phi i16 [ 0, %entry ], [ %inc, %do.body ] 931 %arrayidx2 = getelementptr inbounds [10 x i16], ptr @x, i16 0, i16 %i.0 932 store i16 2, ptr %arrayidx2, align 1 933 store i8 10, ptr %arrayidx2, align 1 934 %exitcond = icmp eq i16 %i.0, 4 935 %inc = add nuw nsw i16 %i.0, 1 936 br i1 %exitcond, label %exit, label %do.body 937 938exit: 939 %bc2 = getelementptr inbounds i8, ptr %arrayidx2, i32 1 940 store i8 11, ptr %bc2, align 1 941 ret i16 0 942} 943 944define void @InitializeMasks(ptr %p) { 945; CHECK-LABEL: @InitializeMasks( 946; CHECK-NEXT: entry: 947; CHECK-NEXT: br label [[FOR_BODY98:%.*]] 948; CHECK: for.body98: 949; CHECK-NEXT: [[INDVARS_IV377:%.*]] = phi i64 [ 8, [[ENTRY:%.*]] ], [ [[INC2:%.*]], [[FOR_INC140:%.*]] ], [ [[INC1:%.*]], [[FOR_INC140_THREAD:%.*]] ] 950; CHECK-NEXT: [[ARRAYIDX106:%.*]] = getelementptr inbounds i64, ptr [[P:%.*]], i64 [[INDVARS_IV377]] 951; CHECK-NEXT: store i64 1, ptr [[ARRAYIDX106]], align 8 952; CHECK-NEXT: [[CMP107:%.*]] = icmp ugt i64 [[INDVARS_IV377]], 15 953; CHECK-NEXT: br i1 [[CMP107]], label [[IF_END:%.*]], label [[IF_END_THREAD:%.*]] 954; CHECK: if.end.thread: 955; CHECK-NEXT: br label [[FOR_INC140_THREAD]] 956; CHECK: if.end: 957; CHECK-NEXT: store i64 2, ptr [[ARRAYIDX106]], align 8 958; CHECK-NEXT: [[CMP127:%.*]] = icmp ult i64 [[INDVARS_IV377]], 48 959; CHECK-NEXT: br i1 [[CMP127]], label [[FOR_INC140_THREAD]], label [[FOR_INC140]] 960; CHECK: for.inc140.thread: 961; CHECK-NEXT: [[INC1]] = add i64 [[INDVARS_IV377]], 1 962; CHECK-NEXT: br label [[FOR_BODY98]] 963; CHECK: for.inc140: 964; CHECK-NEXT: [[INC2]] = add i64 [[INDVARS_IV377]], 1 965; CHECK-NEXT: [[EXITCOND384_NOT:%.*]] = icmp eq i64 [[INDVARS_IV377]], 56 966; CHECK-NEXT: br i1 [[EXITCOND384_NOT]], label [[FOR_INC177:%.*]], label [[FOR_BODY98]] 967; CHECK: for.inc177: 968; CHECK-NEXT: ret void 969; 970entry: 971 br label %for.body98 972 973for.body98: ; preds = %for.inc140, %for.inc140.thread, %entry 974 %indvars.iv377 = phi i64 [ 8, %entry ], [ %inc2, %for.inc140 ], [ %inc1, %for.inc140.thread ] 975 %arrayidx106 = getelementptr inbounds i64, ptr %p, i64 %indvars.iv377 976 store i64 1, ptr %arrayidx106, align 8 977 %cmp107 = icmp ugt i64 %indvars.iv377, 15 978 br i1 %cmp107, label %if.end, label %if.end.thread 979 980if.end.thread: ; preds = %for.body98 981 br label %for.inc140.thread 982 983if.end: ; preds = %for.body98 984 store i64 2, ptr %arrayidx106, align 8 985 %cmp127 = icmp ult i64 %indvars.iv377, 48 986 br i1 %cmp127, label %for.inc140.thread, label %for.inc140 987 988for.inc140.thread: ; preds = %if.end, %if.end.thread 989 %inc1 = add i64 %indvars.iv377, 1 990 br label %for.body98 991 992for.inc140: ; preds = %if.end 993 %inc2 = add i64 %indvars.iv377, 1 994 %exitcond384.not = icmp eq i64 %indvars.iv377, 56 995 br i1 %exitcond384.not, label %for.inc177, label %for.body98 996 997for.inc177: ; preds = %for.inc140 998 ret void 999} 1000