llvm.org GIT mirror llvm / a35ba1f
[InstCombine] add tests for fadd with negated operand; NFC git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@367222 91177308-0d34-0410-b5e6-96231b3b80d8 Sanjay Patel 1 year, 6 days ago
1 changed file(s) with 362 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
11 ; RUN: opt < %s -instcombine -S | FileCheck %s
2
3 declare void @use(float)
4 declare void @use_vec(<2 x float>)
25
36 ; -x + y => y - x
47
2427 ret float %add
2528 }
2629
30 ; Z + (-X / Y) --> Z - (X / Y)
31
32 define double @fdiv_fneg1(double %x, double %y, double %pz) {
33 ; CHECK-LABEL: @fdiv_fneg1(
34 ; CHECK-NEXT: [[Z:%.*]] = frem double 4.200000e+01, [[PZ:%.*]]
35 ; CHECK-NEXT: [[TMP1:%.*]] = fdiv double [[X:%.*]], [[Y:%.*]]
36 ; CHECK-NEXT: [[R:%.*]] = fsub double [[Z]], [[TMP1]]
37 ; CHECK-NEXT: ret double [[R]]
38 ;
39 %z = frem double 42.0, %pz ; thwart complexity-based canonicalization
40 %neg = fsub double -0.000000e+00, %x
41 %div = fdiv double %neg, %y
42 %r = fadd double %z, %div
43 ret double %r
44 }
45
46 ; Z + (Y / -X) --> Z - (Y / X)
47
48 define <2 x double> @fdiv_fneg2(<2 x double> %x, <2 x double> %y, <2 x double> %pz) {
49 ; CHECK-LABEL: @fdiv_fneg2(
50 ; CHECK-NEXT: [[Z:%.*]] = frem <2 x double> , [[PZ:%.*]]
51 ; CHECK-NEXT: [[TMP1:%.*]] = fdiv <2 x double> [[Y:%.*]], [[X:%.*]]
52 ; CHECK-NEXT: [[R:%.*]] = fsub <2 x double> [[Z]], [[TMP1]]
53 ; CHECK-NEXT: ret <2 x double> [[R]]
54 ;
55 %z = frem <2 x double> , %pz ; thwart complexity-based canonicalization
56 %neg = fsub <2 x double> , %x
57 %div = fdiv <2 x double> %y, %neg
58 %r = fadd <2 x double> %z, %div
59 ret <2 x double> %r
60 }
61
62 ; Z + (-X * Y) --> Z - (X * Y)
63
64 define double @fmul_fneg1(double %x, double %y, double %pz) {
65 ; CHECK-LABEL: @fmul_fneg1(
66 ; CHECK-NEXT: [[Z:%.*]] = frem double 4.200000e+01, [[PZ:%.*]]
67 ; CHECK-NEXT: [[TMP1:%.*]] = fmul double [[X:%.*]], [[Y:%.*]]
68 ; CHECK-NEXT: [[R:%.*]] = fsub double [[Z]], [[TMP1]]
69 ; CHECK-NEXT: ret double [[R]]
70 ;
71 %z = frem double 42.0, %pz ; thwart complexity-based canonicalization
72 %neg = fsub double -0.000000e+00, %x
73 %mul = fmul double %neg, %y
74 %r = fadd double %z, %mul
75 ret double %r
76 }
77
78 ; Z + (Y * -X) --> Z - (Y * X)
79
80 define double @fmul_fneg2(double %x, double %py, double %pz) {
81 ; CHECK-LABEL: @fmul_fneg2(
82 ; CHECK-NEXT: [[Y:%.*]] = frem double -4.200000e+01, [[PY:%.*]]
83 ; CHECK-NEXT: [[Z:%.*]] = frem double 4.200000e+01, [[PZ:%.*]]
84 ; CHECK-NEXT: [[TMP1:%.*]] = fmul double [[Y]], [[X:%.*]]
85 ; CHECK-NEXT: [[R:%.*]] = fsub double [[Z]], [[TMP1]]
86 ; CHECK-NEXT: ret double [[R]]
87 ;
88 %y = frem double -42.0, %py ; thwart complexity-based canonicalization
89 %z = frem double 42.0, %pz ; thwart complexity-based canonicalization
90 %neg = fsub double -0.000000e+00, %x
91 %mul = fmul double %y, %neg
92 %r = fadd double %z, %mul
93 ret double %r
94 }
95
96 ; (-X / Y) + Z --> Z - (X / Y)
97
98 define double @fdiv_fneg1_commute(double %x, double %y, double %pz) {
99 ; CHECK-LABEL: @fdiv_fneg1_commute(
100 ; CHECK-NEXT: [[Z:%.*]] = frem double 4.200000e+01, [[PZ:%.*]]
101 ; CHECK-NEXT: [[TMP1:%.*]] = fdiv double [[X:%.*]], [[Y:%.*]]
102 ; CHECK-NEXT: [[R:%.*]] = fsub double [[Z]], [[TMP1]]
103 ; CHECK-NEXT: ret double [[R]]
104 ;
105 %z = frem double 42.0, %pz ; thwart complexity-based canonicalization
106 %neg = fsub double -0.000000e+00, %x
107 %div = fdiv double %neg, %y
108 %r = fadd double %div, %z
109 ret double %r
110 }
111
112 ; (Y / -X) + Z --> Z - (Y / X)
113
114 define <2 x double> @fdiv_fneg2_commute(<2 x double> %x, <2 x double> %y, <2 x double> %pz) {
115 ; CHECK-LABEL: @fdiv_fneg2_commute(
116 ; CHECK-NEXT: [[Z:%.*]] = frem <2 x double> , [[PZ:%.*]]
117 ; CHECK-NEXT: [[TMP1:%.*]] = fdiv <2 x double> [[Y:%.*]], [[X:%.*]]
118 ; CHECK-NEXT: [[R:%.*]] = fsub <2 x double> [[Z]], [[TMP1]]
119 ; CHECK-NEXT: ret <2 x double> [[R]]
120 ;
121 %z = frem <2 x double> , %pz ; thwart complexity-based canonicalization
122 %neg = fsub <2 x double> , %x
123 %div = fdiv <2 x double> %y, %neg
124 %r = fadd <2 x double> %div, %z
125 ret <2 x double> %r
126 }
127
128 ; (-X * Y) + Z --> Z - (X * Y)
129
130 define double @fmul_fneg1_commute(double %x, double %y, double %pz) {
131 ; CHECK-LABEL: @fmul_fneg1_commute(
132 ; CHECK-NEXT: [[Z:%.*]] = frem double 4.200000e+01, [[PZ:%.*]]
133 ; CHECK-NEXT: [[TMP1:%.*]] = fmul double [[X:%.*]], [[Y:%.*]]
134 ; CHECK-NEXT: [[R:%.*]] = fsub double [[Z]], [[TMP1]]
135 ; CHECK-NEXT: ret double [[R]]
136 ;
137 %z = frem double 42.0, %pz ; thwart complexity-based canonicalization
138 %neg = fsub double -0.000000e+00, %x
139 %mul = fmul double %neg, %y
140 %r = fadd double %mul, %z
141 ret double %r
142 }
143
144 ; (Y * -X) + Z --> Z - (Y * X)
145
146 define double @fmul_fneg2_commute(double %x, double %py, double %pz) {
147 ; CHECK-LABEL: @fmul_fneg2_commute(
148 ; CHECK-NEXT: [[Y:%.*]] = frem double 4.100000e+01, [[PY:%.*]]
149 ; CHECK-NEXT: [[Z:%.*]] = frem double 4.200000e+01, [[PZ:%.*]]
150 ; CHECK-NEXT: [[TMP1:%.*]] = fmul double [[Y]], [[X:%.*]]
151 ; CHECK-NEXT: [[R:%.*]] = fsub double [[Z]], [[TMP1]]
152 ; CHECK-NEXT: ret double [[R]]
153 ;
154 %y = frem double 41.0, %py ; thwart complexity-based canonicalization
155 %z = frem double 42.0, %pz ; thwart complexity-based canonicalization
156 %neg = fsub double -0.000000e+00, %x
157 %mul = fmul double %y, %neg
158 %r = fadd double %mul, %z
159 ret double %r
160 }
161
162 ; Z + (-X / Y) --> Z - (X / Y)
163
164 define float @fdiv_fneg1_extra_use(float %x, float %y, float %pz) {
165 ; CHECK-LABEL: @fdiv_fneg1_extra_use(
166 ; CHECK-NEXT: [[Z:%.*]] = frem float 4.200000e+01, [[PZ:%.*]]
167 ; CHECK-NEXT: [[TMP1:%.*]] = fdiv float [[X:%.*]], [[Y:%.*]]
168 ; CHECK-NEXT: [[DIV:%.*]] = fsub float -0.000000e+00, [[TMP1]]
169 ; CHECK-NEXT: call void @use(float [[DIV]])
170 ; CHECK-NEXT: [[R:%.*]] = fsub float [[Z]], [[TMP1]]
171 ; CHECK-NEXT: ret float [[R]]
172 ;
173 %z = frem float 42.0, %pz ; thwart complexity-based canonicalization
174 %neg = fsub float -0.000000e+00, %x
175 %div = fdiv float %neg, %y
176 call void @use(float %div)
177 %r = fadd float %z, %div
178 ret float %r
179 }
180
181 ; Z + (Y / -X) --> Z - (Y / X)
182
183 define float @fdiv_fneg2_extra_use(float %x, float %py, float %pz) {
184 ; CHECK-LABEL: @fdiv_fneg2_extra_use(
185 ; CHECK-NEXT: [[Y:%.*]] = frem float -4.200000e+01, [[PY:%.*]]
186 ; CHECK-NEXT: [[Z:%.*]] = frem float 4.200000e+01, [[PZ:%.*]]
187 ; CHECK-NEXT: [[TMP1:%.*]] = fdiv float [[Y]], [[X:%.*]]
188 ; CHECK-NEXT: [[DIV:%.*]] = fsub float -0.000000e+00, [[TMP1]]
189 ; CHECK-NEXT: call void @use(float [[DIV]])
190 ; CHECK-NEXT: [[R:%.*]] = fsub float [[Z]], [[TMP1]]
191 ; CHECK-NEXT: ret float [[R]]
192 ;
193 %y = frem float -42.0, %py ; thwart complexity-based canonicalization
194 %z = frem float 42.0, %pz ; thwart complexity-based canonicalization
195 %neg = fsub float -0.000000e+00, %x
196 %div = fdiv float %y, %neg
197 call void @use(float %div)
198 %r = fadd float %z, %div
199 ret float %r
200 }
201
202 ; Z + (-X * Y) --> Z - (X * Y)
203
204 define <2 x float> @fmul_fneg1_extra_use(<2 x float> %x, <2 x float> %y, <2 x float> %pz) {
205 ; CHECK-LABEL: @fmul_fneg1_extra_use(
206 ; CHECK-NEXT: [[Z:%.*]] = frem <2 x float> , [[PZ:%.*]]
207 ; CHECK-NEXT: [[TMP1:%.*]] = fmul <2 x float> [[X:%.*]], [[Y:%.*]]
208 ; CHECK-NEXT: [[MUL:%.*]] = fsub <2 x float> , [[TMP1]]
209 ; CHECK-NEXT: call void @use_vec(<2 x float> [[MUL]])
210 ; CHECK-NEXT: [[R:%.*]] = fsub <2 x float> [[Z]], [[TMP1]]
211 ; CHECK-NEXT: ret <2 x float> [[R]]
212 ;
213 %z = frem <2 x float> , %pz ; thwart complexity-based canonicalization
214 %neg = fsub <2 x float> , %x
215 %mul = fmul <2 x float> %neg, %y
216 call void @use_vec(<2 x float> %mul)
217 %r = fadd <2 x float> %z, %mul
218 ret <2 x float> %r
219 }
220
221 ; Z + (Y * -X) --> Z - (Y * X)
222
223 define float @fmul_fneg2_extra_use(float %x, float %py, float %pz) {
224 ; CHECK-LABEL: @fmul_fneg2_extra_use(
225 ; CHECK-NEXT: [[Y:%.*]] = frem float -4.200000e+01, [[PY:%.*]]
226 ; CHECK-NEXT: [[Z:%.*]] = frem float 4.200000e+01, [[PZ:%.*]]
227 ; CHECK-NEXT: [[TMP1:%.*]] = fmul float [[Y]], [[X:%.*]]
228 ; CHECK-NEXT: [[MUL:%.*]] = fsub float -0.000000e+00, [[TMP1]]
229 ; CHECK-NEXT: call void @use(float [[MUL]])
230 ; CHECK-NEXT: [[R:%.*]] = fsub float [[Z]], [[TMP1]]
231 ; CHECK-NEXT: ret float [[R]]
232 ;
233 %y = frem float -42.0, %py ; thwart complexity-based canonicalization
234 %z = frem float 42.0, %pz ; thwart complexity-based canonicalization
235 %neg = fsub float -0.000000e+00, %x
236 %mul = fmul float %y, %neg
237 call void @use(float %mul)
238 %r = fadd float %z, %mul
239 ret float %r
240 }
241
242 ; (-X / Y) + Z --> Z - (X / Y)
243
244 define float @fdiv_fneg1_extra_use2(float %x, float %y, float %z) {
245 ; CHECK-LABEL: @fdiv_fneg1_extra_use2(
246 ; CHECK-NEXT: [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
247 ; CHECK-NEXT: call void @use(float [[NEG]])
248 ; CHECK-NEXT: [[DIV:%.*]] = fdiv float [[NEG]], [[Y:%.*]]
249 ; CHECK-NEXT: [[R:%.*]] = fadd float [[DIV]], [[Z:%.*]]
250 ; CHECK-NEXT: ret float [[R]]
251 ;
252 %neg = fsub float -0.000000e+00, %x
253 call void @use(float %neg)
254 %div = fdiv float %neg, %y
255 %r = fadd float %div, %z
256 ret float %r
257 }
258
259 ; (Y / -X) + Z --> Z - (Y / X)
260
261 define float @fdiv_fneg2_extra_use2(float %x, float %y, float %z) {
262 ; CHECK-LABEL: @fdiv_fneg2_extra_use2(
263 ; CHECK-NEXT: [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
264 ; CHECK-NEXT: call void @use(float [[NEG]])
265 ; CHECK-NEXT: [[DIV:%.*]] = fdiv float [[Y:%.*]], [[NEG]]
266 ; CHECK-NEXT: [[R:%.*]] = fadd float [[DIV]], [[Z:%.*]]
267 ; CHECK-NEXT: ret float [[R]]
268 ;
269 %neg = fsub float -0.000000e+00, %x
270 call void @use(float %neg)
271 %div = fdiv float %y, %neg
272 %r = fadd float %div, %z
273 ret float %r
274 }
275
276 ; (-X * Y) + Z --> Z - (X * Y)
277
278 define <2 x float> @fmul_fneg1_extra_use2(<2 x float> %x, <2 x float> %y, <2 x float> %z) {
279 ; CHECK-LABEL: @fmul_fneg1_extra_use2(
280 ; CHECK-NEXT: [[NEG:%.*]] = fsub <2 x float> , [[X:%.*]]
281 ; CHECK-NEXT: call void @use_vec(<2 x float> [[NEG]])
282 ; CHECK-NEXT: [[MUL:%.*]] = fmul <2 x float> [[NEG]], [[Y:%.*]]
283 ; CHECK-NEXT: [[R:%.*]] = fadd <2 x float> [[MUL]], [[Z:%.*]]
284 ; CHECK-NEXT: ret <2 x float> [[R]]
285 ;
286 %neg = fsub <2 x float> , %x
287 call void @use_vec(<2 x float> %neg)
288 %mul = fmul <2 x float> %neg, %y
289 %r = fadd <2 x float> %mul, %z
290 ret <2 x float> %r
291 }
292
293 ; (Y * -X) + Z --> Z - (Y * X)
294
295 define float @fmul_fneg2_extra_use2(float %x, float %py, float %z) {
296 ; CHECK-LABEL: @fmul_fneg2_extra_use2(
297 ; CHECK-NEXT: [[Y:%.*]] = frem float -4.200000e+01, [[PY:%.*]]
298 ; CHECK-NEXT: [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
299 ; CHECK-NEXT: call void @use(float [[NEG]])
300 ; CHECK-NEXT: [[MUL:%.*]] = fmul float [[Y]], [[NEG]]
301 ; CHECK-NEXT: [[R:%.*]] = fadd float [[MUL]], [[Z:%.*]]
302 ; CHECK-NEXT: ret float [[R]]
303 ;
304 %y = frem float -42.0, %py ; thwart complexity-based canonicalization
305 %neg = fsub float -0.000000e+00, %x
306 call void @use(float %neg)
307 %mul = fmul float %y, %neg
308 %r = fadd float %mul, %z
309 ret float %r
310 }
311
312 ; (-X / Y) + Z --> Z - (X / Y)
313
314 define float @fdiv_fneg1_extra_use3(float %x, float %y, float %z) {
315 ; CHECK-LABEL: @fdiv_fneg1_extra_use3(
316 ; CHECK-NEXT: [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
317 ; CHECK-NEXT: call void @use(float [[NEG]])
318 ; CHECK-NEXT: [[DIV:%.*]] = fdiv float [[NEG]], [[Y:%.*]]
319 ; CHECK-NEXT: call void @use(float [[DIV]])
320 ; CHECK-NEXT: [[R:%.*]] = fadd float [[DIV]], [[Z:%.*]]
321 ; CHECK-NEXT: ret float [[R]]
322 ;
323 %neg = fsub float -0.000000e+00, %x
324 call void @use(float %neg)
325 %div = fdiv float %neg, %y
326 call void @use(float %div)
327 %r = fadd float %div, %z
328 ret float %r
329 }
330
331 ; (Y / -X) + Z --> Z - (Y / X)
332
333 define float @fdiv_fneg2_extra_use3(float %x, float %y, float %z) {
334 ; CHECK-LABEL: @fdiv_fneg2_extra_use3(
335 ; CHECK-NEXT: [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
336 ; CHECK-NEXT: call void @use(float [[NEG]])
337 ; CHECK-NEXT: [[DIV:%.*]] = fdiv float [[Y:%.*]], [[NEG]]
338 ; CHECK-NEXT: call void @use(float [[DIV]])
339 ; CHECK-NEXT: [[R:%.*]] = fadd float [[DIV]], [[Z:%.*]]
340 ; CHECK-NEXT: ret float [[R]]
341 ;
342 %neg = fsub float -0.000000e+00, %x
343 call void @use(float %neg)
344 %div = fdiv float %y, %neg
345 call void @use(float %div)
346 %r = fadd float %div, %z
347 ret float %r
348 }
349
350 ; (-X * Y) + Z --> Z - (X * Y)
351
352 define <2 x float> @fmul_fneg1_extra_use3(<2 x float> %x, <2 x float> %y, <2 x float> %z) {
353 ; CHECK-LABEL: @fmul_fneg1_extra_use3(
354 ; CHECK-NEXT: [[NEG:%.*]] = fsub <2 x float> , [[X:%.*]]
355 ; CHECK-NEXT: call void @use_vec(<2 x float> [[NEG]])
356 ; CHECK-NEXT: [[MUL:%.*]] = fmul <2 x float> [[NEG]], [[Y:%.*]]
357 ; CHECK-NEXT: call void @use_vec(<2 x float> [[MUL]])
358 ; CHECK-NEXT: [[R:%.*]] = fadd <2 x float> [[MUL]], [[Z:%.*]]
359 ; CHECK-NEXT: ret <2 x float> [[R]]
360 ;
361 %neg = fsub <2 x float> , %x
362 call void @use_vec(<2 x float> %neg)
363 %mul = fmul <2 x float> %neg, %y
364 call void @use_vec(<2 x float> %mul)
365 %r = fadd <2 x float> %mul, %z
366 ret <2 x float> %r
367 }
368
369 ; (Y * -X) + Z --> Z - (Y * X)
370
371 define float @fmul_fneg2_extra_use3(float %x, float %py, float %z) {
372 ; CHECK-LABEL: @fmul_fneg2_extra_use3(
373 ; CHECK-NEXT: [[Y:%.*]] = frem float -4.200000e+01, [[PY:%.*]]
374 ; CHECK-NEXT: [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
375 ; CHECK-NEXT: call void @use(float [[NEG]])
376 ; CHECK-NEXT: [[MUL:%.*]] = fmul float [[Y]], [[NEG]]
377 ; CHECK-NEXT: call void @use(float [[MUL]])
378 ; CHECK-NEXT: [[R:%.*]] = fadd float [[MUL]], [[Z:%.*]]
379 ; CHECK-NEXT: ret float [[R]]
380 ;
381 %y = frem float -42.0, %py ; thwart complexity-based canonicalization
382 %neg = fsub float -0.000000e+00, %x
383 call void @use(float %neg)
384 %mul = fmul float %y, %neg
385 call void @use(float %mul)
386 %r = fadd float %mul, %z
387 ret float %r
388 }