1 ; RUN: opt < %s -loop-unroll -S | FileCheck %s 2 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" 3 4 ; This test shows how unrolling an inner loop could break LCSSA for an outer 5 ; loop, and there is no cheap way to recover it. 6 ; 7 ; In this case the inner loop, L3, is being unrolled. It only runs one 8 ; iteration, so unrolling basically means replacing 9 ; br i1 true, label %exit, label %L3_header 10 ; with 11 ; br label %exit 12 ; 13 ; However, this change messes up the loops structure: for instance, block 14 ; L3_body no longer belongs to L2. It becomes an exit block for L2, so LCSSA 15 ; phis for definitions in L2 should now be placed there. In particular, we need 16 ; to insert such a definition for %y1. 17 18 ; CHECK-LABEL: @foo1 19 define void @foo1() { 20 entry: 21 br label %L1_header 22 23 L1_header: 24 br label %L2_header 25 26 L2_header: 27 %y1 = phi i64 [ undef, %L1_header ], [ %x.lcssa, %L2_latch ] 28 br label %L3_header 29 30 L3_header: 31 %y2 = phi i64 [ 0, %L3_latch ], [ %y1, %L2_header ] 32 %x = add i64 undef, -1 33 br i1 true, label %L2_latch, label %L3_body 34 35 L2_latch: 36 %x.lcssa = phi i64 [ %x, %L3_header ] 37 br label %L2_header 38 39 ; CHECK: L3_body: 40 ; CHECK-NEXT: %y1.lcssa = phi i64 [ %y1, %L3_header ] 41 L3_body: 42 store i64 %y1, i64* undef 43 br i1 false, label %L3_latch, label %L1_latch 44 45 L3_latch: 46 br i1 true, label %exit, label %L3_header 47 48 L1_latch: 49 %y.lcssa = phi i64 [ %y2, %L3_body ] 50 br label %L1_header 51 52 exit: 53 ret void 54 } 55 56 ; Additional tests for some corner cases. 57 ; 58 ; CHECK-LABEL: @foo2 59 define void @foo2() { 60 entry: 61 br label %L1_header 62 63 L1_header: 64 br label %L2_header 65 66 L2_header: 67 %a = phi i64 [ undef, %L1_header ], [ %dec_us, %L3_header ] 68 br label %L3_header 69 70 L3_header: 71 %b = phi i64 [ 0, %L3_latch ], [ %a, %L2_header ] 72 %dec_us = add i64 undef, -1 73 br i1 true, label %L2_header, label %L3_break_to_L1 74 75 ; CHECK: L3_break_to_L1: 76 ; CHECK-NEXT: %a.lcssa = phi i64 [ %a, %L3_header ] 77 L3_break_to_L1: 78 br i1 false, label %L3_latch, label %L1_latch 79 80 L1_latch: 81 %b_lcssa = phi i64 [ %b, %L3_break_to_L1 ] 82 br label %L1_header 83 84 L3_latch: 85 br i1 true, label %Exit, label %L3_header 86 87 Exit: 88 ret void 89 } 90 91 ; CHECK-LABEL: @foo3 92 define void @foo3() { 93 entry: 94 br label %L1_header 95 96 L1_header: 97 %a = phi i8* [ %b, %L1_latch ], [ null, %entry ] 98 br i1 undef, label %L2_header, label %L1_latch 99 100 L2_header: 101 br i1 undef, label %L2_latch, label %L1_latch 102 103 ; CHECK: L2_latch: 104 ; CHECK-NEXT: %a.lcssa = phi i8* [ %a, %L2_header ] 105 L2_latch: 106 br i1 true, label %L2_exit, label %L2_header 107 108 L1_latch: 109 %b = phi i8* [ undef, %L1_header ], [ null, %L2_header ] 110 br label %L1_header 111 112 L2_exit: 113 %a_lcssa1 = phi i8* [ %a, %L2_latch ] 114 br label %Exit 115 116 Exit: 117 %a_lcssa2 = phi i8* [ %a_lcssa1, %L2_exit ] 118 ret void 119 } 120 121 ; PR26688 122 ; CHECK-LABEL: @foo4 123 define i8 @foo4() { 124 entry: 125 br label %L1_header 126 127 L1_header: 128 %x = icmp eq i32 1, 0 129 br label %L2_header 130 131 L2_header: 132 br label %L3_header 133 134 L3_header: 135 br i1 true, label %L2_header, label %L3_exiting 136 137 L3_exiting: 138 br i1 true, label %L3_body, label %L1_latch 139 140 ; CHECK: L3_body: 141 ; CHECK-NEXT: %x.lcssa = phi i1 142 L3_body: 143 br i1 %x, label %L3_latch, label %L3_latch 144 145 L3_latch: 146 br i1 false, label %L3_header, label %exit 147 148 L1_latch: 149 br label %L1_header 150 151 exit: 152 ret i8 0 153 } 154