1; RUN: opt -mtriple=arm-none-none-eabi -mcpu=cortex-m23 -passes=loop-unroll -unroll-runtime-multi-exit -S %s -o - | FileCheck %s 2 3; This loop has too many live outs, and should not be unrolled under v6m. 4; CHECK-LABEL: multiple_liveouts 5; CHECK: for.body 6; CHECK: br i1 %cmp.not, label %for.cond.cleanup.loopexit, label %for.body 7define void @multiple_liveouts(ptr %x, ptr %y, ptr %d, i32 %n) { 8entry: 9 %0 = load i32, ptr %d, align 4 10 %arrayidx1 = getelementptr inbounds i32, ptr %d, i32 1 11 %1 = load i32, ptr %arrayidx1, align 4 12 %arrayidx2 = getelementptr inbounds i32, ptr %d, i32 2 13 %2 = load i32, ptr %arrayidx2, align 4 14 %arrayidx3 = getelementptr inbounds i32, ptr %d, i32 3 15 %3 = load i32, ptr %arrayidx3, align 4 16 %cmp.not58 = icmp eq i32 %n, 0 17 br i1 %cmp.not58, label %for.cond.cleanup, label %for.body.preheader 18 19for.body.preheader: ; preds = %entry 20 br label %for.body 21 22for.body: ; preds = %for.body.preheader, %for.body 23 %x.addr.065 = phi ptr [ %incdec.ptr, %for.body ], [ %x, %for.body.preheader ] 24 %y.addr.064 = phi ptr [ %incdec.ptr25, %for.body ], [ %y, %for.body.preheader ] 25 %res00.063 = phi i32 [ %add, %for.body ], [ %0, %for.body.preheader ] 26 %rhs_cols_idx.062 = phi i32 [ %dec, %for.body ], [ %n, %for.body.preheader ] 27 %res11.061 = phi i32 [ %add24, %for.body ], [ %3, %for.body.preheader ] 28 %res10.060 = phi i32 [ %add20, %for.body ], [ %2, %for.body.preheader ] 29 %res01.059 = phi i32 [ %add14, %for.body ], [ %1, %for.body.preheader ] 30 %4 = load i32, ptr %x.addr.065, align 4 31 %arrayidx5 = getelementptr inbounds i32, ptr %x.addr.065, i32 %n 32 %5 = load i32, ptr %arrayidx5, align 4 33 %6 = load i32, ptr %y.addr.064, align 4 34 %conv9 = and i32 %6, 255 35 %conv10 = and i32 %4, 255 36 %mul = mul nuw nsw i32 %conv9, %conv10 37 %add = add nsw i32 %mul, %res00.063 38 %conv12 = and i32 %5, 255 39 %mul13 = mul nuw nsw i32 %conv9, %conv12 40 %add14 = add nsw i32 %mul13, %res01.059 41 %arrayidx15 = getelementptr inbounds i32, ptr %y.addr.064, i32 %n 42 %7 = load i32, ptr %arrayidx15, align 4 43 %conv17 = and i32 %7, 255 44 %mul19 = mul nuw nsw i32 %conv17, %conv10 45 %add20 = add nsw i32 %mul19, %res10.060 46 %mul23 = mul nuw nsw i32 %conv17, %conv12 47 %add24 = add nsw i32 %mul23, %res11.061 48 %incdec.ptr = getelementptr inbounds i32, ptr %x.addr.065, i32 1 49 %incdec.ptr25 = getelementptr inbounds i32, ptr %y.addr.064, i32 1 50 %dec = add nsw i32 %rhs_cols_idx.062, -1 51 %cmp.not = icmp eq i32 %dec, 0 52 br i1 %cmp.not, label %for.cond.cleanup.loopexit, label %for.body 53 54for.cond.cleanup.loopexit: ; preds = %for.body 55 %add.lcssa = phi i32 [ %add, %for.body ] 56 %add14.lcssa = phi i32 [ %add14, %for.body ] 57 %add20.lcssa = phi i32 [ %add20, %for.body ] 58 %add24.lcssa = phi i32 [ %add24, %for.body ] 59 br label %for.cond.cleanup 60 61for.cond.cleanup: ; preds = %for.cond.cleanup.loopexit, %entry 62 %res01.0 = phi i32 [ %1, %entry ], [ %add14.lcssa, %for.cond.cleanup.loopexit ] 63 %res10.0 = phi i32 [ %2, %entry ], [ %add20.lcssa, %for.cond.cleanup.loopexit ] 64 %res11.0 = phi i32 [ %3, %entry ], [ %add24.lcssa, %for.cond.cleanup.loopexit ] 65 %res00.0 = phi i32 [ %0, %entry ], [ %add.lcssa, %for.cond.cleanup.loopexit ] 66 store i32 %res00.0, ptr %d, align 4 67 store i32 %res01.0, ptr %arrayidx1, align 4 68 store i32 %res10.0, ptr %arrayidx2, align 4 69 store i32 %res11.0, ptr %arrayidx3, align 4 70 ret void 71} 72 73; This loop has both multiple exit blocks and multiple liveouts 74; CHECK-LABEL: multiple_liveouts_doubleexit 75; CHECK: for.body 76; CHECK: br i1 %cmp.not, label %cleanup22.loopexit2, label %for.body 77define void @multiple_liveouts_doubleexit(i32 %n, ptr %x, ptr %y, ptr %z) { 78entry: 79 %cmp.not55 = icmp eq i32 %n, 0 80 br i1 %cmp.not55, label %cleanup22, label %for.body.preheader 81 82for.body.preheader: ; preds = %entry 83 br label %for.body 84 85for.body: ; preds = %for.body.preheader, %for.inc 86 %x.addr.062 = phi ptr [ %incdec.ptr, %for.inc ], [ %x, %for.body.preheader ] 87 %y.addr.061 = phi ptr [ %incdec.ptr19, %for.inc ], [ %y, %for.body.preheader ] 88 %rhs_cols_idx.060 = phi i32 [ %dec, %for.inc ], [ %n, %for.body.preheader ] 89 %res11.059 = phi i32 [ %add18, %for.inc ], [ 0, %for.body.preheader ] 90 %res10.058 = phi i32 [ %add16, %for.inc ], [ 0, %for.body.preheader ] 91 %res01.057 = phi i32 [ %add8, %for.inc ], [ 0, %for.body.preheader ] 92 %res00.056 = phi i32 [ %add, %for.inc ], [ 0, %for.body.preheader ] 93 %0 = load i32, ptr %x.addr.062, align 4 94 %1 = load i32, ptr %y.addr.061, align 4 95 %conv5 = and i32 %1, 255 96 %conv6 = and i32 %0, 255 97 %mul = mul nuw nsw i32 %conv5, %conv6 98 %add = add nuw nsw i32 %mul, %res00.056 99 %add8 = add nuw nsw i32 %conv5, %res01.057 100 %cmp9 = icmp ugt i32 %add8, 100 101 br i1 %cmp9, label %cleanup22.loopexit, label %for.inc 102 103for.inc: ; preds = %for.body 104 %arrayidx11 = getelementptr inbounds i32, ptr %y.addr.061, i32 %n 105 %2 = load i32, ptr %arrayidx11, align 4 106 %conv13 = and i32 %2, 255 107 %mul15 = mul nuw nsw i32 %conv13, %conv6 108 %add16 = add nuw nsw i32 %mul15, %res10.058 109 %add18 = add nuw nsw i32 %conv13, %res11.059 110 %incdec.ptr = getelementptr inbounds i32, ptr %x.addr.062, i32 1 111 %incdec.ptr19 = getelementptr inbounds i32, ptr %y.addr.061, i32 1 112 %dec = add nsw i32 %rhs_cols_idx.060, -1 113 %cmp.not = icmp eq i32 %dec, 0 114 br i1 %cmp.not, label %cleanup22.loopexit2, label %for.body 115 116cleanup22.loopexit: ; preds = %for.body 117 %add.lcssa = phi i32 [ %add, %for.body ] 118 %add8.lcssa = phi i32 [ %add8, %for.body ] 119 %res10.0.lcssa.ph = phi i32 [ %res10.058, %for.body ] 120 %res11.0.lcssa.ph = phi i32 [ %res11.059, %for.body ] 121 br label %cleanup22 122 123cleanup22.loopexit2: ; preds = %for.inc 124 %add.lcssa2 = phi i32 [ %add, %for.inc ] 125 %add8.lcssa2 = phi i32 [ %add8, %for.inc ] 126 %res10.0.lcssa.ph2 = phi i32 [ %add16, %for.inc ] 127 %res11.0.lcssa.ph2 = phi i32 [ %add18, %for.inc ] 128 br label %cleanup22 129 130cleanup22: ; preds = %cleanup22.loopexit, %entry 131 %res10.0.lcssa = phi i32 [ 0, %entry ], [ %res10.0.lcssa.ph, %cleanup22.loopexit ], [ %res10.0.lcssa.ph2, %cleanup22.loopexit2 ] 132 %res11.0.lcssa = phi i32 [ 0, %entry ], [ %res11.0.lcssa.ph, %cleanup22.loopexit ], [ %res11.0.lcssa.ph2, %cleanup22.loopexit2 ] 133 %res00.1 = phi i32 [ 0, %entry ], [ %add.lcssa, %cleanup22.loopexit ], [ %add.lcssa2, %cleanup22.loopexit2 ] 134 %res01.1 = phi i32 [ 0, %entry ], [ %add8.lcssa, %cleanup22.loopexit ], [ %add8.lcssa2, %cleanup22.loopexit2 ] 135 store i32 %res00.1, ptr %z, align 4 136 %arrayidx24 = getelementptr inbounds i32, ptr %z, i32 1 137 store i32 %res01.1, ptr %arrayidx24, align 4 138 %arrayidx25 = getelementptr inbounds i32, ptr %z, i32 2 139 store i32 %res10.0.lcssa, ptr %arrayidx25, align 4 140 %arrayidx26 = getelementptr inbounds i32, ptr %z, i32 3 141 store i32 %res11.0.lcssa, ptr %arrayidx26, align 4 142 ret void 143} 144