blob: 3c190687e08675cd2568e33f072fae2022a3e0f5 [file] [log] [blame]
Sam Parker4c4ff132019-03-14 11:14:13 +00001; RUN: llc -O3 -mtriple=arm-arm-eabi -mcpu=cortex-m33 < %s | FileCheck %s
2
3; CHECK-LABEL: add_user
4; CHECK: %for.body
5; CHECK: ldr [[A:r[0-9]+]],{{.*}}, #2]!
6; CHECK: ldr [[B:r[0-9]+]],{{.*}}, #2]!
7; CHECK: smlad [[ACC:r[0-9]+]], [[B]], [[A]], [[ACC]]
8; CHECK: sxtah [[COUNT:r[0-9]+]], [[COUNT]], [[A]]
9define i32 @add_user(i32 %arg, i32* nocapture readnone %arg1, i16* nocapture readonly %arg2, i16* nocapture readonly %arg3) {
10entry:
11 %cmp24 = icmp sgt i32 %arg, 0
12 br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup
13
14for.body.preheader:
15 %.pre = load i16, i16* %arg3, align 2
16 %.pre27 = load i16, i16* %arg2, align 2
17 br label %for.body
18
19for.cond.cleanup:
20 %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ]
21 %count.final = phi i32 [ 0, %entry ], [ %count.next, %for.body ]
22 %res = add i32 %mac1.0.lcssa, %count.final
23 ret i32 %res
24
25for.body:
26 %mac1.026 = phi i32 [ %add11, %for.body ], [ 0, %for.body.preheader ]
27 %i.025 = phi i32 [ %add, %for.body ], [ 0, %for.body.preheader ]
28 %count = phi i32 [ %count.next, %for.body ], [ 0, %for.body.preheader ]
29 %arrayidx = getelementptr inbounds i16, i16* %arg3, i32 %i.025
30 %0 = load i16, i16* %arrayidx, align 2
31 %add = add nuw nsw i32 %i.025, 1
32 %arrayidx1 = getelementptr inbounds i16, i16* %arg3, i32 %add
33 %1 = load i16, i16* %arrayidx1, align 2
34 %arrayidx3 = getelementptr inbounds i16, i16* %arg2, i32 %i.025
35 %2 = load i16, i16* %arrayidx3, align 2
36 %conv = sext i16 %2 to i32
37 %conv4 = sext i16 %0 to i32
38 %count.next = add i32 %conv4, %count
39 %mul = mul nsw i32 %conv, %conv4
40 %arrayidx6 = getelementptr inbounds i16, i16* %arg2, i32 %add
41 %3 = load i16, i16* %arrayidx6, align 2
42 %conv7 = sext i16 %3 to i32
43 %conv8 = sext i16 %1 to i32
44 %mul9 = mul nsw i32 %conv7, %conv8
45 %add10 = add i32 %mul, %mac1.026
46 %add11 = add i32 %mul9, %add10
47 %exitcond = icmp ne i32 %add, %arg
48 br i1 %exitcond, label %for.body, label %for.cond.cleanup
49}
50
51; CHECK-LABEL: mul_bottom_user
52; CHECK: %for.body
53; CHECK: ldr [[A:r[0-9]+]],{{.*}}, #2]!
54; CHECK: ldr [[B:r[0-9]+]],{{.*}}, #2]!
55; CHECK: smlad [[ACC:r[0-9]+]], [[B]], [[A]], [[ACC]]
56; CHECK: sxth [[SXT:r[0-9]+]], [[A]]
57; CHECK: mul [[COUNT:r[0-9]+]], [[SXT]], [[COUNT]]
58define i32 @mul_bottom_user(i32 %arg, i32* nocapture readnone %arg1, i16* nocapture readonly %arg2, i16* nocapture readonly %arg3) {
59entry:
60 %cmp24 = icmp sgt i32 %arg, 0
61 br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup
62
63for.body.preheader:
64 %.pre = load i16, i16* %arg3, align 2
65 %.pre27 = load i16, i16* %arg2, align 2
66 br label %for.body
67
68for.cond.cleanup:
69 %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ]
70 %count.final = phi i32 [ 0, %entry ], [ %count.next, %for.body ]
71 %res = add i32 %mac1.0.lcssa, %count.final
72 ret i32 %res
73
74for.body:
75 %mac1.026 = phi i32 [ %add11, %for.body ], [ 0, %for.body.preheader ]
76 %i.025 = phi i32 [ %add, %for.body ], [ 0, %for.body.preheader ]
77 %count = phi i32 [ %count.next, %for.body ], [ 0, %for.body.preheader ]
78 %arrayidx = getelementptr inbounds i16, i16* %arg3, i32 %i.025
79 %0 = load i16, i16* %arrayidx, align 2
80 %add = add nuw nsw i32 %i.025, 1
81 %arrayidx1 = getelementptr inbounds i16, i16* %arg3, i32 %add
82 %1 = load i16, i16* %arrayidx1, align 2
83 %arrayidx3 = getelementptr inbounds i16, i16* %arg2, i32 %i.025
84 %2 = load i16, i16* %arrayidx3, align 2
85 %conv = sext i16 %2 to i32
86 %conv4 = sext i16 %0 to i32
87 %mul = mul nsw i32 %conv, %conv4
88 %arrayidx6 = getelementptr inbounds i16, i16* %arg2, i32 %add
89 %3 = load i16, i16* %arrayidx6, align 2
90 %conv7 = sext i16 %3 to i32
91 %conv8 = sext i16 %1 to i32
92 %mul9 = mul nsw i32 %conv7, %conv8
93 %add10 = add i32 %mul, %mac1.026
94 %add11 = add i32 %mul9, %add10
95 %count.next = mul i32 %conv4, %count
96 %exitcond = icmp ne i32 %add, %arg
97 br i1 %exitcond, label %for.body, label %for.cond.cleanup
98}
99
100; CHECK-LABEL: mul_top_user
101; CHECK: %for.body
102; CHECK: ldr [[A:[rl0-9]+]],{{.*}}, #2]!
103; CHECK: ldr [[B:[rl0-9]+]],{{.*}}, #2]!
104; CHECK: smlad [[ACC:[rl0-9]+]], [[B]], [[A]], [[ACC]]
105; CHECK: asr.w [[ASR:[rl0-9]+]], [[ASR]], #16
106; CHECK: mul [[COUNT:[rl0-9]+]], [[ASR]], [[COUNT]]
107define i32 @mul_top_user(i32 %arg, i32* nocapture readnone %arg1, i16* nocapture readonly %arg2, i16* nocapture readonly %arg3) {
108entry:
109 %cmp24 = icmp sgt i32 %arg, 0
110 br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup
111
112for.body.preheader:
113 %.pre = load i16, i16* %arg3, align 2
114 %.pre27 = load i16, i16* %arg2, align 2
115 br label %for.body
116
117for.cond.cleanup:
118 %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ]
119 %count.final = phi i32 [ 0, %entry ], [ %count.next, %for.body ]
120 %res = add i32 %mac1.0.lcssa, %count.final
121 ret i32 %res
122
123for.body:
124 %mac1.026 = phi i32 [ %add11, %for.body ], [ 0, %for.body.preheader ]
125 %i.025 = phi i32 [ %add, %for.body ], [ 0, %for.body.preheader ]
126 %count = phi i32 [ %count.next, %for.body ], [ 0, %for.body.preheader ]
127 %arrayidx = getelementptr inbounds i16, i16* %arg3, i32 %i.025
128 %0 = load i16, i16* %arrayidx, align 2
129 %add = add nuw nsw i32 %i.025, 1
130 %arrayidx1 = getelementptr inbounds i16, i16* %arg3, i32 %add
131 %1 = load i16, i16* %arrayidx1, align 2
132 %arrayidx3 = getelementptr inbounds i16, i16* %arg2, i32 %i.025
133 %2 = load i16, i16* %arrayidx3, align 2
134 %conv = sext i16 %2 to i32
135 %conv4 = sext i16 %0 to i32
136 %mul = mul nsw i32 %conv, %conv4
137 %arrayidx6 = getelementptr inbounds i16, i16* %arg2, i32 %add
138 %3 = load i16, i16* %arrayidx6, align 2
139 %conv7 = sext i16 %3 to i32
140 %conv8 = sext i16 %1 to i32
141 %mul9 = mul nsw i32 %conv7, %conv8
142 %add10 = add i32 %mul, %mac1.026
143 %add11 = add i32 %mul9, %add10
144 %count.next = mul i32 %conv7, %count
145 %exitcond = icmp ne i32 %add, %arg
146 br i1 %exitcond, label %for.body, label %for.cond.cleanup
147}
148
149; CHECK-LABEL: and_user
150; CHECK: %for.body
151; CHECK: ldr [[A:r[0-9]+]],{{.*}}, #2]!
152; CHECK: ldr [[B:r[0-9]+]],{{.*}}, #2]!
153; CHECK: smlad [[ACC:r[0-9]+]], [[B]], [[A]], [[ACC]]
154; CHECK: uxth [[UXT:r[0-9]+]], [[A]]
155; CHECK: mul [[MUL:r[0-9]+]], [[UXT]], [[MUL]]
156define i32 @and_user(i32 %arg, i32* nocapture readnone %arg1, i16* nocapture readonly %arg2, i16* nocapture readonly %arg3) {
157entry:
158 %cmp24 = icmp sgt i32 %arg, 0
159 br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup
160
161for.body.preheader:
162 %.pre = load i16, i16* %arg3, align 2
163 %.pre27 = load i16, i16* %arg2, align 2
164 br label %for.body
165
166for.cond.cleanup:
167 %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ]
168 %count.final = phi i32 [ 0, %entry ], [ %count.next, %for.body ]
169 %res = add i32 %mac1.0.lcssa, %count.final
170 ret i32 %res
171
172for.body:
173 %mac1.026 = phi i32 [ %add11, %for.body ], [ 0, %for.body.preheader ]
174 %i.025 = phi i32 [ %add, %for.body ], [ 0, %for.body.preheader ]
175 %count = phi i32 [ %count.next, %for.body ], [ 0, %for.body.preheader ]
176 %arrayidx = getelementptr inbounds i16, i16* %arg3, i32 %i.025
177 %0 = load i16, i16* %arrayidx, align 2
178 %add = add nuw nsw i32 %i.025, 1
179 %arrayidx1 = getelementptr inbounds i16, i16* %arg3, i32 %add
180 %arrayidx3 = getelementptr inbounds i16, i16* %arg2, i32 %i.025
181 %arrayidx6 = getelementptr inbounds i16, i16* %arg2, i32 %add
182 %1 = load i16, i16* %arrayidx1, align 2
183 %2 = load i16, i16* %arrayidx3, align 2
184 %conv = sext i16 %2 to i32
185 %conv4 = sext i16 %0 to i32
186 %bottom = and i32 %conv4, 65535
187 %mul = mul nsw i32 %conv, %conv4
188 %3 = load i16, i16* %arrayidx6, align 2
189 %conv7 = sext i16 %3 to i32
190 %conv8 = sext i16 %1 to i32
191 %mul9 = mul nsw i32 %conv7, %conv8
192 %add10 = add i32 %mul, %mac1.026
193 %add11 = add i32 %mul9, %add10
194 %count.next = mul i32 %bottom, %count
195 %exitcond = icmp ne i32 %add, %arg
196 br i1 %exitcond, label %for.body, label %for.cond.cleanup
197}
198
199; CHECK-LABEL: multi_uses
200; CHECK: %for.body
201; CHECK: ldr [[A:r[0-9]+]], [{{.*}}, #2]!
202; CHECK: ldr [[B:r[0-9]+]], [{{.*}}, #2]!
203; CHECK: smlad [[ACC:[rl0-9]+]], [[B]], [[A]], [[ACC]]
204; CHECK: sxth [[SXT:r[0-9]+]], [[A]]
205; CHECK: eor.w [[EOR:r[0-9]+]], [[SXT]], [[SHIFT:r[0-9]+]]
206; CHECK: mul [[MUL:r[0-9]+]], [[EOR]], [[SXT]]
207; CHECK: lsl.w [[SHIFT]], [[MUL]], #16
208define i32 @multi_uses(i32 %arg, i32* nocapture readnone %arg1, i16* nocapture readonly %arg2, i16* nocapture readonly %arg3) {
209entry:
210 %cmp24 = icmp sgt i32 %arg, 0
211 br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup
212
213for.body.preheader:
214 %.pre = load i16, i16* %arg3, align 2
215 %.pre27 = load i16, i16* %arg2, align 2
216 br label %for.body
217
218for.cond.cleanup:
219 %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ]
220 %count.final = phi i32 [ 0, %entry ], [ %count.next, %for.body ]
221 %res = add i32 %mac1.0.lcssa, %count.final
222 ret i32 %res
223
224for.body:
225 %mac1.026 = phi i32 [ %add11, %for.body ], [ 0, %for.body.preheader ]
226 %i.025 = phi i32 [ %add, %for.body ], [ 0, %for.body.preheader ]
227 %count = phi i32 [ %count.next, %for.body ], [ 0, %for.body.preheader ]
228 %arrayidx = getelementptr inbounds i16, i16* %arg3, i32 %i.025
229 %0 = load i16, i16* %arrayidx, align 2
230 %add = add nuw nsw i32 %i.025, 1
231 %arrayidx1 = getelementptr inbounds i16, i16* %arg3, i32 %add
232 %arrayidx3 = getelementptr inbounds i16, i16* %arg2, i32 %i.025
233 %arrayidx6 = getelementptr inbounds i16, i16* %arg2, i32 %add
234 %1 = load i16, i16* %arrayidx1, align 2
235 %2 = load i16, i16* %arrayidx3, align 2
236 %conv = sext i16 %2 to i32
237 %conv4 = sext i16 %0 to i32
238 %bottom = and i32 %conv4, 65535
239 %mul = mul nsw i32 %conv, %conv4
240 %3 = load i16, i16* %arrayidx6, align 2
241 %conv7 = sext i16 %3 to i32
242 %conv8 = sext i16 %1 to i32
243 %mul9 = mul nsw i32 %conv7, %conv8
244 %add10 = add i32 %mul, %mac1.026
245 %shl = shl i32 %conv4, 16
246 %add11 = add i32 %mul9, %add10
247 %xor = xor i32 %bottom, %count
248 %count.next = mul i32 %xor, %shl
249 %exitcond = icmp ne i32 %add, %arg
250 br i1 %exitcond, label %for.body, label %for.cond.cleanup
251}