1; RUN: opt -S -passes=loop-fusion -loop-fusion-peel-max-count=3 < %s | FileCheck %s 2 3; Tests that we do not fuse two guarded loops together. 4; These loops do not have the same trip count, and the first loop meets the 5; requirements for peeling. However, the exit block of the first loop makes the 6; loops unsafe to fuse together. 7; The expected output of this test is the function as below. 8 9; CHECK-LABEL: void @unsafe_exitblock(ptr noalias %A, ptr noalias %B) 10; CHECK: for.first.guard 11; CHECK: br i1 %cmp3, label %for.first.preheader, label %for.second.guard 12; CHECK: for.first.preheader: 13; CHECK-NEXT: br label %for.first 14; CHECK: for.first: 15; CHECK: br i1 %cmp, label %for.first, label %for.first.exit 16; CHECK: for.first.exit: 17; CHECK-NEXT: call void @bar() 18; CHECK-NEXT: br label %for.second.guard 19; CHECK: for.second.guard: 20; CHECK: br i1 %cmp21, label %for.second.preheader, label %for.end 21; CHECK: for.second.preheader: 22; CHECK-NEXT: br label %for.second 23; CHECK: for.second: 24; CHECK: br i1 %cmp2, label %for.second, label %for.second.exit 25; CHECK: for.second.exit: 26; CHECK-NEXT: br label %for.end 27; CHECK: for.end: 28; CHECK-NEXT: ret void 29 30define void @unsafe_exitblock(ptr noalias %A, ptr noalias %B) { 31for.first.guard: 32 %cmp3 = icmp slt i64 0, 45 33 br i1 %cmp3, label %for.first.preheader, label %for.second.guard 34 35for.first.preheader: ; preds = %for.first.guard 36 br label %for.first 37 38for.first: ; preds = %for.first.preheader, %for.first 39 %i.04 = phi i64 [ %inc, %for.first ], [ 0, %for.first.preheader ] 40 %arrayidx = getelementptr inbounds i32, ptr %A, i64 %i.04 41 store i32 0, ptr %arrayidx, align 4 42 %inc = add nsw i64 %i.04, 1 43 %cmp = icmp slt i64 %inc, 45 44 br i1 %cmp, label %for.first, label %for.first.exit 45 46for.first.exit: ; preds = %for.first 47 call void @bar() 48 br label %for.second.guard 49 50for.second.guard: ; preds = %for.first.exit, %for.first.guard 51 %cmp21 = icmp slt i64 2,45 52 br i1 %cmp21, label %for.second.preheader, label %for.end 53 54for.second.preheader: ; preds = %for.second.guard 55 br label %for.second 56 57for.second: ; preds = %for.second.preheader, %for.second 58 %j.02 = phi i64 [ %inc6, %for.second ], [ 2, %for.second.preheader ] 59 %arrayidx4 = getelementptr inbounds i32, ptr %B, i64 %j.02 60 store i32 0, ptr %arrayidx4, align 4 61 %inc6 = add nsw i64 %j.02, 1 62 %cmp2 = icmp slt i64 %inc6, 45 63 br i1 %cmp2, label %for.second, label %for.second.exit 64 65for.second.exit: ; preds = %for.second 66 br label %for.end 67 68for.end: ; preds = %for.second.exit, %for.second.guard 69 ret void 70} 71 72declare void @bar() 73