[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / CodeGen / Hexagon / hwloop1.ll
blob7a805d951b959f1b7e9351773466bf17c4eb72c5
1 ; RUN: llc -march=hexagon -enable-pipeliner=false < %s | FileCheck %s
2 ; Check that we generate hardware loop instructions.
4 ; Case 1 : Loop with a constant number of iterations.
5 ; CHECK-LABEL: @hwloop1
6 ; CHECK: loop0(.LBB{{.}}_{{.}},#10)
7 ; CHECK: endloop0
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
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
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
34 for.body.preheader:
35   br label %for.body
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
47 for.end.loopexit:
48   br label %for.end
50 for.end:
51   %a.0.lcssa = phi i32 [ 0, %entry ], [ %add, %for.end.loopexit ]
52   ret i32 %a.0.lcssa
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
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
66 for.body.preheader:
67   br label %for.body
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
79 for.end.loopexit:
80   br label %for.end
82 for.end:
83   %a.0.lcssa = phi i32 [ 0, %entry ], [ %add, %for.end.loopexit ]
84   ret i32 %a.0.lcssa
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
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
97 for.body.preheader:
98   br label %for.body
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
108 for.end.loopexit:
109   br label %for.end
111 for.end:
112   ret i32 0
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
120 define void @hwloop5(i32* nocapture %a, i32* nocapture %res) nounwind {
121 entry:
122   br label %for.body
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
135 for.end:
136   ret void
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
145 define void @hwloop6(i32* nocapture %a, i32* nocapture %res) nounwind {
146 entry:
147   br label %for.body
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
159 for.end:
160   ret void