1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes=loop-unroll -unroll-peel-count=2 -S %s | FileCheck --check-prefix=PEEL2 %s 3; RUN: opt -passes=loop-unroll -unroll-peel-count=8 -S %s | FileCheck --check-prefix=PEEL8 %s 4 5; Test case for PR45939. Make sure unroll count is adjusted when loop is peeled and unrolled. 6 7@a = global [8 x i32] zeroinitializer, align 16 8 9define void @test1() { 10; PEEL2-LABEL: @test1( 11; PEEL2-NEXT: entry: 12; PEEL2-NEXT: br label [[FOR_BODY_PEEL_BEGIN:%.*]] 13; PEEL2: for.body.peel.begin: 14; PEEL2-NEXT: br label [[FOR_BODY_PEEL:%.*]] 15; PEEL2: for.body.peel: 16; PEEL2-NEXT: [[ARRAYIDX_PEEL:%.*]] = getelementptr inbounds [8 x i32], ptr @a, i64 0, i64 0 17; PEEL2-NEXT: [[TMP0:%.*]] = trunc i64 0 to i32 18; PEEL2-NEXT: store i32 [[TMP0]], ptr [[ARRAYIDX_PEEL]], align 4 19; PEEL2-NEXT: [[INDVARS_IV_NEXT_PEEL:%.*]] = add nuw nsw i64 0, 1 20; PEEL2-NEXT: [[EXITCOND_PEEL:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT_PEEL]], 8 21; PEEL2-NEXT: br i1 [[EXITCOND_PEEL]], label [[FOR_BODY_PEEL_NEXT:%.*]], label [[FOR_EXIT:%.*]] 22; PEEL2: for.body.peel.next: 23; PEEL2-NEXT: br label [[FOR_BODY_PEEL2:%.*]] 24; PEEL2: for.body.peel2: 25; PEEL2-NEXT: [[ARRAYIDX_PEEL3:%.*]] = getelementptr inbounds [8 x i32], ptr @a, i64 0, i64 [[INDVARS_IV_NEXT_PEEL]] 26; PEEL2-NEXT: [[TMP1:%.*]] = trunc i64 [[INDVARS_IV_NEXT_PEEL]] to i32 27; PEEL2-NEXT: store i32 [[TMP1]], ptr [[ARRAYIDX_PEEL3]], align 4 28; PEEL2-NEXT: [[INDVARS_IV_NEXT_PEEL4:%.*]] = add nuw nsw i64 [[INDVARS_IV_NEXT_PEEL]], 1 29; PEEL2-NEXT: [[EXITCOND_PEEL5:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT_PEEL4]], 8 30; PEEL2-NEXT: br i1 [[EXITCOND_PEEL5]], label [[FOR_BODY_PEEL_NEXT1:%.*]], label [[FOR_EXIT]] 31; PEEL2: for.body.peel.next1: 32; PEEL2-NEXT: br label [[FOR_BODY_PEEL_NEXT6:%.*]] 33; PEEL2: for.body.peel.next6: 34; PEEL2-NEXT: br label [[ENTRY_PEEL_NEWPH:%.*]] 35; PEEL2: entry.peel.newph: 36; PEEL2-NEXT: br label [[FOR_BODY:%.*]] 37; PEEL2: for.body: 38; PEEL2-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT_PEEL4]], [[ENTRY_PEEL_NEWPH]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ] 39; PEEL2-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i32], ptr @a, i64 0, i64 [[INDVARS_IV]] 40; PEEL2-NEXT: [[TMP2:%.*]] = trunc i64 [[INDVARS_IV]] to i32 41; PEEL2-NEXT: store i32 [[TMP2]], ptr [[ARRAYIDX]], align 4 42; PEEL2-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 43; PEEL2-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], 8 44; PEEL2-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_EXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP0:![0-9]+]] 45; PEEL2: for.exit.loopexit: 46; PEEL2-NEXT: br label [[FOR_EXIT]] 47; PEEL2: for.exit: 48; PEEL2-NEXT: ret void 49; 50; PEEL8-LABEL: @test1( 51; PEEL8-NEXT: entry: 52; PEEL8-NEXT: br label [[FOR_BODY_PEEL_BEGIN:%.*]] 53; PEEL8: for.body.peel.begin: 54; PEEL8-NEXT: br label [[FOR_BODY_PEEL:%.*]] 55; PEEL8: for.body.peel: 56; PEEL8-NEXT: [[ARRAYIDX_PEEL:%.*]] = getelementptr inbounds [8 x i32], ptr @a, i64 0, i64 0 57; PEEL8-NEXT: [[TMP0:%.*]] = trunc i64 0 to i32 58; PEEL8-NEXT: store i32 [[TMP0]], ptr [[ARRAYIDX_PEEL]], align 4 59; PEEL8-NEXT: [[INDVARS_IV_NEXT_PEEL:%.*]] = add nuw nsw i64 0, 1 60; PEEL8-NEXT: [[EXITCOND_PEEL:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT_PEEL]], 8 61; PEEL8-NEXT: br i1 [[EXITCOND_PEEL]], label [[FOR_BODY_PEEL_NEXT:%.*]], label [[FOR_EXIT:%.*]] 62; PEEL8: for.body.peel.next: 63; PEEL8-NEXT: br label [[FOR_BODY_PEEL2:%.*]] 64; PEEL8: for.body.peel2: 65; PEEL8-NEXT: [[ARRAYIDX_PEEL3:%.*]] = getelementptr inbounds [8 x i32], ptr @a, i64 0, i64 [[INDVARS_IV_NEXT_PEEL]] 66; PEEL8-NEXT: [[TMP1:%.*]] = trunc i64 [[INDVARS_IV_NEXT_PEEL]] to i32 67; PEEL8-NEXT: store i32 [[TMP1]], ptr [[ARRAYIDX_PEEL3]], align 4 68; PEEL8-NEXT: [[INDVARS_IV_NEXT_PEEL4:%.*]] = add nuw nsw i64 [[INDVARS_IV_NEXT_PEEL]], 1 69; PEEL8-NEXT: [[EXITCOND_PEEL5:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT_PEEL4]], 8 70; PEEL8-NEXT: br i1 [[EXITCOND_PEEL5]], label [[FOR_BODY_PEEL_NEXT1:%.*]], label [[FOR_EXIT]] 71; PEEL8: for.body.peel.next1: 72; PEEL8-NEXT: br label [[FOR_BODY_PEEL7:%.*]] 73; PEEL8: for.body.peel7: 74; PEEL8-NEXT: [[ARRAYIDX_PEEL8:%.*]] = getelementptr inbounds [8 x i32], ptr @a, i64 0, i64 [[INDVARS_IV_NEXT_PEEL4]] 75; PEEL8-NEXT: [[TMP2:%.*]] = trunc i64 [[INDVARS_IV_NEXT_PEEL4]] to i32 76; PEEL8-NEXT: store i32 [[TMP2]], ptr [[ARRAYIDX_PEEL8]], align 4 77; PEEL8-NEXT: [[INDVARS_IV_NEXT_PEEL9:%.*]] = add nuw nsw i64 [[INDVARS_IV_NEXT_PEEL4]], 1 78; PEEL8-NEXT: [[EXITCOND_PEEL10:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT_PEEL9]], 8 79; PEEL8-NEXT: br i1 [[EXITCOND_PEEL10]], label [[FOR_BODY_PEEL_NEXT6:%.*]], label [[FOR_EXIT]] 80; PEEL8: for.body.peel.next6: 81; PEEL8-NEXT: br label [[FOR_BODY_PEEL12:%.*]] 82; PEEL8: for.body.peel12: 83; PEEL8-NEXT: [[ARRAYIDX_PEEL13:%.*]] = getelementptr inbounds [8 x i32], ptr @a, i64 0, i64 [[INDVARS_IV_NEXT_PEEL9]] 84; PEEL8-NEXT: [[TMP3:%.*]] = trunc i64 [[INDVARS_IV_NEXT_PEEL9]] to i32 85; PEEL8-NEXT: store i32 [[TMP3]], ptr [[ARRAYIDX_PEEL13]], align 4 86; PEEL8-NEXT: [[INDVARS_IV_NEXT_PEEL14:%.*]] = add nuw nsw i64 [[INDVARS_IV_NEXT_PEEL9]], 1 87; PEEL8-NEXT: [[EXITCOND_PEEL15:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT_PEEL14]], 8 88; PEEL8-NEXT: br i1 [[EXITCOND_PEEL15]], label [[FOR_BODY_PEEL_NEXT11:%.*]], label [[FOR_EXIT]] 89; PEEL8: for.body.peel.next11: 90; PEEL8-NEXT: br label [[FOR_BODY_PEEL17:%.*]] 91; PEEL8: for.body.peel17: 92; PEEL8-NEXT: [[ARRAYIDX_PEEL18:%.*]] = getelementptr inbounds [8 x i32], ptr @a, i64 0, i64 [[INDVARS_IV_NEXT_PEEL14]] 93; PEEL8-NEXT: [[TMP4:%.*]] = trunc i64 [[INDVARS_IV_NEXT_PEEL14]] to i32 94; PEEL8-NEXT: store i32 [[TMP4]], ptr [[ARRAYIDX_PEEL18]], align 4 95; PEEL8-NEXT: [[INDVARS_IV_NEXT_PEEL19:%.*]] = add nuw nsw i64 [[INDVARS_IV_NEXT_PEEL14]], 1 96; PEEL8-NEXT: [[EXITCOND_PEEL20:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT_PEEL19]], 8 97; PEEL8-NEXT: br i1 [[EXITCOND_PEEL20]], label [[FOR_BODY_PEEL_NEXT16:%.*]], label [[FOR_EXIT]] 98; PEEL8: for.body.peel.next16: 99; PEEL8-NEXT: br label [[FOR_BODY_PEEL22:%.*]] 100; PEEL8: for.body.peel22: 101; PEEL8-NEXT: [[ARRAYIDX_PEEL23:%.*]] = getelementptr inbounds [8 x i32], ptr @a, i64 0, i64 [[INDVARS_IV_NEXT_PEEL19]] 102; PEEL8-NEXT: [[TMP5:%.*]] = trunc i64 [[INDVARS_IV_NEXT_PEEL19]] to i32 103; PEEL8-NEXT: store i32 [[TMP5]], ptr [[ARRAYIDX_PEEL23]], align 4 104; PEEL8-NEXT: [[INDVARS_IV_NEXT_PEEL24:%.*]] = add nuw nsw i64 [[INDVARS_IV_NEXT_PEEL19]], 1 105; PEEL8-NEXT: [[EXITCOND_PEEL25:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT_PEEL24]], 8 106; PEEL8-NEXT: br i1 [[EXITCOND_PEEL25]], label [[FOR_BODY_PEEL_NEXT21:%.*]], label [[FOR_EXIT]] 107; PEEL8: for.body.peel.next21: 108; PEEL8-NEXT: br label [[FOR_BODY_PEEL27:%.*]] 109; PEEL8: for.body.peel27: 110; PEEL8-NEXT: [[ARRAYIDX_PEEL28:%.*]] = getelementptr inbounds [8 x i32], ptr @a, i64 0, i64 [[INDVARS_IV_NEXT_PEEL24]] 111; PEEL8-NEXT: [[TMP6:%.*]] = trunc i64 [[INDVARS_IV_NEXT_PEEL24]] to i32 112; PEEL8-NEXT: store i32 [[TMP6]], ptr [[ARRAYIDX_PEEL28]], align 4 113; PEEL8-NEXT: [[INDVARS_IV_NEXT_PEEL29:%.*]] = add nuw nsw i64 [[INDVARS_IV_NEXT_PEEL24]], 1 114; PEEL8-NEXT: [[EXITCOND_PEEL30:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT_PEEL29]], 8 115; PEEL8-NEXT: br i1 [[EXITCOND_PEEL30]], label [[FOR_BODY_PEEL_NEXT26:%.*]], label [[FOR_EXIT]] 116; PEEL8: for.body.peel.next26: 117; PEEL8-NEXT: br label [[FOR_BODY_PEEL32:%.*]] 118; PEEL8: for.body.peel32: 119; PEEL8-NEXT: [[ARRAYIDX_PEEL33:%.*]] = getelementptr inbounds [8 x i32], ptr @a, i64 0, i64 [[INDVARS_IV_NEXT_PEEL29]] 120; PEEL8-NEXT: [[TMP7:%.*]] = trunc i64 [[INDVARS_IV_NEXT_PEEL29]] to i32 121; PEEL8-NEXT: store i32 [[TMP7]], ptr [[ARRAYIDX_PEEL33]], align 4 122; PEEL8-NEXT: [[INDVARS_IV_NEXT_PEEL34:%.*]] = add nuw nsw i64 [[INDVARS_IV_NEXT_PEEL29]], 1 123; PEEL8-NEXT: [[EXITCOND_PEEL35:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT_PEEL34]], 8 124; PEEL8-NEXT: br i1 [[EXITCOND_PEEL35]], label [[FOR_BODY_PEEL_NEXT31:%.*]], label [[FOR_EXIT]] 125; PEEL8: for.body.peel.next31: 126; PEEL8-NEXT: br label [[FOR_BODY_PEEL_NEXT36:%.*]] 127; PEEL8: for.body.peel.next36: 128; PEEL8-NEXT: br label [[ENTRY_PEEL_NEWPH:%.*]] 129; PEEL8: entry.peel.newph: 130; PEEL8-NEXT: br label [[FOR_BODY:%.*]] 131; PEEL8: for.body: 132; PEEL8-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT_PEEL34]], [[ENTRY_PEEL_NEWPH]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ] 133; PEEL8-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i32], ptr @a, i64 0, i64 [[INDVARS_IV]] 134; PEEL8-NEXT: [[TMP8:%.*]] = trunc i64 [[INDVARS_IV]] to i32 135; PEEL8-NEXT: store i32 [[TMP8]], ptr [[ARRAYIDX]], align 4 136; PEEL8-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 137; PEEL8-NEXT: br i1 true, label [[FOR_BODY]], label [[FOR_EXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP0:![0-9]+]] 138; PEEL8: for.exit.loopexit: 139; PEEL8-NEXT: br label [[FOR_EXIT]] 140; PEEL8: for.exit: 141; PEEL8-NEXT: ret void 142; 143entry: 144 br label %for.body 145 146for.body: ; preds = %entry, %for.body 147 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 148 %arrayidx = getelementptr inbounds [8 x i32], ptr @a, i64 0, i64 %indvars.iv 149 %0 = trunc i64 %indvars.iv to i32 150 store i32 %0, ptr %arrayidx, align 4 151 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 152 %exitcond = icmp ne i64 %indvars.iv.next, 8 153 br i1 %exitcond, label %for.body, label %for.exit 154 155for.exit: ; preds = %for.body 156 ret void 157} 158