160 lines · plain
1;2; Here all the branches we unswitch are exiting from the inner loop.3; That means we should not be getting exponential behavior on inner-loop4; unswitch. In fact there should be just a single version of inner-loop,5; with possibly some outer loop copies.6;7; There should be just a single copy of each loop when strictest mutiplier8; candidates formula (unscaled candidates == 0) is enforced:9 10; RUN: opt < %s -enable-unswitch-cost-multiplier=true \11; RUN: -unswitch-num-initial-unscaled-candidates=0 -unswitch-siblings-toplevel-div=1 \12; RUN: -passes='loop(simple-loop-unswitch<nontrivial>),print<loops>' -disable-output 2>&1 | FileCheck %s --check-prefixes=LOOP113;14; RUN: opt < %s -enable-unswitch-cost-multiplier=true \15; RUN: -unswitch-num-initial-unscaled-candidates=0 -unswitch-siblings-toplevel-div=16 \16; RUN: -passes='loop(simple-loop-unswitch<nontrivial>),print<loops>' -disable-output 2>&1 | FileCheck %s --check-prefixes=LOOP117;18; RUN: opt < %s -enable-unswitch-cost-multiplier=true \19; RUN: -unswitch-num-initial-unscaled-candidates=0 -unswitch-siblings-toplevel-div=1 \20; RUN: -passes='loop-mssa(simple-loop-unswitch<nontrivial>),print<loops>' -disable-output 2>&1 | FileCheck %s --check-prefixes=LOOP121;22; RUN: opt < %s -enable-unswitch-cost-multiplier=true \23; RUN: -unswitch-num-initial-unscaled-candidates=0 -unswitch-siblings-toplevel-div=16 \24; RUN: -passes='loop-mssa(simple-loop-unswitch<nontrivial>),print<loops>' -disable-output 2>&1 | FileCheck %s --check-prefixes=LOOP125;26; When we relax the candidates part of a multiplier formula27; (unscaled candidates == 2) we start getting some unswitches in outer loops,28; which leads to siblings multiplier kicking in.29;30; The tests below also run licm, because it is needed to hoist out31; loop-invariant freeze instructions, which otherwise may block further32; unswitching.33;34; RUN: opt < %s -enable-unswitch-cost-multiplier=true \35; RUN: -unswitch-num-initial-unscaled-candidates=3 -unswitch-siblings-toplevel-div=1 \36; RUN: -passes='loop-mssa(licm,simple-loop-unswitch<nontrivial>),print<loops>' -disable-output 2>&1 | \37; RUN: sort -b -k 1 | FileCheck %s --check-prefixes=LOOP-UNSCALE3-DIV138;39; NB: sort -b is essential here and below, otherwise blanks might lead to different40; order depending on locale.41;42; RUN: opt < %s -enable-unswitch-cost-multiplier=true \43; RUN: -unswitch-num-initial-unscaled-candidates=3 -unswitch-siblings-toplevel-div=2 \44; RUN: -passes='loop-mssa(licm,simple-loop-unswitch<nontrivial>),print<loops>' -disable-output 2>&1 | \45; RUN: sort -b -k 1 | FileCheck %s --check-prefixes=LOOP-UNSCALE3-DIV246;47; With disabled cost-multiplier we get maximal possible amount of unswitches.48;49; RUN: opt < %s -enable-unswitch-cost-multiplier=false \50; RUN: -passes='loop-mssa(licm,simple-loop-unswitch<nontrivial>),print<loops>' -disable-output 2>&1 | \51; RUN: sort -b -k 1 | FileCheck %s --check-prefixes=LOOP-MAX52;53; Single loop nest, not unswitched54; LOOP1: Loop at depth 1 containing:55; LOOP1-NOT: Loop at depth 1 containing:56; LOOP1: Loop at depth 2 containing:57; LOOP1-NOT: Loop at depth 2 containing:58; LOOP1: Loop at depth 3 containing:59; LOOP1-NOT: Loop at depth 3 containing:60;61; Half unswitched loop nests, with unscaled3 and div1 it gets less depth1 loops unswitched62; since they have more cost.63; LOOP-UNSCALE3-DIV1-COUNT-4: Loop at depth 1 containing:64; LOOP-UNSCALE3-DIV1-NOT: Loop at depth 1 containing:65; LOOP-UNSCALE3-DIV1-COUNT-1: Loop at depth 2 containing:66; LOOP-UNSCALE3-DIV1-NOT: Loop at depth 2 containing:67; LOOP-UNSCALE3-DIV1-COUNT-1: Loop at depth 3 containing:68; LOOP-UNSCALE3-DIV1-NOT: Loop at depth 3 containing:69;70; Half unswitched loop nests, with unscaled3 and div2 it gets more depth1 loops unswitched71; as div2 kicks in.72; LOOP-UNSCALE3-DIV2-COUNT-6: Loop at depth 1 containing:73; LOOP-UNSCALE3-DIV2-NOT: Loop at depth 1 containing:74; LOOP-UNSCALE3-DIV2-COUNT-1: Loop at depth 2 containing:75; LOOP-UNSCALE3-DIV2-NOT: Loop at depth 2 containing:76; LOOP-UNSCALE3-DIV2-COUNT-1: Loop at depth 3 containing:77; LOOP-UNSCALE3-DIV2-NOT: Loop at depth 3 containing:78;79; Maximally unswitched (copy of the outer loop per each condition)80; LOOP-MAX-COUNT-6: Loop at depth 1 containing:81; LOOP-MAX-NOT: Loop at depth 1 containing:82; LOOP-MAX-COUNT-1: Loop at depth 2 containing:83; LOOP-MAX-NOT: Loop at depth 2 containing:84; LOOP-MAX-COUNT-1: Loop at depth 3 containing:85; LOOP-MAX-NOT: Loop at depth 3 containing:86 87declare void @bar()88 89define void @loop_nested3_conds5(ptr %addr, i1 %c1, i1 %c2, i1 %c3, i1 %c4, i1 %c5) {90entry:91 %addr2 = getelementptr i32, ptr %addr, i64 192 %addr3 = getelementptr i32, ptr %addr, i64 293 br label %outer94outer:95 %iv1 = phi i32 [0, %entry], [%iv1.next, %outer_latch]96 %iv1.next = add i32 %iv1, 197 ;; skip nontrivial unswitch98 call void @bar()99 br label %middle100middle:101 %iv2 = phi i32 [0, %outer], [%iv2.next, %middle_latch]102 %iv2.next = add i32 %iv2, 1103 ;; skip nontrivial unswitch104 call void @bar()105 br label %loop106loop:107 %iv3 = phi i32 [0, %middle], [%iv3.next, %loop_latch]108 %iv3.next = add i32 %iv3, 1109 ;; skip nontrivial unswitch110 call void @bar()111 br i1 %c1, label %loop_next1_left, label %outer_latch112loop_next1_left:113 br label %loop_next1114loop_next1_right:115 br label %loop_next1116 117loop_next1:118 br i1 %c2, label %loop_next2_left, label %outer_latch119loop_next2_left:120 br label %loop_next2121loop_next2_right:122 br label %loop_next2123 124loop_next2:125 br i1 %c3, label %loop_next3_left, label %outer_latch126loop_next3_left:127 br label %loop_next3128loop_next3_right:129 br label %loop_next3130 131loop_next3:132 br i1 %c4, label %loop_next4_left, label %outer_latch133loop_next4_left:134 br label %loop_next4135loop_next4_right:136 br label %loop_next4137 138loop_next4:139 br i1 %c5, label %loop_latch_left, label %outer_latch140loop_latch_left:141 br label %loop_latch142loop_latch_right:143 br label %loop_latch144 145loop_latch:146 store volatile i32 0, ptr %addr147 %test_loop = icmp slt i32 %iv3, 50148 br i1 %test_loop, label %loop, label %middle_latch149middle_latch:150 store volatile i32 0, ptr %addr2151 %test_middle = icmp slt i32 %iv2, 50152 br i1 %test_middle, label %middle, label %outer_latch153outer_latch:154 store volatile i32 0, ptr %addr3155 %test_outer = icmp slt i32 %iv1, 50156 br i1 %test_outer, label %outer, label %exit157exit:158 ret void159}160