Home | History | Annotate | Download | only in Hexagon
      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