|  | ; RUN: opt < %s -loop-unroll -indvars -disable-output | 
|  |  | 
|  | @b = external global i32, align 4 | 
|  |  | 
|  | ; Test that LoopUnroll does not break LCSSA form. | 
|  | ; | 
|  | ; In this function we have a following CFG: | 
|  | ;            ( entry ) | 
|  | ;                | | 
|  | ;                v | 
|  | ;         ( outer.header ) <-- | 
|  | ;                |             \ | 
|  | ;                v              | | 
|  | ;     --> ( inner.header )      | | 
|  | ;   /       /          \        | | 
|  | ;   \      /            \       | | 
|  | ;    \    v              v     / | 
|  | ;  ( inner.latch )   ( outer.latch ) | 
|  | ;         | | 
|  | ;         v | 
|  | ;     ( exit ) | 
|  | ; | 
|  | ; When the inner loop is unrolled, we inner.latch block has only one | 
|  | ; predecessor and one successor, so it can be merged with exit block. | 
|  | ; During the merge, however, we remove an LCSSA definition for | 
|  | ; %storemerge1.lcssa, breaking LCSSA form for the outer loop. | 
|  |  | 
|  | ; Function Attrs: nounwind uwtable | 
|  | define void @fn1() #0 { | 
|  | entry: | 
|  | br label %outer.header | 
|  |  | 
|  | outer.header:                                     ; preds = %outer.latch, %entry | 
|  | %storemerge1 = phi i32 [ 0, %entry ], [ %inc9, %outer.latch ] | 
|  | br label %inner.header | 
|  |  | 
|  | inner.header:                                     ; preds = %inner.latch, %outer.header | 
|  | %storemerge = phi i32 [ %add, %inner.latch ], [ 0, %outer.header ] | 
|  | %cmp = icmp slt i32 %storemerge, 1 | 
|  | br i1 %cmp, label %inner.latch, label %outer.latch | 
|  |  | 
|  | inner.latch:                                      ; preds = %inner.header | 
|  | %tobool4 = icmp eq i32 %storemerge, 0 | 
|  | %add = add nsw i32 %storemerge, 1 | 
|  | br i1 %tobool4, label %inner.header, label %exit | 
|  |  | 
|  | exit:                                             ; preds = %inner.latch | 
|  | %storemerge1.lcssa = phi i32 [ %storemerge1, %inner.latch ] | 
|  | store i32 %storemerge1.lcssa, i32* @b, align 4 | 
|  | ret void | 
|  |  | 
|  | outer.latch:                                      ; preds = %inner.header | 
|  | %inc9 = add nsw i32 %storemerge1, 1 | 
|  | br label %outer.header | 
|  | } | 
|  |  | 
|  | ; This case is similar to the previous one, and has the same CFG. | 
|  | ; The difference is that loop unrolling doesn't remove any LCSSA definition, | 
|  | ; yet breaks LCSSA form for the outer loop. It happens because before unrolling | 
|  | ; block inner.latch was inside outer loop (and consequently, didn't require | 
|  | ; LCSSA definition for %x), but after unrolling it occurs out of the outer | 
|  | ; loop, so we need to insert an LCSSA definition to keep LCSSA. | 
|  |  | 
|  | ; Function Attrs: nounwind uwtable | 
|  | define void @fn2() { | 
|  | entry: | 
|  | br label %outer.header | 
|  |  | 
|  | outer.header: | 
|  | br label %inner.header | 
|  |  | 
|  | inner.header: | 
|  | %x = load i32, i32* undef, align 4 | 
|  | br i1 true, label %outer.latch, label %inner.latch | 
|  |  | 
|  | inner.latch: | 
|  | %inc6 = add nsw i32 %x, 1 | 
|  | store i32 %inc6, i32* undef, align 4 | 
|  | br i1 false, label %inner.header, label %exit | 
|  |  | 
|  | exit: | 
|  | ret void | 
|  |  | 
|  | outer.latch: | 
|  | br label %outer.header | 
|  | } |