1*9880d681SAndroid Build Coastguard Worker; RUN: opt < %s -loop-unroll -indvars -disable-output 2*9880d681SAndroid Build Coastguard Worker 3*9880d681SAndroid Build Coastguard Worker@b = external global i32, align 4 4*9880d681SAndroid Build Coastguard Worker 5*9880d681SAndroid Build Coastguard Worker; Test that LoopUnroll does not break LCSSA form. 6*9880d681SAndroid Build Coastguard Worker; 7*9880d681SAndroid Build Coastguard Worker; In this function we have a following CFG: 8*9880d681SAndroid Build Coastguard Worker; ( entry ) 9*9880d681SAndroid Build Coastguard Worker; | 10*9880d681SAndroid Build Coastguard Worker; v 11*9880d681SAndroid Build Coastguard Worker; ( outer.header ) <-- 12*9880d681SAndroid Build Coastguard Worker; | \ 13*9880d681SAndroid Build Coastguard Worker; v | 14*9880d681SAndroid Build Coastguard Worker; --> ( inner.header ) | 15*9880d681SAndroid Build Coastguard Worker; / / \ | 16*9880d681SAndroid Build Coastguard Worker; \ / \ | 17*9880d681SAndroid Build Coastguard Worker; \ v v / 18*9880d681SAndroid Build Coastguard Worker; ( inner.latch ) ( outer.latch ) 19*9880d681SAndroid Build Coastguard Worker; | 20*9880d681SAndroid Build Coastguard Worker; v 21*9880d681SAndroid Build Coastguard Worker; ( exit ) 22*9880d681SAndroid Build Coastguard Worker; 23*9880d681SAndroid Build Coastguard Worker; When the inner loop is unrolled, we inner.latch block has only one 24*9880d681SAndroid Build Coastguard Worker; predecessor and one successor, so it can be merged with exit block. 25*9880d681SAndroid Build Coastguard Worker; During the merge, however, we remove an LCSSA definition for 26*9880d681SAndroid Build Coastguard Worker; %storemerge1.lcssa, breaking LCSSA form for the outer loop. 27*9880d681SAndroid Build Coastguard Worker 28*9880d681SAndroid Build Coastguard Worker; Function Attrs: nounwind uwtable 29*9880d681SAndroid Build Coastguard Workerdefine void @fn1() #0 { 30*9880d681SAndroid Build Coastguard Workerentry: 31*9880d681SAndroid Build Coastguard Worker br label %outer.header 32*9880d681SAndroid Build Coastguard Worker 33*9880d681SAndroid Build Coastguard Workerouter.header: ; preds = %outer.latch, %entry 34*9880d681SAndroid Build Coastguard Worker %storemerge1 = phi i32 [ 0, %entry ], [ %inc9, %outer.latch ] 35*9880d681SAndroid Build Coastguard Worker br label %inner.header 36*9880d681SAndroid Build Coastguard Worker 37*9880d681SAndroid Build Coastguard Workerinner.header: ; preds = %inner.latch, %outer.header 38*9880d681SAndroid Build Coastguard Worker %storemerge = phi i32 [ %add, %inner.latch ], [ 0, %outer.header ] 39*9880d681SAndroid Build Coastguard Worker %cmp = icmp slt i32 %storemerge, 1 40*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %inner.latch, label %outer.latch 41*9880d681SAndroid Build Coastguard Worker 42*9880d681SAndroid Build Coastguard Workerinner.latch: ; preds = %inner.header 43*9880d681SAndroid Build Coastguard Worker %tobool4 = icmp eq i32 %storemerge, 0 44*9880d681SAndroid Build Coastguard Worker %add = add nsw i32 %storemerge, 1 45*9880d681SAndroid Build Coastguard Worker br i1 %tobool4, label %inner.header, label %exit 46*9880d681SAndroid Build Coastguard Worker 47*9880d681SAndroid Build Coastguard Workerexit: ; preds = %inner.latch 48*9880d681SAndroid Build Coastguard Worker %storemerge1.lcssa = phi i32 [ %storemerge1, %inner.latch ] 49*9880d681SAndroid Build Coastguard Worker store i32 %storemerge1.lcssa, i32* @b, align 4 50*9880d681SAndroid Build Coastguard Worker ret void 51*9880d681SAndroid Build Coastguard Worker 52*9880d681SAndroid Build Coastguard Workerouter.latch: ; preds = %inner.header 53*9880d681SAndroid Build Coastguard Worker %inc9 = add nsw i32 %storemerge1, 1 54*9880d681SAndroid Build Coastguard Worker br label %outer.header 55*9880d681SAndroid Build Coastguard Worker} 56*9880d681SAndroid Build Coastguard Worker 57*9880d681SAndroid Build Coastguard Worker; This case is similar to the previous one, and has the same CFG. 58*9880d681SAndroid Build Coastguard Worker; The difference is that loop unrolling doesn't remove any LCSSA definition, 59*9880d681SAndroid Build Coastguard Worker; yet breaks LCSSA form for the outer loop. It happens because before unrolling 60*9880d681SAndroid Build Coastguard Worker; block inner.latch was inside outer loop (and consequently, didn't require 61*9880d681SAndroid Build Coastguard Worker; LCSSA definition for %x), but after unrolling it occurs out of the outer 62*9880d681SAndroid Build Coastguard Worker; loop, so we need to insert an LCSSA definition to keep LCSSA. 63*9880d681SAndroid Build Coastguard Worker 64*9880d681SAndroid Build Coastguard Worker; Function Attrs: nounwind uwtable 65*9880d681SAndroid Build Coastguard Workerdefine void @fn2() { 66*9880d681SAndroid Build Coastguard Workerentry: 67*9880d681SAndroid Build Coastguard Worker br label %outer.header 68*9880d681SAndroid Build Coastguard Worker 69*9880d681SAndroid Build Coastguard Workerouter.header: 70*9880d681SAndroid Build Coastguard Worker br label %inner.header 71*9880d681SAndroid Build Coastguard Worker 72*9880d681SAndroid Build Coastguard Workerinner.header: 73*9880d681SAndroid Build Coastguard Worker %x = load i32, i32* undef, align 4 74*9880d681SAndroid Build Coastguard Worker br i1 true, label %outer.latch, label %inner.latch 75*9880d681SAndroid Build Coastguard Worker 76*9880d681SAndroid Build Coastguard Workerinner.latch: 77*9880d681SAndroid Build Coastguard Worker %inc6 = add nsw i32 %x, 1 78*9880d681SAndroid Build Coastguard Worker store i32 %inc6, i32* undef, align 4 79*9880d681SAndroid Build Coastguard Worker br i1 false, label %inner.header, label %exit 80*9880d681SAndroid Build Coastguard Worker 81*9880d681SAndroid Build Coastguard Workerexit: 82*9880d681SAndroid Build Coastguard Worker ret void 83*9880d681SAndroid Build Coastguard Worker 84*9880d681SAndroid Build Coastguard Workerouter.latch: 85*9880d681SAndroid Build Coastguard Worker br label %outer.header 86*9880d681SAndroid Build Coastguard Worker} 87