brintos

brintos / llvm-project-archived public Read only

0
0
Text · 23.0 KiB · 6e600d2 Raw
563 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=loop-unroll -unroll-runtime -unroll-allow-partial -S | FileCheck %s3 4declare void @f() convergent5declare void @g()6 7; Although this loop contains a convergent instruction, it should be8; fully unrolled.9define i32 @full_unroll() {10; CHECK-LABEL: @full_unroll(11; CHECK-NEXT:  entry:12; CHECK-NEXT:    [[ANCHOR:%.*]] = call token @llvm.experimental.convergence.anchor()13; CHECK-NEXT:    br label [[L3:%.*]]14; CHECK:       l3:15; CHECK-NEXT:    [[TOK_LOOP:%.*]] = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token [[ANCHOR]]) ]16; CHECK-NEXT:    br label [[A:%.*]]17; CHECK:       a:18; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_LOOP]]) ]19; CHECK-NEXT:    br label [[A_1:%.*]]20; CHECK:       a.1:21; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_LOOP]]) ]22; CHECK-NEXT:    br label [[A_2:%.*]]23; CHECK:       a.2:24; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_LOOP]]) ]25; CHECK-NEXT:    ret i32 026;27entry:28  %anchor = call token @llvm.experimental.convergence.anchor()29  br label %l330 31l3:32  %x.0 = phi i32 [ 0, %entry ], [ %inc, %a ]33  %tok.loop = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %anchor) ]34  %inc = add nsw i32 %x.0, 135  %exitcond = icmp eq i32 %inc, 336  br label %a37 38a:39  call void @f() [ "convergencectrl"(token %tok.loop) ]40  br i1 %exitcond, label %exit, label %l341 42exit:43  ret i32 044}45 46; This loop contains a convergent instruction, but it should be partially47; unrolled.  The unroll count is the largest power of 2 that divides the48; multiple -- 4, in this case.49define i32 @runtime_unroll(i32 %n) {50; CHECK-LABEL: @runtime_unroll(51; CHECK-NEXT:  entry:52; CHECK-NEXT:    [[ANCHOR:%.*]] = call token @llvm.experimental.convergence.anchor()53; CHECK-NEXT:    [[LOOP_CTL:%.*]] = mul nsw i32 [[N:%.*]], 1254; CHECK-NEXT:    br label [[L3:%.*]]55; CHECK:       l3:56; CHECK-NEXT:    [[X_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_3:%.*]], [[A_3:%.*]] ]57; CHECK-NEXT:    [[TOK_LOOP:%.*]] = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token [[ANCHOR]]) ]58; CHECK-NEXT:    br label [[A:%.*]]59; CHECK:       a:60; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_LOOP]]) ]61; CHECK-NEXT:    br label [[A_1:%.*]]62; CHECK:       a.1:63; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_LOOP]]) ]64; CHECK-NEXT:    br label [[A_2:%.*]]65; CHECK:       a.2:66; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_LOOP]]) ]67; CHECK-NEXT:    br label [[A_3]]68; CHECK:       a.3:69; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_LOOP]]) ]70; CHECK-NEXT:    [[INC_3]] = add nsw i32 [[X_0]], 471; CHECK-NEXT:    [[EXITCOND_3:%.*]] = icmp eq i32 [[INC_3]], [[LOOP_CTL]]72; CHECK-NEXT:    br i1 [[EXITCOND_3]], label [[EXIT:%.*]], label [[L3]]73; CHECK:       exit:74; CHECK-NEXT:    ret i32 075;76entry:77  %anchor = call token @llvm.experimental.convergence.anchor()78  %loop_ctl = mul nsw i32 %n, 1279  br label %l380 81l3:82  %x.0 = phi i32 [ 0, %entry ], [ %inc, %a ]83  %tok.loop = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %anchor) ]84  br label %a85 86a:87  call void @f() [ "convergencectrl"(token %tok.loop) ]88  %inc = add nsw i32 %x.0, 189  %exitcond = icmp eq i32 %inc, %loop_ctl90  br i1 %exitcond, label %exit, label %l391 92exit:93  ret i32 094}95 96; This loop contains a convergent instruction, so its partial unroll97; count must divide its trip multiple.  This overrides its unroll98; pragma -- we unroll exactly 8 times, even though 16 is requested.99define i32 @pragma_unroll(i32 %n) {100; CHECK-LABEL: @pragma_unroll(101; CHECK-NEXT:  entry:102; CHECK-NEXT:    [[ANCHOR:%.*]] = call token @llvm.experimental.convergence.anchor()103; CHECK-NEXT:    [[LOOP_CTL:%.*]] = mul nsw i32 [[N:%.*]], 24104; CHECK-NEXT:    br label [[L3:%.*]], !llvm.loop [[LOOP0:![0-9]+]]105; CHECK:       l3:106; CHECK-NEXT:    [[X_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_7:%.*]], [[A_7:%.*]] ]107; CHECK-NEXT:    [[TOK_LOOP:%.*]] = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token [[ANCHOR]]) ]108; CHECK-NEXT:    br label [[A:%.*]]109; CHECK:       a:110; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_LOOP]]) ]111; CHECK-NEXT:    br label [[A_1:%.*]]112; CHECK:       a.1:113; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_LOOP]]) ]114; CHECK-NEXT:    br label [[A_2:%.*]]115; CHECK:       a.2:116; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_LOOP]]) ]117; CHECK-NEXT:    br label [[A_3:%.*]]118; CHECK:       a.3:119; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_LOOP]]) ]120; CHECK-NEXT:    br label [[A_4:%.*]]121; CHECK:       a.4:122; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_LOOP]]) ]123; CHECK-NEXT:    br label [[A_5:%.*]]124; CHECK:       a.5:125; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_LOOP]]) ]126; CHECK-NEXT:    br label [[A_6:%.*]]127; CHECK:       a.6:128; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_LOOP]]) ]129; CHECK-NEXT:    br label [[A_7]]130; CHECK:       a.7:131; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_LOOP]]) ]132; CHECK-NEXT:    [[INC_7]] = add nsw i32 [[X_0]], 8133; CHECK-NEXT:    [[EXITCOND_7:%.*]] = icmp eq i32 [[INC_7]], [[LOOP_CTL]]134; CHECK-NEXT:    br i1 [[EXITCOND_7]], label [[EXIT:%.*]], label [[L3]], !llvm.loop [[LOOP2:![0-9]+]]135; CHECK:       exit:136; CHECK-NEXT:    ret i32 0137;138entry:139  %anchor = call token @llvm.experimental.convergence.anchor()140  %loop_ctl = mul nsw i32 %n, 24141  br label %l3, !llvm.loop !0142 143l3:144  %x.0 = phi i32 [ 0, %entry ], [ %inc, %a ]145  %tok.loop = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %anchor) ]146  br label %a147 148a:149  call void @f() [ "convergencectrl"(token %tok.loop) ]150  %inc = add nsw i32 %x.0, 1151  %exitcond = icmp eq i32 %inc, %loop_ctl152  br i1 %exitcond, label %exit, label %l3, !llvm.loop !0153 154exit:155  ret i32 0156}157 158; This loop contains a convergent instruction. Since the pragma loop unroll159; count 2 divides trip count 4. The loop unroll should respect the pragma.160define void @pragma_unroll_divisible_trip_count() {161; CHECK-LABEL: @pragma_unroll_divisible_trip_count(162; CHECK-NEXT:  entry:163; CHECK-NEXT:    [[ANCHOR:%.*]] = call token @llvm.experimental.convergence.anchor()164; CHECK-NEXT:    br label [[L3:%.*]], !llvm.loop [[LOOP4:![0-9]+]]165; CHECK:       l3:166; CHECK-NEXT:    [[X_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_1:%.*]], [[L3]] ]167; CHECK-NEXT:    [[TOK_LOOP:%.*]] = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token [[ANCHOR]]) ]168; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_LOOP]]) ]169; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_LOOP]]) ]170; CHECK-NEXT:    [[INC_1]] = add nuw nsw i32 [[X_0]], 2171; CHECK-NEXT:    [[EXITCOND_1:%.*]] = icmp eq i32 [[INC_1]], 4172; CHECK-NEXT:    br i1 [[EXITCOND_1]], label [[EXIT:%.*]], label [[L3]], !llvm.loop [[LOOP6:![0-9]+]]173; CHECK:       exit:174; CHECK-NEXT:    ret void175;176entry:177  %anchor = call token @llvm.experimental.convergence.anchor()178  br label %l3, !llvm.loop !1179 180l3:181  %x.0 = phi i32 [ 0, %entry ], [ %inc, %l3 ]182  %tok.loop = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %anchor) ]183  call void @f() [ "convergencectrl"(token %tok.loop) ]184  %inc = add nsw i32 %x.0, 1185  %exitcond = icmp eq i32 %inc, 4186  br i1 %exitcond, label %exit, label %l3, !llvm.loop !1187 188exit:189  ret void190}191 192; This loop contains a convergent instruction. Since the pragma loop unroll193; count 2 divides trip multiple 2. The loop unroll should respect the pragma.194define i32 @pragma_unroll_divisible_trip_multiple(i32 %n) {195; CHECK-LABEL: @pragma_unroll_divisible_trip_multiple(196; CHECK-NEXT:  entry:197; CHECK-NEXT:    [[ANCHOR:%.*]] = call token @llvm.experimental.convergence.anchor()198; CHECK-NEXT:    [[LOOP_CTL:%.*]] = mul nsw i32 [[N:%.*]], 2199; CHECK-NEXT:    br label [[L3:%.*]], !llvm.loop [[LOOP4]]200; CHECK:       l3:201; CHECK-NEXT:    [[X_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_1:%.*]], [[L3]] ]202; CHECK-NEXT:    [[TOK_LOOP:%.*]] = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token [[ANCHOR]]) ]203; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_LOOP]]) ]204; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_LOOP]]) ]205; CHECK-NEXT:    [[INC_1]] = add nsw i32 [[X_0]], 2206; CHECK-NEXT:    [[EXITCOND_1:%.*]] = icmp eq i32 [[INC_1]], [[LOOP_CTL]]207; CHECK-NEXT:    br i1 [[EXITCOND_1]], label [[EXIT:%.*]], label [[L3]], !llvm.loop [[LOOP7:![0-9]+]]208; CHECK:       exit:209; CHECK-NEXT:    ret i32 0210;211entry:212  %anchor = call token @llvm.experimental.convergence.anchor()213  %loop_ctl = mul nsw i32 %n, 2214  br label %l3, !llvm.loop !1215 216l3:217  %x.0 = phi i32 [ 0, %entry ], [ %inc, %l3 ]218  %tok.loop = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %anchor) ]219  call void @f() [ "convergencectrl"(token %tok.loop) ]220  %inc = add nsw i32 %x.0, 1221  %exitcond = icmp eq i32 %inc, %loop_ctl222  br i1 %exitcond, label %exit, label %l3, !llvm.loop !1223 224exit:225  ret i32 0226}227 228; This loop contains a convergent instruction. Since the pragma loop unroll229; count 2 is unknown to divide runtime trip count, the loop is not unrolled230; since remainder is forbidden for unrolling convergent loop.231define i32 @pragma_unroll_indivisible_runtime_trip_count(i32 %n) {232; CHECK-LABEL: @pragma_unroll_indivisible_runtime_trip_count(233; CHECK-NEXT:  entry:234; CHECK-NEXT:    [[ANCHOR:%.*]] = call token @llvm.experimental.convergence.anchor()235; CHECK-NEXT:    br label [[L3:%.*]], !llvm.loop [[LOOP4]]236; CHECK:       l3:237; CHECK-NEXT:    [[X_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[L3]] ]238; CHECK-NEXT:    [[TOK_LOOP:%.*]] = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token [[ANCHOR]]) ]239; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_LOOP]]) ]240; CHECK-NEXT:    [[INC]] = add nsw i32 [[X_0]], 1241; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], [[N:%.*]]242; CHECK-NEXT:    br i1 [[EXITCOND]], label [[EXIT:%.*]], label [[L3]], !llvm.loop [[LOOP4]]243; CHECK:       exit:244; CHECK-NEXT:    ret i32 0245;246entry:247  %anchor = call token @llvm.experimental.convergence.anchor()248  br label %l3, !llvm.loop !1249 250l3:251  %x.0 = phi i32 [ 0, %entry ], [ %inc, %l3 ]252  %tok.loop = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %anchor) ]253  call void @f() [ "convergencectrl"(token %tok.loop) ]254  %inc = add nsw i32 %x.0, 1255  %exitcond = icmp eq i32 %inc, %n256  br i1 %exitcond, label %exit, label %l3, !llvm.loop !1257 258exit:259  ret i32 0260}261 262; This loop contains a convergent instruction. Since the pragma loop unroll263; count 2 does not divide trip count 5, the loop is not unrolled by 2264; since remainder is forbidden for unrolling convergent loop. Instead, the265; loop gets fully unrolled.266define i32 @pragma_unroll_indivisible_trip_count() {267; CHECK-LABEL: @pragma_unroll_indivisible_trip_count(268; CHECK-NEXT:  entry:269; CHECK-NEXT:    [[ANCHOR:%.*]] = call token @llvm.experimental.convergence.anchor()270; CHECK-NEXT:    br label [[L3:%.*]], !llvm.loop [[LOOP4]]271; CHECK:       l3:272; CHECK-NEXT:    [[TOK_LOOP:%.*]] = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token [[ANCHOR]]) ]273; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_LOOP]]) ]274; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_LOOP]]) ]275; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_LOOP]]) ]276; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_LOOP]]) ]277; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_LOOP]]) ]278; CHECK-NEXT:    ret i32 0279;280entry:281  %anchor = call token @llvm.experimental.convergence.anchor()282  br label %l3, !llvm.loop !1283 284l3:285  %x.0 = phi i32 [ 0, %entry ], [ %inc, %l3 ]286  %tok.loop = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %anchor) ]287  call void @f() [ "convergencectrl"(token %tok.loop) ]288  %inc = add nsw i32 %x.0, 1289  %exitcond = icmp eq i32 %inc, 5290  br i1 %exitcond, label %exit, label %l3, !llvm.loop !1291 292exit:293  ret i32 0294}295 296; This loop contains a convergent instruction that is anchored inside the loop297; itself. It is unrolled by 2 with remainder, as requested by the loop metadata.298define i32 @pragma_unroll_with_remainder(i32 %n) {299; CHECK-LABEL: @pragma_unroll_with_remainder(300; CHECK-NEXT:  entry:301; CHECK-NEXT:    [[TMP0:%.*]] = freeze i32 [[N:%.*]]302; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[TMP0]], -1303; CHECK-NEXT:    [[XTRAITER:%.*]] = and i32 [[TMP0]], 1304; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 1305; CHECK-NEXT:    br i1 [[TMP2]], label [[L3_EPIL_PREHEADER:%.*]], label [[ENTRY_NEW:%.*]]306; CHECK:       entry.new:307; CHECK-NEXT:    [[UNROLL_ITER:%.*]] = sub i32 [[TMP0]], [[XTRAITER]]308; CHECK-NEXT:    br label [[L3:%.*]], !llvm.loop [[LOOP4]]309; CHECK:       l3:310; CHECK-NEXT:    [[X_0:%.*]] = phi i32 [ 0, [[ENTRY_NEW]] ], [ [[INC_1:%.*]], [[L3]] ]311; CHECK-NEXT:    [[NITER:%.*]] = phi i32 [ 0, [[ENTRY_NEW]] ], [ [[NITER_NEXT_1:%.*]], [[L3]] ]312; CHECK-NEXT:    [[TOK_LOOP:%.*]] = call token @llvm.experimental.convergence.anchor()313; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_LOOP]]) ]314; CHECK-NEXT:    [[TOK_LOOP_1:%.*]] = call token @llvm.experimental.convergence.anchor()315; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_LOOP_1]]) ]316; CHECK-NEXT:    [[INC_1]] = add nsw i32 [[X_0]], 2317; CHECK-NEXT:    [[NITER_NEXT_1]] = add i32 [[NITER]], 2318; CHECK-NEXT:    [[NITER_NCMP_1:%.*]] = icmp eq i32 [[NITER_NEXT_1]], [[UNROLL_ITER]]319; CHECK-NEXT:    br i1 [[NITER_NCMP_1]], label [[EXIT_UNR_LCSSA:%.*]], label [[L3]], !llvm.loop [[LOOP8:![0-9]+]]320; CHECK:       exit.unr-lcssa:321; CHECK-NEXT:    [[LCMP_MOD:%.*]] = icmp ne i32 [[XTRAITER]], 0322; CHECK-NEXT:    br i1 [[LCMP_MOD]], label [[L3_EPIL_PREHEADER]], label [[EXIT:%.*]]323; CHECK:       l3.epil.preheader:324; CHECK-NEXT:    [[LCMP_MOD1:%.*]] = icmp ne i32 [[XTRAITER]], 0325; CHECK-NEXT:    call void @llvm.assume(i1 [[LCMP_MOD1]])326; CHECK-NEXT:    br label [[L3_EPIL:%.*]]327; CHECK:       l3.epil:328; CHECK-NEXT:    [[TOK_LOOP_EPIL:%.*]] = call token @llvm.experimental.convergence.anchor()329; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_LOOP_EPIL]]) ]330; CHECK-NEXT:    br label [[EXIT]]331; CHECK:       exit:332; CHECK-NEXT:    ret i32 0333;334entry:335  br label %l3, !llvm.loop !1336 337l3:338  %x.0 = phi i32 [ 0, %entry ], [ %inc, %l3 ]339  %tok.loop = call token @llvm.experimental.convergence.anchor()340  call void @f() [ "convergencectrl"(token %tok.loop) ]341  %inc = add nsw i32 %x.0, 1342  %exitcond = icmp eq i32 %inc, %n343  br i1 %exitcond, label %exit, label %l3, !llvm.loop !1344 345exit:346  ret i32 0347}348 349; Don't unroll a loop that is extended by convergence controls.350;351; We could theoretically duplicate the extension part, but this is not352; implemented.353define i32 @extended_loop(i32 %n) {354; CHECK-LABEL: @extended_loop(355; CHECK-NEXT:  entry:356; CHECK-NEXT:    br label [[L3:%.*]], !llvm.loop [[LOOP4]]357; CHECK:       l3:358; CHECK-NEXT:    [[X_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[L3]] ]359; CHECK-NEXT:    [[TOK_LOOP:%.*]] = call token @llvm.experimental.convergence.anchor()360; CHECK-NEXT:    [[INC]] = add nsw i32 [[X_0]], 1361; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], [[N:%.*]]362; CHECK-NEXT:    br i1 [[EXITCOND]], label [[EXIT:%.*]], label [[L3]], !llvm.loop [[LOOP4]]363; CHECK:       exit:364; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_LOOP]]) ]365; CHECK-NEXT:    ret i32 0366;367entry:368  br label %l3, !llvm.loop !1369 370l3:371  %x.0 = phi i32 [ 0, %entry ], [ %inc, %l3 ]372  %tok.loop = call token @llvm.experimental.convergence.anchor()373  %inc = add nsw i32 %x.0, 1374  %exitcond = icmp eq i32 %inc, %n375  br i1 %exitcond, label %exit, label %l3, !llvm.loop !1376 377exit:378  call void @f() [ "convergencectrl"(token %tok.loop) ]379  ret i32 0380}381 382; Inner loop is extended beyond the outer loop. No unrolling possible.383 384define i32 @extended_inner_loop_1(i32 %n, i1 %cond) {385; CHECK-LABEL: @extended_inner_loop_1(386; CHECK-NEXT:  entry:387; CHECK-NEXT:    br label [[L3:%.*]]388; CHECK:       l3:389; CHECK-NEXT:    [[X_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[LATCH:%.*]] ]390; CHECK-NEXT:    [[TOK_LOOP:%.*]] = call token @llvm.experimental.convergence.anchor()391; CHECK-NEXT:    [[INC]] = add nsw i32 [[X_0]], 1392; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 4393; CHECK-NEXT:    br label [[L2:%.*]], !llvm.loop [[LOOP4]]394; CHECK:       l2:395; CHECK-NEXT:    [[TOK_L2:%.*]] = call token @llvm.experimental.convergence.anchor()396; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_L2]]) ]397; CHECK-NEXT:    br i1 [[COND:%.*]], label [[L2]], label [[LATCH]], !llvm.loop [[LOOP4]]398; CHECK:       latch:399; CHECK-NEXT:    br i1 [[EXITCOND]], label [[EXIT:%.*]], label [[L3]]400; CHECK:       exit:401; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_L2]]) ]402; CHECK-NEXT:    ret i32 0403;404entry:405  br label %l3406 407l3:408  %x.0 = phi i32 [ 0, %entry ], [ %inc, %latch ]409  %tok.loop = call token @llvm.experimental.convergence.anchor()410  %inc = add nsw i32 %x.0, 1411  %exitcond = icmp eq i32 %inc, 4412  br label %l2, !llvm.loop !1413 414l2:415  %tok.l2 = call token @llvm.experimental.convergence.anchor()416  call void @f() [ "convergencectrl"(token %tok.l2) ]417  br i1 %cond, label %l2, label %latch, !llvm.loop !1418 419latch:420  br i1 %exitcond, label %exit, label %l3421 422exit:423  call void @f() [ "convergencectrl"(token %tok.l2) ]424  ret i32 0425}426 427; Inner loop is extended inside the outer loop. Outer loop is unrolled.428 429define i32 @extended_inner_loop_2(i32 %n, i1 %cond) {430; CHECK-LABEL: @extended_inner_loop_2(431; CHECK-NEXT:  entry:432; CHECK-NEXT:    br label [[L3:%.*]]433; CHECK:       l3:434; CHECK-NEXT:    br label [[L2:%.*]], !llvm.loop [[LOOP4]]435; CHECK:       l2:436; CHECK-NEXT:    [[TOK_L2:%.*]] = call token @llvm.experimental.convergence.anchor()437; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_L2]]) ]438; CHECK-NEXT:    br i1 [[COND:%.*]], label [[L2]], label [[LATCH:%.*]], !llvm.loop [[LOOP4]]439; CHECK:       latch:440; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_L2]]) ]441; CHECK-NEXT:    br label [[L2_1:%.*]], !llvm.loop [[LOOP4]]442; CHECK:       l2.1:443; CHECK-NEXT:    [[TOK_L2_1:%.*]] = call token @llvm.experimental.convergence.anchor()444; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_L2_1]]) ]445; CHECK-NEXT:    br i1 [[COND]], label [[L2_1]], label [[LATCH_1:%.*]], !llvm.loop [[LOOP4]]446; CHECK:       latch.1:447; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_L2_1]]) ]448; CHECK-NEXT:    br label [[L2_2:%.*]], !llvm.loop [[LOOP4]]449; CHECK:       l2.2:450; CHECK-NEXT:    [[TOK_L2_2:%.*]] = call token @llvm.experimental.convergence.anchor()451; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_L2_2]]) ]452; CHECK-NEXT:    br i1 [[COND]], label [[L2_2]], label [[LATCH_2:%.*]], !llvm.loop [[LOOP4]]453; CHECK:       latch.2:454; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_L2_2]]) ]455; CHECK-NEXT:    br label [[L2_3:%.*]], !llvm.loop [[LOOP4]]456; CHECK:       l2.3:457; CHECK-NEXT:    [[TOK_L2_3:%.*]] = call token @llvm.experimental.convergence.anchor()458; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_L2_3]]) ]459; CHECK-NEXT:    br i1 [[COND]], label [[L2_3]], label [[LATCH_3:%.*]], !llvm.loop [[LOOP4]]460; CHECK:       latch.3:461; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_L2_3]]) ]462; CHECK-NEXT:    ret i32 0463;464entry:465  br label %l3466 467l3:468  %x.0 = phi i32 [ 0, %entry ], [ %inc, %latch ]469  %tok.loop = call token @llvm.experimental.convergence.anchor()470  %inc = add nsw i32 %x.0, 1471  %exitcond = icmp eq i32 %inc, 4472  br label %l2, !llvm.loop !1473 474l2:475  %tok.l2 = call token @llvm.experimental.convergence.anchor()476  call void @f() [ "convergencectrl"(token %tok.l2) ]477  br i1 %cond, label %l2, label %latch, !llvm.loop !1478 479latch:480  call void @f() [ "convergencectrl"(token %tok.l2) ]481  br i1 %exitcond, label %exit, label %l3482 483exit:484  ret i32 0485}486 487; No extension. Both loops unrolled.488 489define i32 @unroll_nest(i32 %n, i1 %cond) {490; CHECK-LABEL: @unroll_nest(491; CHECK-NEXT:  entry:492; CHECK-NEXT:    br label [[L3:%.*]]493; CHECK:       l3:494; CHECK-NEXT:    br label [[L2:%.*]], !llvm.loop [[LOOP4]]495; CHECK:       l2:496; CHECK-NEXT:    [[TOK_L2:%.*]] = call token @llvm.experimental.convergence.anchor()497; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_L2]]) ]498; CHECK-NEXT:    br i1 [[COND:%.*]], label [[L2_1:%.*]], label [[LATCH:%.*]], !llvm.loop [[LOOP4]]499; CHECK:       l2.1:500; CHECK-NEXT:    [[TOK_L2_1:%.*]] = call token @llvm.experimental.convergence.anchor()501; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_L2_1]]) ]502; CHECK-NEXT:    br i1 [[COND]], label [[L2]], label [[LATCH]], !llvm.loop [[LOOP9:![0-9]+]]503; CHECK:       latch:504; CHECK-NEXT:    br label [[L2_12:%.*]], !llvm.loop [[LOOP4]]505; CHECK:       l2.12:506; CHECK-NEXT:    [[TOK_L2_11:%.*]] = call token @llvm.experimental.convergence.anchor()507; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_L2_11]]) ]508; CHECK-NEXT:    br i1 [[COND]], label [[L2_1_1:%.*]], label [[LATCH_1:%.*]], !llvm.loop [[LOOP4]]509; CHECK:       l2.1.1:510; CHECK-NEXT:    [[TOK_L2_1_1:%.*]] = call token @llvm.experimental.convergence.anchor()511; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_L2_1_1]]) ]512; CHECK-NEXT:    br i1 [[COND]], label [[L2_12]], label [[LATCH_1]], !llvm.loop [[LOOP9]]513; CHECK:       latch.1:514; CHECK-NEXT:    br label [[L2_2:%.*]], !llvm.loop [[LOOP4]]515; CHECK:       l2.2:516; CHECK-NEXT:    [[TOK_L2_2:%.*]] = call token @llvm.experimental.convergence.anchor()517; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_L2_2]]) ]518; CHECK-NEXT:    br i1 [[COND]], label [[L2_1_2:%.*]], label [[LATCH_2:%.*]], !llvm.loop [[LOOP4]]519; CHECK:       l2.1.2:520; CHECK-NEXT:    [[TOK_L2_1_2:%.*]] = call token @llvm.experimental.convergence.anchor()521; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_L2_1_2]]) ]522; CHECK-NEXT:    br i1 [[COND]], label [[L2_2]], label [[LATCH_2]], !llvm.loop [[LOOP9]]523; CHECK:       latch.2:524; CHECK-NEXT:    br label [[L2_3:%.*]], !llvm.loop [[LOOP4]]525; CHECK:       l2.3:526; CHECK-NEXT:    [[TOK_L2_3:%.*]] = call token @llvm.experimental.convergence.anchor()527; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_L2_3]]) ]528; CHECK-NEXT:    br i1 [[COND]], label [[L2_1_3:%.*]], label [[LATCH_3:%.*]], !llvm.loop [[LOOP4]]529; CHECK:       l2.1.3:530; CHECK-NEXT:    [[TOK_L2_1_3:%.*]] = call token @llvm.experimental.convergence.anchor()531; CHECK-NEXT:    call void @f() [ "convergencectrl"(token [[TOK_L2_1_3]]) ]532; CHECK-NEXT:    br i1 [[COND]], label [[L2_3]], label [[LATCH_3]], !llvm.loop [[LOOP9]]533; CHECK:       latch.3:534; CHECK-NEXT:    ret i32 0535;536entry:537  br label %l3538 539l3:540  %x.0 = phi i32 [ 0, %entry ], [ %inc, %latch ]541  %tok.loop = call token @llvm.experimental.convergence.anchor()542  %inc = add nsw i32 %x.0, 1543  %exitcond = icmp eq i32 %inc, 4544  br label %l2, !llvm.loop !1545 546l2:547  %tok.l2 = call token @llvm.experimental.convergence.anchor()548  call void @f() [ "convergencectrl"(token %tok.l2) ]549  br i1 %cond, label %l2, label %latch, !llvm.loop !1550 551latch:552  br i1 %exitcond, label %exit, label %l3553 554exit:555  ret i32 0556}557 558declare token @llvm.experimental.convergence.anchor()559declare token @llvm.experimental.convergence.loop()560 561!0 = !{!0, !{!"llvm.loop.unroll.count", i32 16}}562!1 = !{!1, !{!"llvm.loop.unroll.count", i32 2}}563