[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / Transforms / InstCombine / fadd.ll
blob24a22dc52ffd457f3ec60a9ee7cd9c16f6029342
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
4 declare void @use(float)
5 declare void @use_vec(<2 x float>)
7 ; -x + y => y - x
9 define float @fneg_op0(float %x, float %y) {
10 ; CHECK-LABEL: @fneg_op0(
11 ; CHECK-NEXT:    [[ADD:%.*]] = fsub float [[Y:%.*]], [[X:%.*]]
12 ; CHECK-NEXT:    ret float [[ADD]]
14   %neg = fsub float -0.0, %x
15   %add = fadd float %neg, %y
16   ret float %add
19 ; x + -y => x - y
21 define float @fneg_op1(float %x, float %y) {
22 ; CHECK-LABEL: @fneg_op1(
23 ; CHECK-NEXT:    [[ADD:%.*]] = fsub float [[X:%.*]], [[Y:%.*]]
24 ; CHECK-NEXT:    ret float [[ADD]]
26   %neg = fsub float -0.0, %y
27   %add = fadd float %x, %neg
28   ret float %add
31 ; Z + (-X / Y) --> Z - (X / Y)
33 define double @fdiv_fneg1(double %x, double %y, double %pz) {
34 ; CHECK-LABEL: @fdiv_fneg1(
35 ; CHECK-NEXT:    [[Z:%.*]] = frem double 4.200000e+01, [[PZ:%.*]]
36 ; CHECK-NEXT:    [[TMP1:%.*]] = fdiv double [[X:%.*]], [[Y:%.*]]
37 ; CHECK-NEXT:    [[R:%.*]] = fsub double [[Z]], [[TMP1]]
38 ; CHECK-NEXT:    ret double [[R]]
40   %z = frem double 42.0, %pz ; thwart complexity-based canonicalization
41   %neg = fsub double -0.000000e+00, %x
42   %div = fdiv double %neg, %y
43   %r = fadd double %z, %div
44   ret double %r
47 ; Z + (Y / -X) --> Z - (Y / X)
49 define <2 x double> @fdiv_fneg2(<2 x double> %x, <2 x double> %y, <2 x double> %pz) {
50 ; CHECK-LABEL: @fdiv_fneg2(
51 ; CHECK-NEXT:    [[Z:%.*]] = frem <2 x double> <double 4.200000e+01, double 8.000000e+00>, [[PZ:%.*]]
52 ; CHECK-NEXT:    [[TMP1:%.*]] = fdiv <2 x double> [[Y:%.*]], [[X:%.*]]
53 ; CHECK-NEXT:    [[R:%.*]] = fsub <2 x double> [[Z]], [[TMP1]]
54 ; CHECK-NEXT:    ret <2 x double> [[R]]
56   %z = frem <2 x double> <double 42.0, double 8.0>, %pz ; thwart complexity-based canonicalization
57   %neg = fsub <2 x double> <double -0.0, double -0.0>, %x
58   %div = fdiv <2 x double> %y, %neg
59   %r = fadd <2 x double> %z, %div
60   ret <2 x double> %r
63 ; Z + (-X * Y) --> Z - (X * Y)
65 define double @fmul_fneg1(double %x, double %y, double %pz) {
66 ; CHECK-LABEL: @fmul_fneg1(
67 ; CHECK-NEXT:    [[Z:%.*]] = frem double 4.200000e+01, [[PZ:%.*]]
68 ; CHECK-NEXT:    [[TMP1:%.*]] = fmul double [[X:%.*]], [[Y:%.*]]
69 ; CHECK-NEXT:    [[R:%.*]] = fsub double [[Z]], [[TMP1]]
70 ; CHECK-NEXT:    ret double [[R]]
72   %z = frem double 42.0, %pz ; thwart complexity-based canonicalization
73   %neg = fsub double -0.000000e+00, %x
74   %mul = fmul double %neg, %y
75   %r = fadd double %z, %mul
76   ret double %r
79 ; Z + (Y * -X) --> Z - (Y * X)
81 define double @fmul_fneg2(double %x, double %py, double %pz) {
82 ; CHECK-LABEL: @fmul_fneg2(
83 ; CHECK-NEXT:    [[Y:%.*]] = frem double -4.200000e+01, [[PY:%.*]]
84 ; CHECK-NEXT:    [[Z:%.*]] = frem double 4.200000e+01, [[PZ:%.*]]
85 ; CHECK-NEXT:    [[TMP1:%.*]] = fmul double [[Y]], [[X:%.*]]
86 ; CHECK-NEXT:    [[R:%.*]] = fsub double [[Z]], [[TMP1]]
87 ; CHECK-NEXT:    ret double [[R]]
89   %y = frem double -42.0, %py ; thwart complexity-based canonicalization
90   %z = frem double 42.0, %pz ; thwart complexity-based canonicalization
91   %neg = fsub double -0.000000e+00, %x
92   %mul = fmul double %y, %neg
93   %r = fadd double %z, %mul
94   ret double %r
97 ; (-X / Y) + Z --> Z - (X / Y)
99 define double @fdiv_fneg1_commute(double %x, double %y, double %pz) {
100 ; CHECK-LABEL: @fdiv_fneg1_commute(
101 ; CHECK-NEXT:    [[Z:%.*]] = frem double 4.200000e+01, [[PZ:%.*]]
102 ; CHECK-NEXT:    [[TMP1:%.*]] = fdiv double [[X:%.*]], [[Y:%.*]]
103 ; CHECK-NEXT:    [[R:%.*]] = fsub double [[Z]], [[TMP1]]
104 ; CHECK-NEXT:    ret double [[R]]
106   %z = frem double 42.0, %pz ; thwart complexity-based canonicalization
107   %neg = fsub double -0.000000e+00, %x
108   %div = fdiv double %neg, %y
109   %r = fadd double %div, %z
110   ret double %r
113 ; (Y / -X) + Z --> Z - (Y / X)
115 define <2 x double> @fdiv_fneg2_commute(<2 x double> %x, <2 x double> %y, <2 x double> %pz) {
116 ; CHECK-LABEL: @fdiv_fneg2_commute(
117 ; CHECK-NEXT:    [[Z:%.*]] = frem <2 x double> <double 4.200000e+01, double 8.000000e+00>, [[PZ:%.*]]
118 ; CHECK-NEXT:    [[TMP1:%.*]] = fdiv <2 x double> [[Y:%.*]], [[X:%.*]]
119 ; CHECK-NEXT:    [[R:%.*]] = fsub <2 x double> [[Z]], [[TMP1]]
120 ; CHECK-NEXT:    ret <2 x double> [[R]]
122   %z = frem <2 x double> <double 42.0, double 8.0>, %pz ; thwart complexity-based canonicalization
123   %neg = fsub <2 x double> <double -0.0, double -0.0>, %x
124   %div = fdiv <2 x double> %y, %neg
125   %r = fadd <2 x double> %div, %z
126   ret <2 x double> %r
129 ; (-X * Y) + Z --> Z - (X * Y)
131 define double @fmul_fneg1_commute(double %x, double %y, double %pz) {
132 ; CHECK-LABEL: @fmul_fneg1_commute(
133 ; CHECK-NEXT:    [[Z:%.*]] = frem double 4.200000e+01, [[PZ:%.*]]
134 ; CHECK-NEXT:    [[TMP1:%.*]] = fmul double [[X:%.*]], [[Y:%.*]]
135 ; CHECK-NEXT:    [[R:%.*]] = fsub double [[Z]], [[TMP1]]
136 ; CHECK-NEXT:    ret double [[R]]
138   %z = frem double 42.0, %pz ; thwart complexity-based canonicalization
139   %neg = fsub double -0.000000e+00, %x
140   %mul = fmul double %neg, %y
141   %r = fadd double %mul, %z
142   ret double %r
145 ; (Y * -X) + Z --> Z - (Y * X)
147 define double @fmul_fneg2_commute(double %x, double %py, double %pz) {
148 ; CHECK-LABEL: @fmul_fneg2_commute(
149 ; CHECK-NEXT:    [[Y:%.*]] = frem double 4.100000e+01, [[PY:%.*]]
150 ; CHECK-NEXT:    [[Z:%.*]] = frem double 4.200000e+01, [[PZ:%.*]]
151 ; CHECK-NEXT:    [[TMP1:%.*]] = fmul double [[Y]], [[X:%.*]]
152 ; CHECK-NEXT:    [[R:%.*]] = fsub double [[Z]], [[TMP1]]
153 ; CHECK-NEXT:    ret double [[R]]
155   %y = frem double 41.0, %py ; thwart complexity-based canonicalization
156   %z = frem double 42.0, %pz ; thwart complexity-based canonicalization
157   %neg = fsub double -0.000000e+00, %x
158   %mul = fmul double %y, %neg
159   %r = fadd double %mul, %z
160   ret double %r
163 ; Z + (-X / Y) - extra use means we can't transform to fsub without an extra instruction
165 define float @fdiv_fneg1_extra_use(float %x, float %y, float %pz) {
166 ; CHECK-LABEL: @fdiv_fneg1_extra_use(
167 ; CHECK-NEXT:    [[Z:%.*]] = frem float 4.200000e+01, [[PZ:%.*]]
168 ; CHECK-NEXT:    [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
169 ; CHECK-NEXT:    [[DIV:%.*]] = fdiv float [[NEG]], [[Y:%.*]]
170 ; CHECK-NEXT:    call void @use(float [[DIV]])
171 ; CHECK-NEXT:    [[R:%.*]] = fadd float [[Z]], [[DIV]]
172 ; CHECK-NEXT:    ret float [[R]]
174   %z = frem float 42.0, %pz ; thwart complexity-based canonicalization
175   %neg = fsub float -0.000000e+00, %x
176   %div = fdiv float %neg, %y
177   call void @use(float %div)
178   %r = fadd float %z, %div
179   ret float %r
182 ; Z + (Y / -X) - extra use means we can't transform to fsub without an extra instruction
184 define float @fdiv_fneg2_extra_use(float %x, float %py, float %pz) {
185 ; CHECK-LABEL: @fdiv_fneg2_extra_use(
186 ; CHECK-NEXT:    [[Y:%.*]] = frem float -4.200000e+01, [[PY:%.*]]
187 ; CHECK-NEXT:    [[Z:%.*]] = frem float 4.200000e+01, [[PZ:%.*]]
188 ; CHECK-NEXT:    [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
189 ; CHECK-NEXT:    [[DIV:%.*]] = fdiv float [[Y]], [[NEG]]
190 ; CHECK-NEXT:    call void @use(float [[DIV]])
191 ; CHECK-NEXT:    [[R:%.*]] = fadd float [[Z]], [[DIV]]
192 ; CHECK-NEXT:    ret float [[R]]
194   %y = frem float -42.0, %py ; thwart complexity-based canonicalization
195   %z = frem float 42.0, %pz ; thwart complexity-based canonicalization
196   %neg = fsub float -0.000000e+00, %x
197   %div = fdiv float %y, %neg
198   call void @use(float %div)
199   %r = fadd float %z, %div
200   ret float %r
203 ; Z + (-X * Y) - extra use means we can't transform to fsub without an extra instruction
205 define <2 x float> @fmul_fneg1_extra_use(<2 x float> %x, <2 x float> %y, <2 x float> %pz) {
206 ; CHECK-LABEL: @fmul_fneg1_extra_use(
207 ; CHECK-NEXT:    [[Z:%.*]] = frem <2 x float> <float 4.200000e+01, float -1.000000e+00>, [[PZ:%.*]]
208 ; CHECK-NEXT:    [[NEG:%.*]] = fsub <2 x float> <float -0.000000e+00, float -0.000000e+00>, [[X:%.*]]
209 ; CHECK-NEXT:    [[MUL:%.*]] = fmul <2 x float> [[NEG]], [[Y:%.*]]
210 ; CHECK-NEXT:    call void @use_vec(<2 x float> [[MUL]])
211 ; CHECK-NEXT:    [[R:%.*]] = fadd <2 x float> [[Z]], [[MUL]]
212 ; CHECK-NEXT:    ret <2 x float> [[R]]
214   %z = frem <2 x float> <float 42.0, float -1.0>, %pz ; thwart complexity-based canonicalization
215   %neg = fsub <2 x float> <float -0.0, float -0.0>, %x
216   %mul = fmul <2 x float> %neg, %y
217   call void @use_vec(<2 x float> %mul)
218   %r = fadd <2 x float> %z, %mul
219   ret <2 x float> %r
222 ; Z + (Y * -X) - extra use means we can't transform to fsub without an extra instruction
224 define float @fmul_fneg2_extra_use(float %x, float %py, float %pz) {
225 ; CHECK-LABEL: @fmul_fneg2_extra_use(
226 ; CHECK-NEXT:    [[Y:%.*]] = frem float -4.200000e+01, [[PY:%.*]]
227 ; CHECK-NEXT:    [[Z:%.*]] = frem float 4.200000e+01, [[PZ:%.*]]
228 ; CHECK-NEXT:    [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
229 ; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[Y]], [[NEG]]
230 ; CHECK-NEXT:    call void @use(float [[MUL]])
231 ; CHECK-NEXT:    [[R:%.*]] = fadd float [[Z]], [[MUL]]
232 ; CHECK-NEXT:    ret float [[R]]
234   %y = frem float -42.0, %py ; thwart complexity-based canonicalization
235   %z = frem float 42.0, %pz ; thwart complexity-based canonicalization
236   %neg = fsub float -0.000000e+00, %x
237   %mul = fmul float %y, %neg
238   call void @use(float %mul)
239   %r = fadd float %z, %mul
240   ret float %r
243 ; (-X / Y) + Z --> Z - (X / Y)
245 define float @fdiv_fneg1_extra_use2(float %x, float %y, float %z) {
246 ; CHECK-LABEL: @fdiv_fneg1_extra_use2(
247 ; CHECK-NEXT:    [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
248 ; CHECK-NEXT:    call void @use(float [[NEG]])
249 ; CHECK-NEXT:    [[TMP1:%.*]] = fdiv float [[X]], [[Y:%.*]]
250 ; CHECK-NEXT:    [[R:%.*]] = fsub float [[Z:%.*]], [[TMP1]]
251 ; CHECK-NEXT:    ret float [[R]]
253   %neg = fsub float -0.000000e+00, %x
254   call void @use(float %neg)
255   %div = fdiv float %neg, %y
256   %r = fadd float %div, %z
257   ret float %r
260 ; (Y / -X) + Z --> Z - (Y / X)
262 define float @fdiv_fneg2_extra_use2(float %x, float %y, float %z) {
263 ; CHECK-LABEL: @fdiv_fneg2_extra_use2(
264 ; CHECK-NEXT:    [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
265 ; CHECK-NEXT:    call void @use(float [[NEG]])
266 ; CHECK-NEXT:    [[TMP1:%.*]] = fdiv float [[Y:%.*]], [[X]]
267 ; CHECK-NEXT:    [[R:%.*]] = fsub float [[Z:%.*]], [[TMP1]]
268 ; CHECK-NEXT:    ret float [[R]]
270   %neg = fsub float -0.000000e+00, %x
271   call void @use(float %neg)
272   %div = fdiv float %y, %neg
273   %r = fadd float %div, %z
274   ret float %r
277 ; (-X * Y) + Z --> Z - (X * Y)
279 define <2 x float> @fmul_fneg1_extra_use2(<2 x float> %x, <2 x float> %y, <2 x float> %z) {
280 ; CHECK-LABEL: @fmul_fneg1_extra_use2(
281 ; CHECK-NEXT:    [[NEG:%.*]] = fsub <2 x float> <float -0.000000e+00, float -0.000000e+00>, [[X:%.*]]
282 ; CHECK-NEXT:    call void @use_vec(<2 x float> [[NEG]])
283 ; CHECK-NEXT:    [[TMP1:%.*]] = fmul <2 x float> [[X]], [[Y:%.*]]
284 ; CHECK-NEXT:    [[R:%.*]] = fsub <2 x float> [[Z:%.*]], [[TMP1]]
285 ; CHECK-NEXT:    ret <2 x float> [[R]]
287   %neg = fsub <2 x float> <float -0.0, float -0.0>, %x
288   call void @use_vec(<2 x float> %neg)
289   %mul = fmul <2 x float> %neg, %y
290   %r = fadd <2 x float> %mul, %z
291   ret <2 x float> %r
294 ; (Y * -X) + Z --> Z - (Y * X)
296 define float @fmul_fneg2_extra_use2(float %x, float %py, float %z) {
297 ; CHECK-LABEL: @fmul_fneg2_extra_use2(
298 ; CHECK-NEXT:    [[Y:%.*]] = frem float -4.200000e+01, [[PY:%.*]]
299 ; CHECK-NEXT:    [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
300 ; CHECK-NEXT:    call void @use(float [[NEG]])
301 ; CHECK-NEXT:    [[TMP1:%.*]] = fmul float [[Y]], [[X]]
302 ; CHECK-NEXT:    [[R:%.*]] = fsub float [[Z:%.*]], [[TMP1]]
303 ; CHECK-NEXT:    ret float [[R]]
305   %y = frem float -42.0, %py ; thwart complexity-based canonicalization
306   %neg = fsub float -0.000000e+00, %x
307   call void @use(float %neg)
308   %mul = fmul float %y, %neg
309   %r = fadd float %mul, %z
310   ret float %r
313 ; (-X / Y) + Z --> Z - (X / Y)
315 define float @fdiv_fneg1_extra_use3(float %x, float %y, float %z) {
316 ; CHECK-LABEL: @fdiv_fneg1_extra_use3(
317 ; CHECK-NEXT:    [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
318 ; CHECK-NEXT:    call void @use(float [[NEG]])
319 ; CHECK-NEXT:    [[DIV:%.*]] = fdiv float [[NEG]], [[Y:%.*]]
320 ; CHECK-NEXT:    call void @use(float [[DIV]])
321 ; CHECK-NEXT:    [[R:%.*]] = fadd float [[DIV]], [[Z:%.*]]
322 ; CHECK-NEXT:    ret float [[R]]
324   %neg = fsub float -0.000000e+00, %x
325   call void @use(float %neg)
326   %div = fdiv float %neg, %y
327   call void @use(float %div)
328   %r = fadd float %div, %z
329   ret float %r
332 ; (Y / -X) + Z --> Z - (Y / X)
334 define float @fdiv_fneg2_extra_use3(float %x, float %y, float %z) {
335 ; CHECK-LABEL: @fdiv_fneg2_extra_use3(
336 ; CHECK-NEXT:    [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
337 ; CHECK-NEXT:    call void @use(float [[NEG]])
338 ; CHECK-NEXT:    [[DIV:%.*]] = fdiv float [[Y:%.*]], [[NEG]]
339 ; CHECK-NEXT:    call void @use(float [[DIV]])
340 ; CHECK-NEXT:    [[R:%.*]] = fadd float [[DIV]], [[Z:%.*]]
341 ; CHECK-NEXT:    ret float [[R]]
343   %neg = fsub float -0.000000e+00, %x
344   call void @use(float %neg)
345   %div = fdiv float %y, %neg
346   call void @use(float %div)
347   %r = fadd float %div, %z
348   ret float %r
351 ; (-X * Y) + Z --> Z - (X * Y)
353 define <2 x float> @fmul_fneg1_extra_use3(<2 x float> %x, <2 x float> %y, <2 x float> %z) {
354 ; CHECK-LABEL: @fmul_fneg1_extra_use3(
355 ; CHECK-NEXT:    [[NEG:%.*]] = fsub <2 x float> <float -0.000000e+00, float -0.000000e+00>, [[X:%.*]]
356 ; CHECK-NEXT:    call void @use_vec(<2 x float> [[NEG]])
357 ; CHECK-NEXT:    [[MUL:%.*]] = fmul <2 x float> [[NEG]], [[Y:%.*]]
358 ; CHECK-NEXT:    call void @use_vec(<2 x float> [[MUL]])
359 ; CHECK-NEXT:    [[R:%.*]] = fadd <2 x float> [[MUL]], [[Z:%.*]]
360 ; CHECK-NEXT:    ret <2 x float> [[R]]
362   %neg = fsub <2 x float> <float -0.0, float -0.0>, %x
363   call void @use_vec(<2 x float> %neg)
364   %mul = fmul <2 x float> %neg, %y
365   call void @use_vec(<2 x float> %mul)
366   %r = fadd <2 x float> %mul, %z
367   ret <2 x float> %r
370 ; (Y * -X) + Z --> Z - (Y * X)
372 define float @fmul_fneg2_extra_use3(float %x, float %py, float %z) {
373 ; CHECK-LABEL: @fmul_fneg2_extra_use3(
374 ; CHECK-NEXT:    [[Y:%.*]] = frem float -4.200000e+01, [[PY:%.*]]
375 ; CHECK-NEXT:    [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
376 ; CHECK-NEXT:    call void @use(float [[NEG]])
377 ; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[Y]], [[NEG]]
378 ; CHECK-NEXT:    call void @use(float [[MUL]])
379 ; CHECK-NEXT:    [[R:%.*]] = fadd float [[MUL]], [[Z:%.*]]
380 ; CHECK-NEXT:    ret float [[R]]
382   %y = frem float -42.0, %py ; thwart complexity-based canonicalization
383   %neg = fsub float -0.000000e+00, %x
384   call void @use(float %neg)
385   %mul = fmul float %y, %neg
386   call void @use(float %mul)
387   %r = fadd float %mul, %z
388   ret float %r