[ARM] Adjust how NEON shifts are lowered
[llvm-core.git] / test / CodeGen / X86 / fadd-combines.ll
blobfdd83dacd707467e56816272ea56b40ed25e873f
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=x86_64-unknown-unknown < %s | FileCheck %s
4 define float @fadd_zero_f32(float %x) #0 {
5 ; CHECK-LABEL: fadd_zero_f32:
6 ; CHECK:       # %bb.0:
7 ; CHECK-NEXT:    retq
8   %y = fadd float %x, 0.0
9   ret float %y
12 define <4 x float> @fadd_zero_4f32(<4 x float> %x) #0 {
13 ; CHECK-LABEL: fadd_zero_4f32:
14 ; CHECK:       # %bb.0:
15 ; CHECK-NEXT:    retq
16   %y = fadd <4 x float> %x, zeroinitializer
17   ret <4 x float> %y
20 define <4 x float> @fadd_zero_4f32_undef(<4 x float> %x) {
21 ; CHECK-LABEL: fadd_zero_4f32_undef:
22 ; CHECK:       # %bb.0:
23 ; CHECK-NEXT:    retq
24   %y = fadd nsz <4 x float> %x, <float 0.0, float undef, float 0.0, float undef>
25   ret <4 x float> %y
28 ; CHECK: float 3
29 define float @fadd_2const_f32(float %x) #0 {
30 ; CHECK-LABEL: fadd_2const_f32:
31 ; CHECK:       # %bb.0:
32 ; CHECK-NEXT:    addss {{.*}}(%rip), %xmm0
33 ; CHECK-NEXT:    retq
34   %y = fadd float %x, 1.0
35   %z = fadd float %y, 2.0
36   ret float %z
39 ; CHECK: float 5
40 ; CHECK: float 5
41 ; CHECK: float 5
42 ; CHECK: float 5
43 define <4 x float> @fadd_2const_4f32(<4 x float> %x) #0 {
44 ; CHECK-LABEL: fadd_2const_4f32:
45 ; CHECK:       # %bb.0:
46 ; CHECK-NEXT:    addps {{.*}}(%rip), %xmm0
47 ; CHECK-NEXT:    retq
48   %y = fadd <4 x float> %x, <float 1.0, float 2.0, float 3.0, float 4.0>
49   %z = fadd <4 x float> %y, <float 4.0, float 3.0, float 2.0, float 1.0>
50   ret <4 x float> %z
53 ; CHECK: float 3
54 define float @fadd_x_fmul_x_c_f32(float %x) #0 {
55 ; CHECK-LABEL: fadd_x_fmul_x_c_f32:
56 ; CHECK:       # %bb.0:
57 ; CHECK-NEXT:    mulss {{.*}}(%rip), %xmm0
58 ; CHECK-NEXT:    retq
59   %y = fmul float %x, 2.0
60   %z = fadd float %x, %y
61   ret float %z
64 ; CHECK: float 2
65 ; CHECK: float 3
66 ; CHECK: float 4
67 ; CHECK: float 5
68 define <4 x float> @fadd_x_fmul_x_c_4f32(<4 x float> %x) #0 {
69 ; CHECK-LABEL: fadd_x_fmul_x_c_4f32:
70 ; CHECK:       # %bb.0:
71 ; CHECK-NEXT:    mulps {{.*}}(%rip), %xmm0
72 ; CHECK-NEXT:    retq
73   %y = fmul <4 x float> %x, <float 1.0, float 2.0, float 3.0, float 4.0>
74   %z = fadd <4 x float> %x, %y
75   ret <4 x float> %z
78 ; CHECK: float 3
79 define float @fadd_fmul_x_c_x_f32(float %x) #0 {
80 ; CHECK-LABEL: fadd_fmul_x_c_x_f32:
81 ; CHECK:       # %bb.0:
82 ; CHECK-NEXT:    mulss {{.*}}(%rip), %xmm0
83 ; CHECK-NEXT:    retq
84   %y = fmul float %x, 2.0
85   %z = fadd float %y, %x
86   ret float %z
89 ; CHECK: float 2
90 ; CHECK: float 3
91 ; CHECK: float 4
92 ; CHECK: float 5
93 define <4 x float> @fadd_fmul_x_c_x_4f32(<4 x float> %x) #0 {
94 ; CHECK-LABEL: fadd_fmul_x_c_x_4f32:
95 ; CHECK:       # %bb.0:
96 ; CHECK-NEXT:    mulps {{.*}}(%rip), %xmm0
97 ; CHECK-NEXT:    retq
98   %y = fmul <4 x float> %x, <float 1.0, float 2.0, float 3.0, float 4.0>
99   %z = fadd <4 x float> %y, %x
100   ret <4 x float> %z
103 ; CHECK: float 4
104 define float @fadd_fadd_x_x_fmul_x_c_f32(float %x) #0 {
105 ; CHECK-LABEL: fadd_fadd_x_x_fmul_x_c_f32:
106 ; CHECK:       # %bb.0:
107 ; CHECK-NEXT:    mulss {{.*}}(%rip), %xmm0
108 ; CHECK-NEXT:    retq
109   %y = fadd float %x, %x
110   %z = fmul float %x, 2.0
111   %w = fadd float %y, %z
112   ret float %w
115 ; CHECK: float 3
116 ; CHECK: float 4
117 ; CHECK: float 5
118 ; CHECK: float 6
119 define <4 x float> @fadd_fadd_x_x_fmul_x_c_4f32(<4 x float> %x) #0 {
120 ; CHECK-LABEL: fadd_fadd_x_x_fmul_x_c_4f32:
121 ; CHECK:       # %bb.0:
122 ; CHECK-NEXT:    mulps {{.*}}(%rip), %xmm0
123 ; CHECK-NEXT:    retq
124   %y = fadd <4 x float> %x, %x
125   %z = fmul <4 x float> %x, <float 1.0, float 2.0, float 3.0, float 4.0>
126   %w = fadd <4 x float> %y, %z
127   ret <4 x float> %w
130 ; CHECK: float 4
131 define float @fadd_fmul_x_c_fadd_x_x_f32(float %x) #0 {
132 ; CHECK-LABEL: fadd_fmul_x_c_fadd_x_x_f32:
133 ; CHECK:       # %bb.0:
134 ; CHECK-NEXT:    mulss {{.*}}(%rip), %xmm0
135 ; CHECK-NEXT:    retq
136   %y = fadd float %x, %x
137   %z = fmul float %x, 2.0
138   %w = fadd float %z, %y
139   ret float %w
142 ; CHECK: float 3
143 ; CHECK: float 4
144 ; CHECK: float 5
145 ; CHECK: float 6
146 define <4 x float> @fadd_fmul_x_c_fadd_x_x_4f32(<4 x float> %x) #0 {
147 ; CHECK-LABEL: fadd_fmul_x_c_fadd_x_x_4f32:
148 ; CHECK:       # %bb.0:
149 ; CHECK-NEXT:    mulps {{.*}}(%rip), %xmm0
150 ; CHECK-NEXT:    retq
151   %y = fadd <4 x float> %x, %x
152   %z = fmul <4 x float> %x, <float 1.0, float 2.0, float 3.0, float 4.0>
153   %w = fadd <4 x float> %z, %y
154   ret <4 x float> %w
157 ; CHECK: float 3
158 define float @fadd_x_fadd_x_x_f32(float %x) #0 {
159 ; CHECK-LABEL: fadd_x_fadd_x_x_f32:
160 ; CHECK:       # %bb.0:
161 ; CHECK-NEXT:    mulss {{.*}}(%rip), %xmm0
162 ; CHECK-NEXT:    retq
163   %y = fadd float %x, %x
164   %z = fadd float %x, %y
165   ret float %z
168 ; CHECK: float 3
169 ; CHECK: float 3
170 ; CHECK: float 3
171 ; CHECK: float 3
172 define <4 x float> @fadd_x_fadd_x_x_4f32(<4 x float> %x) #0 {
173 ; CHECK-LABEL: fadd_x_fadd_x_x_4f32:
174 ; CHECK:       # %bb.0:
175 ; CHECK-NEXT:    mulps {{.*}}(%rip), %xmm0
176 ; CHECK-NEXT:    retq
177   %y = fadd <4 x float> %x, %x
178   %z = fadd <4 x float> %x, %y
179   ret <4 x float> %z
182 ; CHECK: float 3
183 define float @fadd_fadd_x_x_x_f32(float %x) #0 {
184 ; CHECK-LABEL: fadd_fadd_x_x_x_f32:
185 ; CHECK:       # %bb.0:
186 ; CHECK-NEXT:    mulss {{.*}}(%rip), %xmm0
187 ; CHECK-NEXT:    retq
188   %y = fadd float %x, %x
189   %z = fadd float %y, %x
190   ret float %z
193 ; CHECK: float 3
194 ; CHECK: float 3
195 ; CHECK: float 3
196 ; CHECK: float 3
197 define <4 x float> @fadd_fadd_x_x_x_4f32(<4 x float> %x) #0 {
198 ; CHECK-LABEL: fadd_fadd_x_x_x_4f32:
199 ; CHECK:       # %bb.0:
200 ; CHECK-NEXT:    mulps {{.*}}(%rip), %xmm0
201 ; CHECK-NEXT:    retq
202   %y = fadd <4 x float> %x, %x
203   %z = fadd <4 x float> %y, %x
204   ret <4 x float> %z
207 ; CHECK: float 4
208 define float @fadd_fadd_x_x_fadd_x_x_f32(float %x) #0 {
209 ; CHECK-LABEL: fadd_fadd_x_x_fadd_x_x_f32:
210 ; CHECK:       # %bb.0:
211 ; CHECK-NEXT:    mulss {{.*}}(%rip), %xmm0
212 ; CHECK-NEXT:    retq
213   %y = fadd float %x, %x
214   %z = fadd float %y, %y
215   ret float %z
218 ; CHECK: float 4
219 ; CHECK: float 4
220 ; CHECK: float 4
221 ; CHECK: float 4
222 define <4 x float> @fadd_fadd_x_x_fadd_x_x_4f32(<4 x float> %x) #0 {
223 ; CHECK-LABEL: fadd_fadd_x_x_fadd_x_x_4f32:
224 ; CHECK:       # %bb.0:
225 ; CHECK-NEXT:    mulps {{.*}}(%rip), %xmm0
226 ; CHECK-NEXT:    retq
227   %y = fadd <4 x float> %x, %x
228   %z = fadd <4 x float> %y, %y
229   ret <4 x float> %z
232 ; ((x + 42.0) + 17.0) + (x + 42.0) --> (x + 59.0) + (x + 17.0)
233 ; It's still 3 adds, but the first 2 are independent.
234 ; More reassocation could get this to 2 adds or 1 FMA (that's done in IR, but not in the DAG).
236 define float @fadd_const_multiuse_attr(float %x) #0 {
237 ; CHECK-LABEL: fadd_const_multiuse_attr:
238 ; CHECK:       # %bb.0:
239 ; CHECK-NEXT:    movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
240 ; CHECK-NEXT:    addss %xmm0, %xmm1
241 ; CHECK-NEXT:    addss {{.*}}(%rip), %xmm0
242 ; CHECK-NEXT:    addss %xmm1, %xmm0
243 ; CHECK-NEXT:    retq
244   %a1 = fadd float %x, 42.0
245   %a2 = fadd float %a1, 17.0
246   %a3 = fadd float %a1, %a2
247   ret float %a3
250 attributes #0 = { "less-precise-fpmad"="true" "no-infs-fp-math"="true" "no-nans-fp-math"="true" "unsafe-fp-math"="true" "no-signed-zeros-fp-math"="true" }