1; RUN: opt -mtriple=aarch64--linux-gnueabi -loop-vectorize -force-vector-width=4 -force-vector-interleave=1 < %s -S | FileCheck %s 2 3; The following tests contain loops for which SCEV cannot determine the backedge 4; taken count. This is because the backedge taken condition is produced by an 5; icmp with one of the sides being a loop varying non-AddRec expression. 6; However, there is a possibility to normalize this to an AddRec expression 7; using SCEV predicates. This allows us to compute a 'guarded' backedge count. 8; The Loop Vectorizer is able to version to loop in order to use this guarded 9; backedge count and vectorize more loops. 10 11 12; CHECK-LABEL: test_sge 13; CHECK-LABEL: vector.scevcheck 14; CHECK-LABEL: vector.body 15define void @test_sge(i32* noalias %A, 16 i32* noalias %B, 17 i32* noalias %C, i32 %N) { 18entry: 19 %cmp13 = icmp eq i32 %N, 0 20 br i1 %cmp13, label %for.end, label %for.body.preheader 21 22for.body.preheader: 23 br label %for.body 24 25for.body: 26 %indvars.iv = phi i16 [ %indvars.next, %for.body ], [ 0, %for.body.preheader ] 27 %indvars.next = add i16 %indvars.iv, 1 28 %indvars.ext = zext i16 %indvars.iv to i32 29 30 %arrayidx = getelementptr inbounds i32, i32* %B, i32 %indvars.ext 31 %0 = load i32, i32* %arrayidx, align 4 32 %arrayidx3 = getelementptr inbounds i32, i32* %C, i32 %indvars.ext 33 %1 = load i32, i32* %arrayidx3, align 4 34 35 %mul4 = mul i32 %1, %0 36 37 %arrayidx7 = getelementptr inbounds i32, i32* %A, i32 %indvars.ext 38 store i32 %mul4, i32* %arrayidx7, align 4 39 40 %exitcond = icmp sge i32 %indvars.ext, %N 41 br i1 %exitcond, label %for.end.loopexit, label %for.body 42 43for.end.loopexit: 44 br label %for.end 45 46for.end: 47 ret void 48} 49 50; CHECK-LABEL: test_uge 51; CHECK-LABEL: vector.scevcheck 52; CHECK-LABEL: vector.body 53define void @test_uge(i32* noalias %A, 54 i32* noalias %B, 55 i32* noalias %C, i32 %N, i32 %Offset) { 56entry: 57 %cmp13 = icmp eq i32 %N, 0 58 br i1 %cmp13, label %for.end, label %for.body.preheader 59 60for.body.preheader: 61 br label %for.body 62 63for.body: 64 %indvars.iv = phi i16 [ %indvars.next, %for.body ], [ 0, %for.body.preheader ] 65 %indvars.next = add i16 %indvars.iv, 1 66 67 %indvars.ext = sext i16 %indvars.iv to i32 68 %indvars.access = add i32 %Offset, %indvars.ext 69 70 %arrayidx = getelementptr inbounds i32, i32* %B, i32 %indvars.access 71 %0 = load i32, i32* %arrayidx, align 4 72 %arrayidx3 = getelementptr inbounds i32, i32* %C, i32 %indvars.access 73 %1 = load i32, i32* %arrayidx3, align 4 74 75 %mul4 = add i32 %1, %0 76 77 %arrayidx7 = getelementptr inbounds i32, i32* %A, i32 %indvars.access 78 store i32 %mul4, i32* %arrayidx7, align 4 79 80 %exitcond = icmp uge i32 %indvars.ext, %N 81 br i1 %exitcond, label %for.end.loopexit, label %for.body 82 83for.end.loopexit: 84 br label %for.end 85 86for.end: 87 ret void 88} 89 90; CHECK-LABEL: test_ule 91; CHECK-LABEL: vector.scevcheck 92; CHECK-LABEL: vector.body 93define void @test_ule(i32* noalias %A, 94 i32* noalias %B, 95 i32* noalias %C, i32 %N, 96 i16 %M) { 97entry: 98 %cmp13 = icmp eq i32 %N, 0 99 br i1 %cmp13, label %for.end, label %for.body.preheader 100 101for.body.preheader: 102 br label %for.body 103 104for.body: 105 %indvars.iv = phi i16 [ %indvars.next, %for.body ], [ %M, %for.body.preheader ] 106 %indvars.next = sub i16 %indvars.iv, 1 107 %indvars.ext = zext i16 %indvars.iv to i32 108 109 %arrayidx = getelementptr inbounds i32, i32* %B, i32 %indvars.ext 110 %0 = load i32, i32* %arrayidx, align 4 111 %arrayidx3 = getelementptr inbounds i32, i32* %C, i32 %indvars.ext 112 %1 = load i32, i32* %arrayidx3, align 4 113 114 %mul4 = mul i32 %1, %0 115 116 %arrayidx7 = getelementptr inbounds i32, i32* %A, i32 %indvars.ext 117 store i32 %mul4, i32* %arrayidx7, align 4 118 119 %exitcond = icmp ule i32 %indvars.ext, %N 120 br i1 %exitcond, label %for.end.loopexit, label %for.body 121 122for.end.loopexit: 123 br label %for.end 124 125for.end: 126 ret void 127} 128 129; CHECK-LABEL: test_sle 130; CHECK-LABEL: vector.scevcheck 131; CHECK-LABEL: vector.body 132define void @test_sle(i32* noalias %A, 133 i32* noalias %B, 134 i32* noalias %C, i32 %N, 135 i16 %M) { 136entry: 137 %cmp13 = icmp eq i32 %N, 0 138 br i1 %cmp13, label %for.end, label %for.body.preheader 139 140for.body.preheader: 141 br label %for.body 142 143for.body: 144 %indvars.iv = phi i16 [ %indvars.next, %for.body ], [ %M, %for.body.preheader ] 145 %indvars.next = sub i16 %indvars.iv, 1 146 %indvars.ext = sext i16 %indvars.iv to i32 147 148 %arrayidx = getelementptr inbounds i32, i32* %B, i32 %indvars.ext 149 %0 = load i32, i32* %arrayidx, align 4 150 %arrayidx3 = getelementptr inbounds i32, i32* %C, i32 %indvars.ext 151 %1 = load i32, i32* %arrayidx3, align 4 152 153 %mul4 = mul i32 %1, %0 154 155 %arrayidx7 = getelementptr inbounds i32, i32* %A, i32 %indvars.ext 156 store i32 %mul4, i32* %arrayidx7, align 4 157 158 %exitcond = icmp sle i32 %indvars.ext, %N 159 br i1 %exitcond, label %for.end.loopexit, label %for.body 160 161for.end.loopexit: 162 br label %for.end 163 164for.end: 165 ret void 166} 167