1; 2; There should be just a single copy of each loop when strictest mutiplier 3; candidates formula (unscaled candidates == 0) is enforced: 4 5; RUN: opt < %s -enable-nontrivial-unswitch -enable-unswitch-cost-multiplier=true \ 6; RUN: -unswitch-num-initial-unscaled-candidates=0 -unswitch-siblings-toplevel-div=1 \ 7; RUN: -passes='loop(unswitch),print<loops>' -disable-output 2>&1 | FileCheck %s --check-prefixes=LOOP1 8; 9; RUN: opt < %s -enable-nontrivial-unswitch -enable-unswitch-cost-multiplier=true \ 10; RUN: -unswitch-num-initial-unscaled-candidates=0 -unswitch-siblings-toplevel-div=16 \ 11; RUN: -passes='loop(unswitch),print<loops>' -disable-output 2>&1 | FileCheck %s --check-prefixes=LOOP1 12; 13; 14; When we relax the candidates part of a multiplier formula 15; (unscaled candidates == 4) we start getting some unswitches, 16; which leads to siblings multiplier kicking in. 17; 18; RUN: opt < %s -enable-nontrivial-unswitch -enable-unswitch-cost-multiplier=true \ 19; RUN: -unswitch-num-initial-unscaled-candidates=4 -unswitch-siblings-toplevel-div=1 \ 20; RUN: -passes='loop(unswitch),print<loops>' -disable-output 2>&1 | \ 21; RUN: sort -b -k 1 | FileCheck %s --check-prefixes=LOOP-UNSCALE4-DIV1 22; 23; NB: sort -b is essential here and below, otherwise blanks might lead to different 24; order depending on locale. 25; 26; RUN: opt < %s -enable-nontrivial-unswitch -enable-unswitch-cost-multiplier=true \ 27; RUN: -unswitch-num-initial-unscaled-candidates=4 -unswitch-siblings-toplevel-div=2 \ 28; RUN: -passes='loop(unswitch),print<loops>' -disable-output 2>&1 | \ 29; RUN: sort -b -k 1 | FileCheck %s --check-prefixes=LOOP-UNSCALE4-DIV2 30; 31; 32; Get 33; 2^(num conds) == 2^5 = 32 34; loop nests when cost multiplier is disabled: 35; 36; RUN: opt < %s -enable-nontrivial-unswitch -enable-unswitch-cost-multiplier=false \ 37; RUN: -passes='loop(unswitch),print<loops>' -disable-output 2>&1 | \ 38; RUN: sort -b -k 1 | FileCheck %s --check-prefixes=LOOP32 39; 40; Single loop nest, not unswitched 41; LOOP1: Loop at depth 1 containing: 42; LOOP1: Loop at depth 2 containing: 43; LOOP1: Loop at depth 3 containing: 44; LOOP1-NOT: Loop at depth {{[0-9]+}} containing: 45; 46; Half unswitched loop nests, with unscaled4 and div1 it gets less depth1 loops unswitched 47; since they have more cost. 48; LOOP-UNSCALE4-DIV1-COUNT-6: Loop at depth 1 containing: 49; LOOP-UNSCALE4-DIV1-COUNT-19: Loop at depth 2 containing: 50; LOOP-UNSCALE4-DIV1-COUNT-29: Loop at depth 3 containing: 51; LOOP-UNSCALE4-DIV1-NOT: Loop at depth {{[0-9]+}} containing: 52; 53; Half unswitched loop nests, with unscaled4 and div2 it gets more depth1 loops unswitched 54; as div2 kicks in. 55; LOOP-UNSCALE4-DIV2-COUNT-11: Loop at depth 1 containing: 56; LOOP-UNSCALE4-DIV2-COUNT-22: Loop at depth 2 containing: 57; LOOP-UNSCALE4-DIV2-COUNT-29: Loop at depth 3 containing: 58; LOOP-UNSCALE4-DIV2-NOT: Loop at depth {{[0-9]+}} containing: 59; 60; 32 loop nests, fully unswitched 61; LOOP32-COUNT-32: Loop at depth 1 containing: 62; LOOP32-COUNT-32: Loop at depth 2 containing: 63; LOOP32-COUNT-32: Loop at depth 3 containing: 64; LOOP32-NOT: Loop at depth {{[0-9]+}} containing: 65 66declare void @bar() 67 68define void @loop_nested3_conds5(i32* %addr, i1 %c1, i1 %c2, i1 %c3, i1 %c4, i1 %c5) { 69entry: 70 %addr1 = getelementptr i32, i32* %addr, i64 0 71 %addr2 = getelementptr i32, i32* %addr, i64 1 72 %addr3 = getelementptr i32, i32* %addr, i64 2 73 br label %outer 74outer: 75 %iv1 = phi i32 [0, %entry], [%iv1.next, %outer_latch] 76 %iv1.next = add i32 %iv1, 1 77 ;; skip nontrivial unswitch 78 call void @bar() 79 br label %middle 80middle: 81 %iv2 = phi i32 [0, %outer], [%iv2.next, %middle_latch] 82 %iv2.next = add i32 %iv2, 1 83 ;; skip nontrivial unswitch 84 call void @bar() 85 br label %loop 86loop: 87 %iv3 = phi i32 [0, %middle], [%iv3.next, %loop_latch] 88 %iv3.next = add i32 %iv3, 1 89 ;; skip nontrivial unswitch 90 call void @bar() 91 br i1 %c1, label %loop_next1_left, label %loop_next1_right 92loop_next1_left: 93 br label %loop_next1 94loop_next1_right: 95 br label %loop_next1 96 97loop_next1: 98 br i1 %c2, label %loop_next2_left, label %loop_next2_right 99loop_next2_left: 100 br label %loop_next2 101loop_next2_right: 102 br label %loop_next2 103 104loop_next2: 105 br i1 %c3, label %loop_next3_left, label %loop_next3_right 106loop_next3_left: 107 br label %loop_next3 108loop_next3_right: 109 br label %loop_next3 110 111loop_next3: 112 br i1 %c4, label %loop_next4_left, label %loop_next4_right 113loop_next4_left: 114 br label %loop_next4 115loop_next4_right: 116 br label %loop_next4 117 118loop_next4: 119 br i1 %c5, label %loop_latch_left, label %loop_latch_right 120loop_latch_left: 121 br label %loop_latch 122loop_latch_right: 123 br label %loop_latch 124 125loop_latch: 126 store volatile i32 0, i32* %addr1 127 %test_loop = icmp slt i32 %iv3, 50 128 br i1 %test_loop, label %loop, label %middle_latch 129middle_latch: 130 store volatile i32 0, i32* %addr2 131 %test_middle = icmp slt i32 %iv2, 50 132 br i1 %test_middle, label %middle, label %outer_latch 133outer_latch: 134 store volatile i32 0, i32* %addr3 135 %test_outer = icmp slt i32 %iv1, 50 136 br i1 %test_outer, label %outer, label %exit 137exit: 138 ret void 139} 140