1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -S -passes=loop-unroll -unroll-force-peel-count=1 | FileCheck %s 3; RUN: opt < %s -S -passes='loop-unroll<peeling;no-runtime>' -unroll-force-peel-count=1 | FileCheck %s 4 5target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" 6target triple = "x86_64-unknown-linux-gnu" 7 8; Loop peeling must result in valid scope declartions 9 10define internal fastcc void @test01(ptr %p0, ptr %p1, ptr %p2) unnamed_addr align 2 { 11; CHECK-LABEL: @test01( 12; CHECK-NEXT: for.body47.lr.ph: 13; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata !0) 14; CHECK-NEXT: br label [[FOR_BODY47_PEEL_BEGIN:%.*]] 15; CHECK: for.body47.peel.begin: 16; CHECK-NEXT: br label [[FOR_BODY47_PEEL:%.*]] 17; CHECK: for.body47.peel: 18; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata !3) 19; CHECK-NEXT: store i8 42, ptr [[P0:%.*]], align 1, !alias.scope !3 20; CHECK-NEXT: store i8 43, ptr [[P1:%.*]], align 1, !alias.scope !0 21; CHECK-NEXT: store i8 44, ptr [[P2:%.*]], align 1, !alias.scope !5 22; CHECK-NEXT: store i8 42, ptr [[P0]], align 1, !noalias !3 23; CHECK-NEXT: store i8 43, ptr [[P1]], align 1, !noalias !0 24; CHECK-NEXT: store i8 44, ptr [[P2]], align 1, !noalias !5 25; CHECK-NEXT: [[CMP52_PEEL:%.*]] = icmp eq i32 0, 0 26; CHECK-NEXT: br i1 [[CMP52_PEEL]], label [[COND_TRUE_PEEL:%.*]], label [[COND_END_PEEL:%.*]] 27; CHECK: cond.true.peel: 28; CHECK-NEXT: store i8 52, ptr [[P0]], align 1, !alias.scope !3 29; CHECK-NEXT: store i8 53, ptr [[P1]], align 1, !alias.scope !0 30; CHECK-NEXT: store i8 54, ptr [[P2]], align 1, !alias.scope !5 31; CHECK-NEXT: store i8 52, ptr [[P0]], align 1, !noalias !3 32; CHECK-NEXT: store i8 53, ptr [[P1]], align 1, !noalias !0 33; CHECK-NEXT: store i8 54, ptr [[P2]], align 1, !noalias !5 34; CHECK-NEXT: br label [[COND_END_PEEL]] 35; CHECK: cond.end.peel: 36; CHECK-NEXT: store i8 62, ptr [[P0]], align 1, !alias.scope !3 37; CHECK-NEXT: store i8 63, ptr [[P1]], align 1, !alias.scope !0 38; CHECK-NEXT: store i8 64, ptr [[P2]], align 1, !alias.scope !5 39; CHECK-NEXT: store i8 62, ptr [[P0]], align 1, !noalias !3 40; CHECK-NEXT: store i8 63, ptr [[P1]], align 1, !noalias !0 41; CHECK-NEXT: store i8 64, ptr [[P2]], align 1, !noalias !5 42; CHECK-NEXT: [[INC_PEEL:%.*]] = add nuw i32 0, 1 43; CHECK-NEXT: [[EXITCOND_NOT_PEEL:%.*]] = icmp eq i32 [[INC_PEEL]], undef 44; CHECK-NEXT: br i1 [[EXITCOND_NOT_PEEL]], label [[FOR_COND_CLEANUP46:%.*]], label [[FOR_BODY47_PEEL_NEXT:%.*]] 45; CHECK: for.body47.peel.next: 46; CHECK-NEXT: br label [[FOR_BODY47_PEEL_NEXT1:%.*]] 47; CHECK: for.body47.peel.next1: 48; CHECK-NEXT: br label [[FOR_BODY47_LR_PH_PEEL_NEWPH:%.*]] 49; CHECK: for.body47.lr.ph.peel.newph: 50; CHECK-NEXT: br label [[FOR_BODY47:%.*]] 51; CHECK: for.cond.cleanup46.loopexit: 52; CHECK-NEXT: br label [[FOR_COND_CLEANUP46]] 53; CHECK: for.cond.cleanup46: 54; CHECK-NEXT: ret void 55; CHECK: for.body47: 56; CHECK-NEXT: [[J_02:%.*]] = phi i32 [ [[INC_PEEL]], [[FOR_BODY47_LR_PH_PEEL_NEWPH]] ], [ [[INC:%.*]], [[COND_END:%.*]] ] 57; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata !6) 58; CHECK-NEXT: store i8 42, ptr [[P0]], align 1, !alias.scope !6 59; CHECK-NEXT: store i8 43, ptr [[P1]], align 1, !alias.scope !0 60; CHECK-NEXT: store i8 44, ptr [[P2]], align 1, !alias.scope !8 61; CHECK-NEXT: store i8 42, ptr [[P0]], align 1, !noalias !6 62; CHECK-NEXT: store i8 43, ptr [[P1]], align 1, !noalias !0 63; CHECK-NEXT: store i8 44, ptr [[P2]], align 1, !noalias !8 64; CHECK-NEXT: br i1 false, label [[COND_TRUE:%.*]], label [[COND_END]] 65; CHECK: cond.true: 66; CHECK-NEXT: store i8 52, ptr [[P0]], align 1, !alias.scope !6 67; CHECK-NEXT: store i8 53, ptr [[P1]], align 1, !alias.scope !0 68; CHECK-NEXT: store i8 54, ptr [[P2]], align 1, !alias.scope !8 69; CHECK-NEXT: store i8 52, ptr [[P0]], align 1, !noalias !6 70; CHECK-NEXT: store i8 53, ptr [[P1]], align 1, !noalias !0 71; CHECK-NEXT: store i8 54, ptr [[P2]], align 1, !noalias !8 72; CHECK-NEXT: br label [[COND_END]] 73; CHECK: cond.end: 74; CHECK-NEXT: store i8 62, ptr [[P0]], align 1, !alias.scope !6 75; CHECK-NEXT: store i8 63, ptr [[P1]], align 1, !alias.scope !0 76; CHECK-NEXT: store i8 64, ptr [[P2]], align 1, !alias.scope !8 77; CHECK-NEXT: store i8 62, ptr [[P0]], align 1, !noalias !6 78; CHECK-NEXT: store i8 63, ptr [[P1]], align 1, !noalias !0 79; CHECK-NEXT: store i8 64, ptr [[P2]], align 1, !noalias !8 80; CHECK-NEXT: [[INC]] = add nuw i32 [[J_02]], 1 81; CHECK-NEXT: br i1 undef, label [[FOR_COND_CLEANUP46_LOOPEXIT:%.*]], label [[FOR_BODY47]], [[LOOP9:!llvm.loop !.*]] 82; 83for.body47.lr.ph: 84 call void @llvm.experimental.noalias.scope.decl(metadata !5) 85 br label %for.body47 86 87for.cond.cleanup46: ; preds = %cond.end 88 ret void 89 90for.body47: ; preds = %cond.end, %for.body47.lr.ph 91 %j.02 = phi i32 [ 0, %for.body47.lr.ph ], [ %inc, %cond.end ] 92 call void @llvm.experimental.noalias.scope.decl(metadata !0) 93 store i8 42, ptr %p0, !alias.scope !0 94 store i8 43, ptr %p1, !alias.scope !5 95 store i8 44, ptr %p2, !alias.scope !7 96 store i8 42, ptr %p0, !noalias !0 97 store i8 43, ptr %p1, !noalias !5 98 store i8 44, ptr %p2, !noalias !7 99 %cmp52 = icmp eq i32 %j.02, 0 100 br i1 %cmp52, label %cond.true, label %cond.end 101 102cond.true: ; preds = %for.body47 103 store i8 52, ptr %p0, !alias.scope !0 104 store i8 53, ptr %p1, !alias.scope !5 105 store i8 54, ptr %p2, !alias.scope !7 106 store i8 52, ptr %p0, !noalias !0 107 store i8 53, ptr %p1, !noalias !5 108 store i8 54, ptr %p2, !noalias !7 109 br label %cond.end 110 111cond.end: ; preds = %cond.true, %for.body47 112 store i8 62, ptr %p0, !alias.scope !0 113 store i8 63, ptr %p1, !alias.scope !5 114 store i8 64, ptr %p2, !alias.scope !7 115 store i8 62, ptr %p0, !noalias !0 116 store i8 63, ptr %p1, !noalias !5 117 store i8 64, ptr %p2, !noalias !7 118 %inc = add nuw i32 %j.02, 1 119 %exitcond.not = icmp eq i32 %inc, undef 120 br i1 %exitcond.not, label %for.cond.cleanup46, label %for.body47, !llvm.loop !3 121} 122 123; Function Attrs: inaccessiblememonly nofree nosync nounwind willreturn 124declare void @llvm.experimental.noalias.scope.decl(metadata) #0 125 126attributes #0 = { inaccessiblememonly nofree nosync nounwind willreturn } 127 128!0 = !{!1} 129!1 = distinct !{!1, !2, !"foo: %inner.result"} 130!2 = distinct !{!2, !"foo"} 131!3 = distinct !{!3, !4} 132!4 = !{!"llvm.loop.mustprogress"} 133!5 = !{!6} 134!6 = distinct !{!6, !2, !"foo: %outer.result"} 135!7 = !{!1, !6} 136 137; CHECK: !0 = !{!1} 138; CHECK: !1 = distinct !{!1, !2, !"foo: %outer.result"} 139; CHECK: !2 = distinct !{!2, !"foo"} 140; CHECK: !3 = !{!4} 141; CHECK: !4 = distinct !{!4, !2, !"foo: %inner.result:Peel0"} 142; CHECK: !5 = !{!4, !1} 143; CHECK: !6 = !{!7} 144; CHECK: !7 = distinct !{!7, !2, !"foo: %inner.result"} 145; CHECK: !8 = !{!7, !1} 146; CHECK: !9 = distinct !{!9, !10, !11, !12} 147; CHECK: !10 = !{!"llvm.loop.mustprogress"} 148; CHECK: !11 = !{!"llvm.loop.peeled.count", i32 1} 149; CHECK: !12 = !{!"llvm.loop.unroll.disable"} 150