1; RUN: opt -aa-pipeline=basic-aa -passes='print<memoryssa>,verify<memoryssa>' -disable-output < %s 2>&1 | FileCheck %s --check-prefixes=CHECK,NOLIMIT 2; RUN: opt -memssa-check-limit=0 -aa-pipeline=basic-aa -passes='print<memoryssa>,verify<memoryssa>' -disable-output < %s 2>&1 | FileCheck %s --check-prefixes=CHECK,LIMIT 3 4; %ptr can't alias %local, so we should be able to optimize the use of %local to 5; point to the store to %local. 6; CHECK-LABEL: define void @check 7define void @check(ptr %ptr, i1 %bool) { 8entry: 9 %local = alloca i8, align 1 10; CHECK: 1 = MemoryDef(liveOnEntry) 11; CHECK-NEXT: store i8 0, ptr %local, align 1 12 store i8 0, ptr %local, align 1 13 br i1 %bool, label %if.then, label %if.end 14 15if.then: 16 %p2 = getelementptr inbounds i8, ptr %ptr, i32 1 17; CHECK: 2 = MemoryDef(1) 18; CHECK-NEXT: store i8 0, ptr %p2, align 1 19 store i8 0, ptr %p2, align 1 20 br label %if.end 21 22if.end: 23; CHECK: 3 = MemoryPhi({entry,1},{if.then,2}) 24; NOLIMIT: MemoryUse(1) 25; NOLIMIT-NEXT: load i8, ptr %local, align 1 26; LIMIT: MemoryUse(3) 27; LIMIT-NEXT: load i8, ptr %local, align 1 28 load i8, ptr %local, align 1 29 ret void 30} 31 32; CHECK-LABEL: define void @check2 33define void @check2(i1 %val1, i1 %val2, i1 %val3) { 34entry: 35 %local = alloca i8, align 1 36 %local2 = alloca i8, align 1 37 38; CHECK: 1 = MemoryDef(liveOnEntry) 39; CHECK-NEXT: store i8 0, ptr %local 40 store i8 0, ptr %local 41 br i1 %val1, label %if.then, label %phi.3 42 43if.then: 44; CHECK: 2 = MemoryDef(1) 45; CHECK-NEXT: store i8 2, ptr %local2 46 store i8 2, ptr %local2 47 br i1 %val2, label %phi.2, label %phi.3 48 49phi.3: 50; CHECK: 7 = MemoryPhi({entry,1},{if.then,2}) 51; CHECK: 3 = MemoryDef(7) 52; CHECK-NEXT: store i8 3, ptr %local2 53 store i8 3, ptr %local2 54 br i1 %val3, label %phi.2, label %phi.1 55 56phi.2: 57; CHECK: 5 = MemoryPhi({if.then,2},{phi.3,3}) 58; CHECK: 4 = MemoryDef(5) 59; CHECK-NEXT: store i8 4, ptr %local2 60 store i8 4, ptr %local2 61 br label %phi.1 62 63phi.1: 64; Order matters here; phi.2 needs to come before phi.3, because that's the order 65; they're visited in. 66; CHECK: 6 = MemoryPhi({phi.2,4},{phi.3,3}) 67; NOLIMIT: MemoryUse(1) 68; NOLIMIT-NEXT: load i8, ptr %local 69; LIMIT: MemoryUse(6) 70; LIMIT-NEXT: load i8, ptr %local 71 load i8, ptr %local 72 ret void 73} 74 75; CHECK-LABEL: define void @cross_phi 76define void @cross_phi(ptr noalias %p1, ptr noalias %p2, i1 %arg) { 77; CHECK: 1 = MemoryDef(liveOnEntry) 78; CHECK-NEXT: store i8 0, ptr %p1 79 store i8 0, ptr %p1 80; NOLIMIT: MemoryUse(1) 81; NOLIMIT-NEXT: load i8, ptr %p1 82; LIMIT: MemoryUse(1) 83; LIMIT-NEXT: load i8, ptr %p1 84 load i8, ptr %p1 85 br i1 %arg, label %a, label %b 86 87a: 88; CHECK: 2 = MemoryDef(1) 89; CHECK-NEXT: store i8 0, ptr %p2 90 store i8 0, ptr %p2 91 br i1 %arg, label %c, label %d 92 93b: 94; CHECK: 3 = MemoryDef(1) 95; CHECK-NEXT: store i8 1, ptr %p2 96 store i8 1, ptr %p2 97 br i1 %arg, label %c, label %d 98 99c: 100; CHECK: 6 = MemoryPhi({a,2},{b,3}) 101; CHECK: 4 = MemoryDef(6) 102; CHECK-NEXT: store i8 2, ptr %p2 103 store i8 2, ptr %p2 104 br label %e 105 106d: 107; CHECK: 7 = MemoryPhi({a,2},{b,3}) 108; CHECK: 5 = MemoryDef(7) 109; CHECK-NEXT: store i8 3, ptr %p2 110 store i8 3, ptr %p2 111 br label %e 112 113e: 114; 8 = MemoryPhi({c,4},{d,5}) 115; NOLIMIT: MemoryUse(1) 116; NOLIMIT-NEXT: load i8, ptr %p1 117; LIMIT: MemoryUse(8) 118; LIMIT-NEXT: load i8, ptr %p1 119 load i8, ptr %p1 120 ret void 121} 122 123; CHECK-LABEL: define void @looped 124define void @looped(ptr noalias %p1, ptr noalias %p2, i1 %arg) { 125; CHECK: 1 = MemoryDef(liveOnEntry) 126; CHECK-NEXT: store i8 0, ptr %p1 127 store i8 0, ptr %p1 128 br label %loop.1 129 130loop.1: 131; CHECK: 6 = MemoryPhi({%0,1},{loop.3,4}) 132; CHECK: 2 = MemoryDef(6) 133; CHECK-NEXT: store i8 0, ptr %p2 134 store i8 0, ptr %p2 135 br i1 %arg, label %loop.2, label %loop.3 136 137loop.2: 138; CHECK: 5 = MemoryPhi({loop.1,2},{loop.3,4}) 139; CHECK: 3 = MemoryDef(5) 140; CHECK-NEXT: store i8 1, ptr %p2 141 store i8 1, ptr %p2 142 br label %loop.3 143 144loop.3: 145; CHECK: 7 = MemoryPhi({loop.1,2},{loop.2,3}) 146; CHECK: 4 = MemoryDef(7) 147; CHECK-NEXT: store i8 2, ptr %p2 148 store i8 2, ptr %p2 149; NOLIMIT: MemoryUse(1) 150; NOLIMIT-NEXT: load i8, ptr %p1 151; LIMIT: MemoryUse(4) 152; LIMIT-NEXT: load i8, ptr %p1 153 load i8, ptr %p1 154 br i1 %arg, label %loop.2, label %loop.1 155} 156 157; CHECK-LABEL: define void @looped_visitedonlyonce 158define void @looped_visitedonlyonce(ptr noalias %p1, ptr noalias %p2, i1 %arg) { 159 br label %while.cond 160 161while.cond: 162; CHECK: 5 = MemoryPhi({%0,liveOnEntry},{if.end,3}) 163; CHECK-NEXT: br i1 %arg, label %if.then, label %if.end 164 br i1 %arg, label %if.then, label %if.end 165 166if.then: 167; CHECK: 1 = MemoryDef(5) 168; CHECK-NEXT: store i8 0, ptr %p1 169 store i8 0, ptr %p1 170 br i1 %arg, label %if.end, label %if.then2 171 172if.then2: 173; CHECK: 2 = MemoryDef(1) 174; CHECK-NEXT: store i8 1, ptr %p2 175 store i8 1, ptr %p2 176 br label %if.end 177 178if.end: 179; CHECK: 4 = MemoryPhi({while.cond,5},{if.then,1},{if.then2,2}) 180; CHECK: MemoryUse(4) 181; CHECK-NEXT: load i8, ptr %p1 182 load i8, ptr %p1 183; CHECK: 3 = MemoryDef(4) 184; CHECK-NEXT: store i8 2, ptr %p2 185 store i8 2, ptr %p2 186; NOLIMIT: MemoryUse(4) 187; NOLIMIT-NEXT: load i8, ptr %p1 188; LIMIT: MemoryUse(3) 189; LIMIT-NEXT: load i8, ptr %p1 190 load i8, ptr %p1 191 br label %while.cond 192} 193 194; CHECK-LABEL: define i32 @use_not_optimized_due_to_backedge 195define i32 @use_not_optimized_due_to_backedge(ptr nocapture %m_i_strides, ptr nocapture readonly %eval_left_dims) { 196entry: 197; CHECK: 1 = MemoryDef(liveOnEntry) 198; CHECK-NEXT: store i32 1, ptr %m_i_strides, align 4 199 store i32 1, ptr %m_i_strides, align 4 200 br label %for.body 201 202for.cond.cleanup: ; preds = %for.inc 203 ret i32 %m_i_size.1 204 205for.body: ; preds = %entry, %for.inc 206; CHECK: 4 = MemoryPhi({entry,1},{for.inc,3}) 207; CHECK-NEXT: %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.inc ] 208 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.inc ] 209 %m_i_size.022 = phi i32 [ 1, %entry ], [ %m_i_size.1, %for.inc ] 210 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 211 %cmp1 = icmp eq i64 %indvars.iv, 0 212 %arrayidx2 = getelementptr inbounds i32, ptr %m_i_strides, i64 %indvars.iv 213; CHECK: MemoryUse(4) 214; CHECK-NEXT: %0 = load i32, ptr %arrayidx2, align 4 215 %0 = load i32, ptr %arrayidx2, align 4 216 %arrayidx4 = getelementptr inbounds i32, ptr %eval_left_dims, i64 %indvars.iv 217; CHECK: MemoryUse(4) 218; CHECK-NEXT: %1 = load i32, ptr %arrayidx4, align 4 219 %1 = load i32, ptr %arrayidx4, align 4 220 %mul = mul nsw i32 %1, %0 221 br i1 %cmp1, label %if.then, label %for.inc 222 223if.then: ; preds = %for.body 224 %arrayidx7 = getelementptr inbounds i32, ptr %m_i_strides, i64 %indvars.iv.next 225; CHECK: 2 = MemoryDef(4) 226; CHECK-NEXT: store i32 %mul, ptr %arrayidx7, align 4 227 store i32 %mul, ptr %arrayidx7, align 4 228 br label %for.inc 229 230for.inc: ; preds = %for.body, %if.then 231; CHECK: 3 = MemoryPhi({for.body,4},{if.then,2}) 232; CHECK-NEXT: %m_i_size.1 = phi i32 [ %m_i_size.022, %if.then ], [ %mul, %for.body ] 233 %m_i_size.1 = phi i32 [ %m_i_size.022, %if.then ], [ %mul, %for.body ] 234 br i1 %cmp1, label %for.body, label %for.cond.cleanup 235} 236 237 238%ArrayType = type { [2 x i64] } 239%StructOverArrayType = type { %ArrayType } 240%BigStruct = type { i8, i8, i8, i8, i8, i8, i8, %ArrayType, %ArrayType} 241 242; CHECK-LABEL: define void @use_not_optimized_due_to_backedge_unknown 243define void @use_not_optimized_due_to_backedge_unknown(ptr %this) { 244entry: 245 %eval_left_dims = alloca %StructOverArrayType, align 8 246 %eval_right_dims = alloca %StructOverArrayType, align 8 247 %lhs_strides = alloca %ArrayType, align 8 248 %rhs_strides = alloca %ArrayType, align 8 249 br label %for.body.preheader 250 251for.body.preheader: ; preds = %entry 252 %arrayidx.i527 = getelementptr inbounds %BigStruct, ptr %this, i64 0, i32 7, i32 0, i64 0 253; CHECK: 1 = MemoryDef(liveOnEntry) 254; CHECK-NEXT: store i64 1, ptr %arrayidx.i527, align 8 255 store i64 1, ptr %arrayidx.i527, align 8 256 %arrayidx.i528 = getelementptr inbounds %BigStruct, ptr %this, i64 0, i32 8, i32 0, i64 0 257; CHECK: 2 = MemoryDef(1) 258; CHECK-NEXT: store i64 1, ptr %arrayidx.i528, align 8 259 store i64 1, ptr %arrayidx.i528, align 8 260 br label %for.main.body 261 262for.main.body: ; preds = %if.end220.if.then185_crit_edge, %for.body.preheader 263; CHECK: 4 = MemoryPhi({for.body.preheader,2},{if.end220.if.then185_crit_edge,3}) 264; CHECK-NEXT: %nocontract_idx.0656 = phi i64 [ 0, %for.body.preheader ], [ 1, %if.end220.if.then185_crit_edge ] 265 %nocontract_idx.0656 = phi i64 [ 0, %for.body.preheader ], [ 1, %if.end220.if.then185_crit_edge ] 266 %add199 = add nuw nsw i64 %nocontract_idx.0656, 1 267 %cmp200 = icmp eq i64 %nocontract_idx.0656, 0 268 %arrayidx.i559 = getelementptr inbounds %BigStruct, ptr %this, i64 0, i32 7, i32 0, i64 %nocontract_idx.0656 269; CHECK: MemoryUse(4) 270; CHECK-NEXT: %tmp21 = load i64, ptr %arrayidx.i559, align 8 271 %tmp21 = load i64, ptr %arrayidx.i559, align 8 272 %mul206 = mul nsw i64 %tmp21, %tmp21 273 br i1 %cmp200, label %if.end220.if.then185_crit_edge, label %the.end 274 275if.end220.if.then185_crit_edge: ; preds = %for.main.body 276 %arrayidx.i571 = getelementptr inbounds %BigStruct, ptr %this, i64 0, i32 7, i32 0, i64 %add199 277; CHECK: 3 = MemoryDef(4) 278; CHECK-NEXT: store i64 %mul206, ptr %arrayidx.i571, align 8 279 store i64 %mul206, ptr %arrayidx.i571, align 8 280 br label %for.main.body 281 282the.end: ; preds = %for.main.body 283 ret void 284 285} 286 287 288@c = local_unnamed_addr global [2 x i16] zeroinitializer, align 2 289 290define i32 @dont_merge_noalias_simple(ptr noalias %ptr) { 291; CHECK-LABEL: define i32 @dont_merge_noalias_simple 292; CHECK-LABEL: entry: 293; CHECK: ; 1 = MemoryDef(liveOnEntry) 294; CHECK-NEXT: store i16 1, ptr @c, align 2 295 296; CHECK-LABEL: %for.body 297; NOLIMIT: ; MemoryUse(1) 298; LIMIT: ; MemoryUse(4) 299; CHECK-NEXT: %lv = load i16, ptr %arrayidx, align 2 300 301entry: 302 store i16 1, ptr @c, align 2 303 br label %for.body 304 305for.body: ; preds = %for.body, %entry 306 %storemerge2 = phi i32 [ 1, %entry ], [ %dec, %for.body ] 307 %idxprom1 = zext i32 %storemerge2 to i64 308 %arrayidx = getelementptr inbounds [2 x i16], ptr @c, i64 0, i64 %idxprom1 309 %lv = load i16, ptr %arrayidx, align 2 310 %conv = sext i16 %lv to i32 311 store i32 %conv, ptr %ptr, align 4 312 %dec = add nsw i32 %storemerge2, -1 313 %cmp = icmp sgt i32 %storemerge2, 0 314 br i1 %cmp, label %for.body, label %for.end 315 316for.end: ; preds = %for.body 317 store i16 0, ptr @c, align 2 318 ret i32 0 319} 320 321 322define i32 @dont_merge_noalias_complex(ptr noalias %ptr, ptr noalias %another) { 323; CHECK-LABEL: define i32 @dont_merge_noalias_complex 324; CHECK-LABEL: entry: 325; CHECK: ; 1 = MemoryDef(liveOnEntry) 326; CHECK-NEXT: store i16 1, ptr @c, align 2 327 328; CHECK-LABEL: %for.body 329; NOLIMIT: ; MemoryUse(1) 330; LIMIT: ; MemoryUse(7) 331; CHECK-NEXT: %lv = load i16, ptr %arrayidx, align 2 332 333entry: 334 store i16 1, ptr @c, align 2 335 br label %for.body 336 337for.body: ; preds = %for.body, %entry 338 %storemerge2 = phi i32 [ 1, %entry ], [ %dec, %merge.body ] 339 %idxprom1 = zext i32 %storemerge2 to i64 340 %arrayidx = getelementptr inbounds [2 x i16], ptr @c, i64 0, i64 %idxprom1 341 %lv = load i16, ptr %arrayidx, align 2 342 %conv = sext i16 %lv to i32 343 store i32 %conv, ptr %ptr, align 4 344 %dec = add nsw i32 %storemerge2, -1 345 346 %cmpif = icmp sgt i32 %storemerge2, 1 347 br i1 %cmpif, label %if.body, label %else.body 348 349if.body: 350 store i32 %conv, ptr %another, align 4 351 br label %merge.body 352 353else.body: 354 store i32 %conv, ptr %another, align 4 355 br label %merge.body 356 357merge.body: 358 %cmp = icmp sgt i32 %storemerge2, 0 359 br i1 %cmp, label %for.body, label %for.end 360 361for.end: ; preds = %for.body 362 store i16 0, ptr @c, align 2 363 ret i32 0 364} 365 366declare i1 @should_exit(i32) readnone 367declare void @init(ptr) 368 369; Test case for PR47498. 370; %l.1 may read the result of `store i32 10, ptr %p.1` in %storebb, because 371; after %storebb has been executed, %loop.1.header might be executed again. 372; Make sure %l.1's defining access is the MemoryPhi in the block. 373define void @dont_merge_noalias_complex_2(i32 %arg, i32 %arg1) { 374; CHECK-LABEL: define void @dont_merge_noalias_complex_2( 375 376; CHECK-LABEL: entry: 377; CHECK: ; 1 = MemoryDef(liveOnEntry) 378; CHECK-NEXT: call void @init(ptr %tmp) 379 380; CHECK-LABEL: loop.1.header: 381; CHECK-NEXT: ; 4 = MemoryPhi({entry,1},{loop.1.latch,3}) 382; CHECK: ; MemoryUse(4) 383; CHECK-NEXT: %l.1 = load i32, ptr %p.1, align 4 384 385; CHECK-LABEL: loop.1.latch: 386; CHECK-NEXT: ; 3 = MemoryPhi({loop.1.header,4},{storebb,2}) 387 388; CHECK-LABEL: storebb: 389; CHECK-NEXT: %iv.add2 = add nuw nsw i64 %iv, 2 390; CHECK-NEXT: %p.2 = getelementptr inbounds [32 x i32], ptr %tmp, i64 0, i64 %iv.add2 391; CHECK-NEXT: ; MemoryUse(4) 392; CHECK-NEXT: %l.2 = load i32, ptr %p.2, align 4 393; CHECK-NEXT: ; 2 = MemoryDef(4) 394; CHECK-NEXT: store i32 10, ptr %p.1, align 4 395entry: 396 %tmp = alloca [32 x i32], align 16 397 call void @init(ptr %tmp) 398 br label %loop.1.header 399 400loop.1.header: 401 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.1.latch ] 402 %iv.next = add nuw nsw i64 %iv, 1 403 %p.1 = getelementptr inbounds [32 x i32], ptr %tmp, i64 0, i64 %iv.next 404 %l.1 = load i32, ptr %p.1, align 4 405 %tmp244 = icmp ult i64 %iv, 10 406 br i1 %tmp244, label %loop.1.latch, label %storebb 407 408loop.1.latch: 409 %ec = call i1 @should_exit(i32 %l.1) 410 br i1 %ec, label %exit, label %loop.1.header 411 412storebb: 413 %iv.add2 = add nuw nsw i64 %iv, 2 414 %p.2 = getelementptr inbounds [32 x i32], ptr %tmp, i64 0, i64 %iv.add2 415 %l.2 = load i32, ptr %p.2, align 4 416 store i32 10, ptr %p.1, align 4 417 br label %loop.1.latch 418 419exit: 420 ret void 421} 422 423define i32 @phi_with_constant_values(i1 %cmp) { 424; CHECK-LABEL: define i32 @phi_with_constant_values 425; CHECK-LABEL: lhs: 426; CHECK: ; 1 = MemoryDef(liveOnEntry) 427; CHECK-NEXT: store i16 1, ptr @c, align 2 428 429; CHECK-LABEL: rhs: 430; CHECK: ; 2 = MemoryDef(liveOnEntry) 431; CHECK-NEXT: store i16 1, ptr %s2.ptr, align 2 432 433; CHECK-LABEL: merge: 434; CHECK: ; 3 = MemoryPhi({lhs,1},{rhs,2}) 435; CHECK-NEXT: %storemerge2 = phi i32 [ 2, %lhs ], [ 3, %rhs ] 436; LIMIT: ; MemoryUse(3) 437; LIMIT-NEXT: %lv = load i16, ptr %arrayidx, align 2 438; NOLIMIT: ; MemoryUse(liveOnEntry) 439; NOLIMIT-NEXT: %lv = load i16, ptr %arrayidx, align 2 440 441entry: 442 br i1 %cmp, label %lhs, label %rhs 443 444lhs: 445 store i16 1, ptr @c, align 2 446 br label %merge 447 448rhs: 449 %s2.ptr = getelementptr inbounds [2 x i16], ptr @c, i64 0, i64 1 450 store i16 1, ptr %s2.ptr, align 2 451 br label %merge 452 453merge: ; preds = %for.body, %entry 454 %storemerge2 = phi i32 [ 2, %lhs ], [ 3, %rhs ] 455 %idxprom1 = zext i32 %storemerge2 to i64 456 %arrayidx = getelementptr inbounds [2 x i16], ptr @c, i64 0, i64 %idxprom1 457 %lv = load i16, ptr %arrayidx, align 2 458 br label %end 459 460end: ; preds = %for.body 461 ret i32 0 462} 463 464; CHECK-LABEL: define void @use_clobbered_by_def_in_loop() 465define void @use_clobbered_by_def_in_loop() { 466entry: 467 %nodeStack = alloca [12 x i32], align 4 468 call void @llvm.lifetime.start.p0(i64 48, ptr nonnull %nodeStack) 469 br i1 false, label %cleanup, label %while.cond 470 471; CHECK-LABEL: while.cond: 472; CHECK-NEXT: ; [[NO6:.*]] = MemoryPhi({entry,1},{while.cond.backedge,5}) 473 474while.cond: ; preds = %entry, %while.cond.backedge 475 %depth.1 = phi i32 [ %depth.1.be, %while.cond.backedge ], [ 0, %entry ] 476 %cmp = icmp sgt i32 %depth.1, 0 477 br i1 %cmp, label %land.rhs, label %while.end 478 479; CHECK-LABEL: land.rhs: 480; CHECK-NEXT: %sub = add nsw i32 %depth.1, -1 481; CHECK-NEXT: %arrayidx = getelementptr inbounds [12 x i32], ptr %nodeStack, i32 0, i32 %sub 482; CHECK-NEXT: ; MemoryUse([[NO6]]) 483; CHECK-NEXT: %0 = load i32, ptr %arrayidx, align 4 484 485land.rhs: ; preds = %while.cond 486 %sub = add nsw i32 %depth.1, -1 487 %arrayidx = getelementptr inbounds [12 x i32], ptr %nodeStack, i32 0, i32 %sub 488 %0 = load i32, ptr %arrayidx, align 4 489 br i1 true, label %while.body, label %while.end 490 491while.body: ; preds = %land.rhs 492 br i1 true, label %cleanup, label %while.cond.backedge 493 494while.cond.backedge: ; preds = %while.body, %while.end 495 %depth.1.be = phi i32 [ %sub, %while.body ], [ %inc, %while.end ] 496 br label %while.cond 497 498while.end: ; preds = %while.cond, %land.rhs 499 %arrayidx10 = getelementptr inbounds [12 x i32], ptr %nodeStack, i32 0, i32 %depth.1 500 store i32 %depth.1, ptr %arrayidx10, align 4 501 %inc = add nsw i32 %depth.1, 1 502 br i1 true, label %cleanup, label %while.cond.backedge 503 504cleanup: ; preds = %while.body, %while.end, %entry 505 call void @llvm.lifetime.end.p0(i64 48, ptr nonnull %nodeStack) 506 ret void 507} 508 509declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) 510declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) 511 512define void @another_loop_clobber_inc() { 513; CHECK-LABEL: void @another_loop_clobber_inc 514; CHECK-LABEL: loop.header: 515; CHECK-NEXT: ; 4 = MemoryPhi({entry,1},{cond.read,3}) 516 517; CHECK-LABEL: cond.read: 518; CHECK: ; MemoryUse(4) 519; CHECK-NEXT: %use = load i32, ptr %ptr.1, align 4 520; CHECK-NEXT: ; 2 = MemoryDef(4) 521; CHECK-NEXT: %c.2 = call i1 @cond(i32 %use) 522; CHECK-NEXT: %ptr.10 = getelementptr inbounds [12 x i32], ptr %nodeStack, i32 0, i32 %inc 523; CHECK-NEXT: ; 3 = MemoryDef(2) 524; CHECK-NEXT: store i32 10, ptr %ptr.2, align 4 525 526entry: 527 %nodeStack = alloca [12 x i32], align 4 528 %c.1 = call i1 @cond(i32 1) 529 br i1 %c.1, label %cleanup, label %loop.header 530 531loop.header: ; preds = %entry, %while.cond.backedge 532 %depth.1 = phi i32 [ %inc, %cond.read], [ 1, %entry ] 533 %cmp = icmp sgt i32 %depth.1, 0 534 %inc = add nsw i32 %depth.1, 3 535 %inc2 = add nsw i32 %depth.1, 6 536 br i1 %cmp, label %cond.read, label %cleanup 537 538cond.read: ; preds = %while.cond 539 %ptr.1 = getelementptr inbounds [12 x i32], ptr %nodeStack, i32 0, i32 %depth.1 540 %ptr.2 = getelementptr inbounds [12 x i32], ptr %nodeStack, i32 0, i32 %inc2 541 %use = load i32, ptr %ptr.1, align 4 542 %c.2 = call i1 @cond(i32 %use) 543 %ptr.10 = getelementptr inbounds [12 x i32], ptr %nodeStack, i32 0, i32 %inc 544 store i32 10, ptr %ptr.2, align 4 545 br i1 %c.2, label %loop.header, label %cleanup 546 547cleanup: 548 ret void 549} 550 551define void @another_loop_clobber_dec() { 552; CHECK-LABEL: void @another_loop_clobber_dec 553; CHECK-LABEL: loop.header: 554; CHECK-NEXT: ; 4 = MemoryPhi({entry,1},{cond.read,3}) 555 556; CHECK-LABEL: cond.read: 557; CHECK: ; MemoryUse(4) 558; CHECK-NEXT: %use = load i32, ptr %ptr.1, align 4 559; CHECK-NEXT: ; 2 = MemoryDef(4) 560; CHECK-NEXT: %c.2 = call i1 @cond(i32 %use) 561; CHECK-NEXT: %ptr.10 = getelementptr inbounds [12 x i32], ptr %nodeStack, i32 0, i64 %sub 562; CHECK-NEXT: ; 3 = MemoryDef(2) 563; CHECK-NEXT: store i32 10, ptr %ptr.2, align 4 564 565entry: 566 %nodeStack = alloca [12 x i32], align 4 567 %c.1 = call i1 @cond(i32 1) 568 br i1 %c.1, label %cleanup, label %loop.header 569 570loop.header: ; preds = %entry, %while.cond.backedge 571 %depth.1 = phi i64 [ %sub, %cond.read], [ 20, %entry ] 572 %cmp = icmp sgt i64 %depth.1, 6 573 %sub = sub nsw nuw i64 %depth.1, 3 574 %sub2 = sub nsw nuw i64 %depth.1, 6 575 br i1 %cmp, label %cond.read, label %cleanup 576 577cond.read: ; preds = %while.cond 578 %ptr.1 = getelementptr inbounds [12 x i32], ptr %nodeStack, i32 0, i64 %depth.1 579 %ptr.2 = getelementptr inbounds [12 x i32], ptr %nodeStack, i32 0, i64 %sub2 580 %use = load i32, ptr %ptr.1, align 4 581 %c.2 = call i1 @cond(i32 %use) 582 %ptr.10 = getelementptr inbounds [12 x i32], ptr %nodeStack, i32 0, i64 %sub 583 store i32 10, ptr %ptr.2, align 4 584 br i1 %c.2, label %loop.header, label %cleanup 585 586cleanup: 587 ret void 588} 589 590declare i1 @cond(i32) 591