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 10 define i32 @hwloop1() nounwind { 11 entry: 12 br label %for.body 13 for.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 20 for.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 29 define i32 @hwloop2(i32 %n, i32* nocapture %b) nounwind { 30 entry: 31 %cmp1 = icmp sgt i32 %n, 0 32 br i1 %cmp1, label %for.body.preheader, label %for.end 33 34 for.body.preheader: 35 br label %for.body 36 37 for.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 47 for.end.loopexit: 48 br label %for.end 49 50 for.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 61 define i32 @hwloop3(i32 %n, i32* nocapture %b) nounwind { 62 entry: 63 %cmp1 = icmp sgt i32 %n, 0 64 br i1 %cmp1, label %for.body.preheader, label %for.end 65 66 for.body.preheader: 67 br label %for.body 68 69 for.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 79 for.end.loopexit: 80 br label %for.end 81 82 for.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 92 define i32 @hwloop4(i32 %n, i32* nocapture %b) nounwind { 93 entry: 94 %cmp1 = icmp sgt i32 %n, 0 95 br i1 %cmp1, label %for.body.preheader, label %for.end 96 97 for.body.preheader: 98 br label %for.body 99 100 for.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 108 for.end.loopexit: 109 br label %for.end 110 111 for.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 120 define void @hwloop5(i32* nocapture %a, i32* nocapture %res) nounwind { 121 entry: 122 br label %for.body 123 124 for.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 135 for.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 145 define void @hwloop6(i32* nocapture %a, i32* nocapture %res) nounwind { 146 entry: 147 br label %for.body 148 149 for.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 159 for.end: 160 ret void 161 } 162