346 lines · plain
1; RUN: opt < %s -passes=loop-unroll -pragma-unroll-threshold=1024 -S | FileCheck -check-prefixes=CHECK,REM %s2; RUN: opt < %s -passes=loop-unroll,loop-unroll -pragma-unroll-threshold=1024 -S | FileCheck -check-prefixes=CHECK,REM %s3; RUN: opt < %s -passes=loop-unroll -unroll-allow-remainder=0 -pragma-unroll-threshold=1024 -S | FileCheck -check-prefixes=CHECK,NOREM %s4;5; Run loop unrolling twice to verify that loop unrolling metadata is properly6; removed and further unrolling is disabled after the pass is run once.7 8target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"9target triple = "x86_64-unknown-linux-gnu"10 11; loop4 contains a small loop which should be completely unrolled by12; the default unrolling heuristics. It serves as a control for the13; unroll(disable) pragma test loop4_with_disable.14;15; CHECK-LABEL: @loop4(16; CHECK-NOT: br i117define void @loop4(ptr nocapture %a) {18entry:19 br label %for.body20 21for.body: ; preds = %for.body, %entry22 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]23 %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv24 %0 = load i32, ptr %arrayidx, align 425 %inc = add nsw i32 %0, 126 store i32 %inc, ptr %arrayidx, align 427 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 128 %exitcond = icmp eq i64 %indvars.iv.next, 429 br i1 %exitcond, label %for.end, label %for.body30 31for.end: ; preds = %for.body32 ret void33}34 35; #pragma clang loop unroll(disable)36;37; CHECK-LABEL: @loop4_with_disable(38; CHECK: store i3239; CHECK-NOT: store i3240; CHECK: br i141define void @loop4_with_disable(ptr nocapture %a) {42entry:43 br label %for.body44 45for.body: ; preds = %for.body, %entry46 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]47 %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv48 %0 = load i32, ptr %arrayidx, align 449 %inc = add nsw i32 %0, 150 store i32 %inc, ptr %arrayidx, align 451 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 152 %exitcond = icmp eq i64 %indvars.iv.next, 453 br i1 %exitcond, label %for.end, label %for.body, !llvm.loop !154 55for.end: ; preds = %for.body56 ret void57}58!1 = !{!1, !2}59!2 = !{!"llvm.loop.unroll.disable"}60 61; loop64 has a high enough count that it should *not* be unrolled by62; the default unrolling heuristic. It serves as the control for the63; unroll(full) pragma test loop64_with_.* tests below.64;65; CHECK-LABEL: @loop64(66; CHECK: store i3267; CHECK-NOT: store i3268; CHECK: br i169define void @loop64(ptr nocapture %a) {70entry:71 br label %for.body72 73for.body: ; preds = %for.body, %entry74 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]75 %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv76 %0 = load i32, ptr %arrayidx, align 477 %inc = add nsw i32 %0, 178 store i32 %inc, ptr %arrayidx, align 479 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 180 %exitcond = icmp eq i64 %indvars.iv.next, 6481 br i1 %exitcond, label %for.end, label %for.body82 83for.end: ; preds = %for.body84 ret void85}86 87; #pragma clang loop unroll(full)88; Loop should be fully unrolled.89;90; CHECK-LABEL: @loop64_with_full(91; CHECK-NOT: br i192define void @loop64_with_full(ptr nocapture %a) {93entry:94 br label %for.body95 96for.body: ; preds = %for.body, %entry97 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]98 %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv99 %0 = load i32, ptr %arrayidx, align 4100 %inc = add nsw i32 %0, 1101 store i32 %inc, ptr %arrayidx, align 4102 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1103 %exitcond = icmp eq i64 %indvars.iv.next, 64104 br i1 %exitcond, label %for.end, label %for.body, !llvm.loop !3105 106for.end: ; preds = %for.body107 ret void108}109!3 = !{!3, !4}110!4 = !{!"llvm.loop.unroll.full"}111 112; #pragma clang loop unroll_count(4)113; Loop should be unrolled 4 times.114;115; CHECK-LABEL: @loop64_with_count4(116; CHECK: store i32117; CHECK: store i32118; CHECK: store i32119; CHECK: store i32120; CHECK-NOT: store i32121; CHECK: br i1122define void @loop64_with_count4(ptr nocapture %a) {123entry:124 br label %for.body125 126for.body: ; preds = %for.body, %entry127 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]128 %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv129 %0 = load i32, ptr %arrayidx, align 4130 %inc = add nsw i32 %0, 1131 store i32 %inc, ptr %arrayidx, align 4132 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1133 %exitcond = icmp eq i64 %indvars.iv.next, 64134 br i1 %exitcond, label %for.end, label %for.body, !llvm.loop !5135 136for.end: ; preds = %for.body137 ret void138}139!5 = !{!5, !6}140!6 = !{!"llvm.loop.unroll.count", i32 4}141 142; #pragma clang loop unroll(full)143; Full unrolling is requested, but loop has a runtime trip count so144; no unrolling should occur.145;146; CHECK-LABEL: @runtime_loop_with_full(147; CHECK: store i32148; CHECK-NOT: store i32149define void @runtime_loop_with_full(ptr nocapture %a, i32 %b) {150entry:151 %cmp3 = icmp sgt i32 %b, 0152 br i1 %cmp3, label %for.body, label %for.end, !llvm.loop !8153 154for.body: ; preds = %entry, %for.body155 %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ]156 %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv157 %0 = load i32, ptr %arrayidx, align 4158 %inc = add nsw i32 %0, 1159 store i32 %inc, ptr %arrayidx, align 4160 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1161 %lftr.wideiv = trunc i64 %indvars.iv.next to i32162 %exitcond = icmp eq i32 %lftr.wideiv, %b163 br i1 %exitcond, label %for.end, label %for.body, !llvm.loop !8164 165for.end: ; preds = %for.body, %entry166 ret void167}168!8 = !{!8, !4}169 170; #pragma clang loop unroll_count(4)171; Loop has a runtime trip count. Runtime unrolling should occur and loop172; should be duplicated (original and 4x unrolled) if remainder is allowed,173; otherwise loop should not be unrolled.174;175; CHECK-LABEL: @runtime_loop_with_count4(176; CHECK: for.body177; CHECK: store178; REM: store179; REM: store180; REM: store181; CHECK-NOT: store182; CHECK: br i1183; REM: for.body.epil:184; REM: store185; NOREM-NOT: for.body.epil:186; NOREM-NOT: store187; CHECK-NOT: store188; REM: br i1189; NOREM-NOT: br i1190define void @runtime_loop_with_count4(ptr nocapture %a, i32 %b) {191entry:192 %cmp3 = icmp sgt i32 %b, 0193 br i1 %cmp3, label %for.body, label %for.end, !llvm.loop !9194 195for.body: ; preds = %entry, %for.body196 %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ]197 %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv198 %0 = load i32, ptr %arrayidx, align 4199 %inc = add nsw i32 %0, 1200 store i32 %inc, ptr %arrayidx, align 4201 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1202 %lftr.wideiv = trunc i64 %indvars.iv.next to i32203 %exitcond = icmp eq i32 %lftr.wideiv, %b204 br i1 %exitcond, label %for.end, label %for.body, !llvm.loop !9205 206for.end: ; preds = %for.body, %entry207 ret void208}209!9 = !{!9, !6}210 211; #pragma clang loop unroll_count(1)212; Loop should not be unrolled213;214; CHECK-LABEL: @unroll_1(215; CHECK: store i32216; CHECK-NOT: store i32217; CHECK: br i1218define void @unroll_1(ptr nocapture %a, i32 %b) {219entry:220 br label %for.body221 222for.body: ; preds = %for.body, %entry223 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]224 %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv225 %0 = load i32, ptr %arrayidx, align 4226 %inc = add nsw i32 %0, 1227 store i32 %inc, ptr %arrayidx, align 4228 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1229 %exitcond = icmp eq i64 %indvars.iv.next, 4230 br i1 %exitcond, label %for.end, label %for.body, !llvm.loop !10231 232for.end: ; preds = %for.body233 ret void234}235!10 = !{!10, !11}236!11 = !{!"llvm.loop.unroll.count", i32 1}237 238; #pragma clang loop unroll(enable)239; Loop should be fully unrolled.240;241; CHECK-LABEL: @loop64_with_enable(242; CHECK-NOT: br i1243define void @loop64_with_enable(ptr nocapture %a) {244entry:245 br label %for.body246 247for.body: ; preds = %for.body, %entry248 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]249 %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv250 %0 = load i32, ptr %arrayidx, align 4251 %inc = add nsw i32 %0, 1252 store i32 %inc, ptr %arrayidx, align 4253 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1254 %exitcond = icmp eq i64 %indvars.iv.next, 64255 br i1 %exitcond, label %for.end, label %for.body, !llvm.loop !12256 257for.end: ; preds = %for.body258 ret void259}260!12 = !{!12, !13}261!13 = !{!"llvm.loop.unroll.enable"}262 263; #pragma clang loop unroll(enable)264; Loop has a runtime trip count and should be runtime unrolled and duplicated265; (original and 8x) if remainder is allowed, otherwise it should not be266; unrolled.267;268; CHECK-LABEL: @runtime_loop_with_enable(269; CHECK: for.body:270; CHECK: store i32271; REM: store i32272; REM: store i32273; REM: store i32274; REM: store i32275; REM: store i32276; REM: store i32277; REM: store i32278; CHECK-NOT: store i32279; CHECK: br i1280; REM: for.body.epil:281; NOREM-NOT: for.body.epil:282; REM: store283; CHECK-NOT: store284; REM: br i1285; NOREM-NOT: br i1286define void @runtime_loop_with_enable(ptr nocapture %a, i32 %b) {287entry:288 %cmp3 = icmp sgt i32 %b, 0289 br i1 %cmp3, label %for.body, label %for.end, !llvm.loop !8290 291for.body: ; preds = %entry, %for.body292 %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ]293 %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv294 %0 = load i32, ptr %arrayidx, align 4295 %inc = add nsw i32 %0, 1296 store i32 %inc, ptr %arrayidx, align 4297 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1298 %lftr.wideiv = trunc i64 %indvars.iv.next to i32299 %exitcond = icmp eq i32 %lftr.wideiv, %b300 br i1 %exitcond, label %for.end, label %for.body, !llvm.loop !14301 302for.end: ; preds = %for.body, %entry303 ret void304}305!14 = !{!14, !13}306 307; #pragma clang loop unroll_count(3)308; Loop has a runtime trip count. Runtime unrolling should occur and loop309; should be duplicated (original and 3x unrolled) if remainder is allowed,310; otherwise it should not be unrolled.311;312; CHECK-LABEL: @runtime_loop_with_count3(313; CHECK: for.body314; CHECK: store315; REM: store316; REM: store317; CHECK-NOT: store318; CHECK: br i1319; REM: for.body.epil:320; REM: store321; NOREM-NOT: for.body.epil:322; NOREM-NOT: store323; CHECK-NOT: store324; REM: br i1325define void @runtime_loop_with_count3(ptr nocapture %a, i32 %b) {326entry:327 %cmp3 = icmp sgt i32 %b, 0328 br i1 %cmp3, label %for.body, label %for.end, !llvm.loop !16329 330for.body: ; preds = %entry, %for.body331 %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ]332 %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv333 %0 = load i32, ptr %arrayidx, align 4334 %inc = add nsw i32 %0, 1335 store i32 %inc, ptr %arrayidx, align 4336 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1337 %lftr.wideiv = trunc i64 %indvars.iv.next to i32338 %exitcond = icmp eq i32 %lftr.wideiv, %b339 br i1 %exitcond, label %for.end, label %for.body, !llvm.loop !15340 341for.end: ; preds = %for.body, %entry342 ret void343}344!15 = !{!15, !16}345!16 = !{!"llvm.loop.unroll.count", i32 3}346