1; RUN: llc -march=hexagon -enable-pipeliner=false < %s | FileCheck %s 2; Check that we generate hardware loop instructions. 3 4; Case 1 : Loop with a constant number of iterations. 5; CHECK-LABEL: @hwloop1 6; CHECK: loop0(.LBB{{.}}_{{.}},#10) 7; CHECK: endloop0 8 9@a = common global [10 x i32] zeroinitializer, align 4 10define i32 @hwloop1() nounwind { 11entry: 12 br label %for.body 13for.body: 14 %i.01 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 15 %arrayidx = getelementptr inbounds [10 x i32], [10 x i32]* @a, i32 0, i32 %i.01 16 store i32 %i.01, i32* %arrayidx, align 4 17 %inc = add nsw i32 %i.01, 1 18 %exitcond = icmp eq i32 %inc, 10 19 br i1 %exitcond, label %for.end, label %for.body 20for.end: 21 ret i32 0 22} 23 24; Case 2 : Loop with a run-time number of iterations. 25; CHECK-LABEL: @hwloop2 26; CHECK: loop0(.LBB{{.}}_{{.}},r{{[0-9]+}}) 27; CHECK: endloop0 28 29define i32 @hwloop2(i32 %n, i32* nocapture %b) nounwind { 30entry: 31 %cmp1 = icmp sgt i32 %n, 0 32 br i1 %cmp1, label %for.body.preheader, label %for.end 33 34for.body.preheader: 35 br label %for.body 36 37for.body: 38 %a.03 = phi i32 [ %add, %for.body ], [ 0, %for.body.preheader ] 39 %i.02 = phi i32 [ %inc, %for.body ], [ 0, %for.body.preheader ] 40 %arrayidx = getelementptr inbounds i32, i32* %b, i32 %i.02 41 %0 = load i32, i32* %arrayidx, align 4 42 %add = add nsw i32 %0, %a.03 43 %inc = add nsw i32 %i.02, 1 44 %exitcond = icmp eq i32 %inc, %n 45 br i1 %exitcond, label %for.end.loopexit, label %for.body 46 47for.end.loopexit: 48 br label %for.end 49 50for.end: 51 %a.0.lcssa = phi i32 [ 0, %entry ], [ %add, %for.end.loopexit ] 52 ret i32 %a.0.lcssa 53} 54 55; Case 3 : Induction variable increment more than 1. 56; CHECK-LABEL: @hwloop3 57; CHECK: lsr(r{{[0-9]+}},#2) 58; CHECK: loop0(.LBB{{.}}_{{.}},r{{[0-9]+}}) 59; CHECK: endloop0 60 61define i32 @hwloop3(i32 %n, i32* nocapture %b) nounwind { 62entry: 63 %cmp1 = icmp sgt i32 %n, 0 64 br i1 %cmp1, label %for.body.preheader, label %for.end 65 66for.body.preheader: 67 br label %for.body 68 69for.body: 70 %a.03 = phi i32 [ %add, %for.body ], [ 0, %for.body.preheader ] 71 %i.02 = phi i32 [ %inc, %for.body ], [ 0, %for.body.preheader ] 72 %arrayidx = getelementptr inbounds i32, i32* %b, i32 %i.02 73 %0 = load i32, i32* %arrayidx, align 4 74 %add = add nsw i32 %0, %a.03 75 %inc = add nsw i32 %i.02, 4 76 %exitcond = icmp eq i32 %inc, %n 77 br i1 %exitcond, label %for.end.loopexit, label %for.body 78 79for.end.loopexit: 80 br label %for.end 81 82for.end: 83 %a.0.lcssa = phi i32 [ 0, %entry ], [ %add, %for.end.loopexit ] 84 ret i32 %a.0.lcssa 85} 86 87; Case 4 : Loop exit compare uses register instead of immediate value. 88; CHECK-LABEL: @hwloop4 89; CHECK: loop0(.LBB{{.}}_{{.}},r{{[0-9]+}}) 90; CHECK: endloop0 91 92define i32 @hwloop4(i32 %n, i32* nocapture %b) nounwind { 93entry: 94 %cmp1 = icmp sgt i32 %n, 0 95 br i1 %cmp1, label %for.body.preheader, label %for.end 96 97for.body.preheader: 98 br label %for.body 99 100for.body: 101 %i.02 = phi i32 [ %inc, %for.body ], [ 0, %for.body.preheader ] 102 %arrayidx = getelementptr inbounds i32, i32* %b, i32 %i.02 103 store i32 %i.02, i32* %arrayidx, align 4 104 %inc = add nsw i32 %i.02, 1 105 %exitcond = icmp eq i32 %inc, %n 106 br i1 %exitcond, label %for.end.loopexit, label %for.body 107 108for.end.loopexit: 109 br label %for.end 110 111for.end: 112 ret i32 0 113} 114 115; Case 5: After LSR, the initial value is 100 and the iv decrements to 0. 116; CHECK-LABEL: @hwloop5 117; CHECK: loop0(.LBB{{.}}_{{.}},#100) 118; CHECK: endloop0 119 120define void @hwloop5(i32* nocapture %a, i32* nocapture %res) nounwind { 121entry: 122 br label %for.body 123 124for.body: 125 %i.03 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 126 %arrayidx = getelementptr inbounds i32, i32* %a, i32 %i.03 127 %0 = load i32, i32* %arrayidx, align 4 128 %mul = mul nsw i32 %0, %0 129 %arrayidx2 = getelementptr inbounds i32, i32* %res, i32 %i.03 130 store i32 %mul, i32* %arrayidx2, align 4 131 %inc = add nsw i32 %i.03, 1 132 %exitcond = icmp eq i32 %inc, 100 133 br i1 %exitcond, label %for.end, label %for.body 134 135for.end: 136 ret void 137} 138 139; Case 6: Large immediate offset 140; CHECK-LABEL: @hwloop6 141; CHECK-NOT: loop0(.LBB{{.}}_{{.}},#1024) 142; CHECK: loop0(.LBB{{.}}_{{.}},r{{[0-9]+}}) 143; CHECK: endloop0 144 145define void @hwloop6(i32* nocapture %a, i32* nocapture %res) nounwind { 146entry: 147 br label %for.body 148 149for.body: 150 %i.02 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 151 %arrayidx = getelementptr inbounds i32, i32* %a, i32 %i.02 152 %0 = load i32, i32* %arrayidx, align 4 153 %arrayidx1 = getelementptr inbounds i32, i32* %res, i32 %i.02 154 store i32 %0, i32* %arrayidx1, align 4 155 %inc = add nsw i32 %i.02, 1 156 %exitcond = icmp eq i32 %inc, 1024 157 br i1 %exitcond, label %for.end, label %for.body 158 159for.end: 160 ret void 161} 162