xref: /aosp_15_r20/external/llvm/test/CodeGen/X86/fmul-combines.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: llc -mtriple=x86_64-unknown-unknown -march=x86-64 < %s | FileCheck %s
2*9880d681SAndroid Build Coastguard Worker
3*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fmul2_f32:
4*9880d681SAndroid Build Coastguard Worker; CHECK: addss %xmm0, %xmm0
5*9880d681SAndroid Build Coastguard Workerdefine float @fmul2_f32(float %x) {
6*9880d681SAndroid Build Coastguard Worker  %y = fmul float %x, 2.0
7*9880d681SAndroid Build Coastguard Worker  ret float %y
8*9880d681SAndroid Build Coastguard Worker}
9*9880d681SAndroid Build Coastguard Worker
10*9880d681SAndroid Build Coastguard Worker; fmul 2.0, x -> fadd x, x for vectors.
11*9880d681SAndroid Build Coastguard Worker
12*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fmul2_v4f32:
13*9880d681SAndroid Build Coastguard Worker; CHECK: addps %xmm0, %xmm0
14*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq
15*9880d681SAndroid Build Coastguard Workerdefine <4 x float> @fmul2_v4f32(<4 x float> %x) {
16*9880d681SAndroid Build Coastguard Worker  %y = fmul <4 x float> %x, <float 2.0, float 2.0, float 2.0, float 2.0>
17*9880d681SAndroid Build Coastguard Worker  ret <4 x float> %y
18*9880d681SAndroid Build Coastguard Worker}
19*9880d681SAndroid Build Coastguard Worker
20*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: constant_fold_fmul_v4f32:
21*9880d681SAndroid Build Coastguard Worker; CHECK: movaps
22*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
23*9880d681SAndroid Build Coastguard Workerdefine <4 x float> @constant_fold_fmul_v4f32(<4 x float> %x) {
24*9880d681SAndroid Build Coastguard Worker  %y = fmul <4 x float> <float 4.0, float 4.0, float 4.0, float 4.0>, <float 2.0, float 2.0, float 2.0, float 2.0>
25*9880d681SAndroid Build Coastguard Worker  ret <4 x float> %y
26*9880d681SAndroid Build Coastguard Worker}
27*9880d681SAndroid Build Coastguard Worker
28*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fmul0_v4f32:
29*9880d681SAndroid Build Coastguard Worker; CHECK: xorps %xmm0, %xmm0
30*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq
31*9880d681SAndroid Build Coastguard Workerdefine <4 x float> @fmul0_v4f32(<4 x float> %x) #0 {
32*9880d681SAndroid Build Coastguard Worker  %y = fmul <4 x float> %x, <float 0.0, float 0.0, float 0.0, float 0.0>
33*9880d681SAndroid Build Coastguard Worker  ret <4 x float> %y
34*9880d681SAndroid Build Coastguard Worker}
35*9880d681SAndroid Build Coastguard Worker
36*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fmul_c2_c4_v4f32:
37*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: addps
38*9880d681SAndroid Build Coastguard Worker; CHECK: mulps
39*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mulps
40*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
41*9880d681SAndroid Build Coastguard Workerdefine <4 x float> @fmul_c2_c4_v4f32(<4 x float> %x) #0 {
42*9880d681SAndroid Build Coastguard Worker  %y = fmul <4 x float> %x, <float 2.0, float 2.0, float 2.0, float 2.0>
43*9880d681SAndroid Build Coastguard Worker  %z = fmul <4 x float> %y, <float 4.0, float 4.0, float 4.0, float 4.0>
44*9880d681SAndroid Build Coastguard Worker  ret <4 x float> %z
45*9880d681SAndroid Build Coastguard Worker}
46*9880d681SAndroid Build Coastguard Worker
47*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fmul_c3_c4_v4f32:
48*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: addps
49*9880d681SAndroid Build Coastguard Worker; CHECK: mulps
50*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mulps
51*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
52*9880d681SAndroid Build Coastguard Workerdefine <4 x float> @fmul_c3_c4_v4f32(<4 x float> %x) #0 {
53*9880d681SAndroid Build Coastguard Worker  %y = fmul <4 x float> %x, <float 3.0, float 3.0, float 3.0, float 3.0>
54*9880d681SAndroid Build Coastguard Worker  %z = fmul <4 x float> %y, <float 4.0, float 4.0, float 4.0, float 4.0>
55*9880d681SAndroid Build Coastguard Worker  ret <4 x float> %z
56*9880d681SAndroid Build Coastguard Worker}
57*9880d681SAndroid Build Coastguard Worker
58*9880d681SAndroid Build Coastguard Worker; We should be able to pre-multiply the two constant vectors.
59*9880d681SAndroid Build Coastguard Worker; CHECK: float 5
60*9880d681SAndroid Build Coastguard Worker; CHECK: float 12
61*9880d681SAndroid Build Coastguard Worker; CHECK: float 21
62*9880d681SAndroid Build Coastguard Worker; CHECK: float 32
63*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fmul_v4f32_two_consts_no_splat:
64*9880d681SAndroid Build Coastguard Worker; CHECK: mulps
65*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mulps
66*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
67*9880d681SAndroid Build Coastguard Workerdefine <4 x float> @fmul_v4f32_two_consts_no_splat(<4 x float> %x) #0 {
68*9880d681SAndroid Build Coastguard Worker  %y = fmul <4 x float> %x, <float 1.0, float 2.0, float 3.0, float 4.0>
69*9880d681SAndroid Build Coastguard Worker  %z = fmul <4 x float> %y, <float 5.0, float 6.0, float 7.0, float 8.0>
70*9880d681SAndroid Build Coastguard Worker  ret <4 x float> %z
71*9880d681SAndroid Build Coastguard Worker}
72*9880d681SAndroid Build Coastguard Worker
73*9880d681SAndroid Build Coastguard Worker; Same as above, but reverse operands to make sure non-canonical form is also handled.
74*9880d681SAndroid Build Coastguard Worker; CHECK: float 5
75*9880d681SAndroid Build Coastguard Worker; CHECK: float 12
76*9880d681SAndroid Build Coastguard Worker; CHECK: float 21
77*9880d681SAndroid Build Coastguard Worker; CHECK: float 32
78*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fmul_v4f32_two_consts_no_splat_non_canonical:
79*9880d681SAndroid Build Coastguard Worker; CHECK: mulps
80*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mulps
81*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
82*9880d681SAndroid Build Coastguard Workerdefine <4 x float> @fmul_v4f32_two_consts_no_splat_non_canonical(<4 x float> %x) #0 {
83*9880d681SAndroid Build Coastguard Worker  %y = fmul <4 x float> <float 1.0, float 2.0, float 3.0, float 4.0>, %x
84*9880d681SAndroid Build Coastguard Worker  %z = fmul <4 x float> <float 5.0, float 6.0, float 7.0, float 8.0>, %y
85*9880d681SAndroid Build Coastguard Worker  ret <4 x float> %z
86*9880d681SAndroid Build Coastguard Worker}
87*9880d681SAndroid Build Coastguard Worker
88*9880d681SAndroid Build Coastguard Worker; More than one use of a constant multiply should not inhibit the optimization.
89*9880d681SAndroid Build Coastguard Worker; Instead of a chain of 2 dependent mults, this test will have 2 independent mults.
90*9880d681SAndroid Build Coastguard Worker; CHECK: float 6
91*9880d681SAndroid Build Coastguard Worker; CHECK: float 14
92*9880d681SAndroid Build Coastguard Worker; CHECK: float 24
93*9880d681SAndroid Build Coastguard Worker; CHECK: float 36
94*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fmul_v4f32_two_consts_no_splat_multiple_use:
95*9880d681SAndroid Build Coastguard Worker; CHECK: mulps
96*9880d681SAndroid Build Coastguard Worker; CHECK: ret
97*9880d681SAndroid Build Coastguard Workerdefine <4 x float> @fmul_v4f32_two_consts_no_splat_multiple_use(<4 x float> %x) #0 {
98*9880d681SAndroid Build Coastguard Worker  %y = fmul <4 x float> %x, <float 1.0, float 2.0, float 3.0, float 4.0>
99*9880d681SAndroid Build Coastguard Worker  %z = fmul <4 x float> %y, <float 5.0, float 6.0, float 7.0, float 8.0>
100*9880d681SAndroid Build Coastguard Worker  %a = fadd <4 x float> %y, %z
101*9880d681SAndroid Build Coastguard Worker  ret <4 x float> %a
102*9880d681SAndroid Build Coastguard Worker}
103*9880d681SAndroid Build Coastguard Worker
104*9880d681SAndroid Build Coastguard Worker; PR22698 - http://llvm.org/bugs/show_bug.cgi?id=22698
105*9880d681SAndroid Build Coastguard Worker; Make sure that we don't infinite loop swapping constants back and forth.
106*9880d681SAndroid Build Coastguard Worker
107*9880d681SAndroid Build Coastguard Workerdefine <4 x float> @PR22698_splats(<4 x float> %a) #0 {
108*9880d681SAndroid Build Coastguard Worker  %mul1 = fmul fast <4 x float> <float 2.0, float 2.0, float 2.0, float 2.0>, <float 3.0, float 3.0, float 3.0, float 3.0>
109*9880d681SAndroid Build Coastguard Worker  %mul2 = fmul fast <4 x float> <float 4.0, float 4.0, float 4.0, float 4.0>, %mul1
110*9880d681SAndroid Build Coastguard Worker  %mul3 = fmul fast <4 x float> %a, %mul2
111*9880d681SAndroid Build Coastguard Worker  ret <4 x float> %mul3
112*9880d681SAndroid Build Coastguard Worker
113*9880d681SAndroid Build Coastguard Worker; CHECK: float 24
114*9880d681SAndroid Build Coastguard Worker; CHECK: float 24
115*9880d681SAndroid Build Coastguard Worker; CHECK: float 24
116*9880d681SAndroid Build Coastguard Worker; CHECK: float 24
117*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: PR22698_splats:
118*9880d681SAndroid Build Coastguard Worker; CHECK: mulps
119*9880d681SAndroid Build Coastguard Worker; CHECK: ret
120*9880d681SAndroid Build Coastguard Worker}
121*9880d681SAndroid Build Coastguard Worker
122*9880d681SAndroid Build Coastguard Worker; Same as above, but verify that non-splat vectors are handled correctly too.
123*9880d681SAndroid Build Coastguard Workerdefine <4 x float> @PR22698_no_splats(<4 x float> %a) #0 {
124*9880d681SAndroid Build Coastguard Worker  %mul1 = fmul fast <4 x float> <float 1.0, float 2.0, float 3.0, float 4.0>, <float 5.0, float 6.0, float 7.0, float 8.0>
125*9880d681SAndroid Build Coastguard Worker  %mul2 = fmul fast <4 x float> <float 9.0, float 10.0, float 11.0, float 12.0>, %mul1
126*9880d681SAndroid Build Coastguard Worker  %mul3 = fmul fast <4 x float> %a, %mul2
127*9880d681SAndroid Build Coastguard Worker  ret <4 x float> %mul3
128*9880d681SAndroid Build Coastguard Worker
129*9880d681SAndroid Build Coastguard Worker; CHECK: float 45
130*9880d681SAndroid Build Coastguard Worker; CHECK: float 120
131*9880d681SAndroid Build Coastguard Worker; CHECK: float 231
132*9880d681SAndroid Build Coastguard Worker; CHECK: float 384
133*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: PR22698_no_splats:
134*9880d681SAndroid Build Coastguard Worker; CHECK: mulps
135*9880d681SAndroid Build Coastguard Worker; CHECK: ret
136*9880d681SAndroid Build Coastguard Worker}
137*9880d681SAndroid Build Coastguard Worker
138*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fmul_c2_c4_f32:
139*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: addss
140*9880d681SAndroid Build Coastguard Worker; CHECK: mulss
141*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mulss
142*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
143*9880d681SAndroid Build Coastguard Workerdefine float @fmul_c2_c4_f32(float %x) #0 {
144*9880d681SAndroid Build Coastguard Worker  %y = fmul float %x, 2.0
145*9880d681SAndroid Build Coastguard Worker  %z = fmul float %y, 4.0
146*9880d681SAndroid Build Coastguard Worker  ret float %z
147*9880d681SAndroid Build Coastguard Worker}
148*9880d681SAndroid Build Coastguard Worker
149*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fmul_c3_c4_f32:
150*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: addss
151*9880d681SAndroid Build Coastguard Worker; CHECK: mulss
152*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mulss
153*9880d681SAndroid Build Coastguard Worker; CHECK-NET: ret
154*9880d681SAndroid Build Coastguard Workerdefine float @fmul_c3_c4_f32(float %x) #0 {
155*9880d681SAndroid Build Coastguard Worker  %y = fmul float %x, 3.0
156*9880d681SAndroid Build Coastguard Worker  %z = fmul float %y, 4.0
157*9880d681SAndroid Build Coastguard Worker  ret float %z
158*9880d681SAndroid Build Coastguard Worker}
159*9880d681SAndroid Build Coastguard Worker
160*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fmul_fneg_fneg_f32:
161*9880d681SAndroid Build Coastguard Worker; CHECK: mulss %xmm1, %xmm0
162*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq
163*9880d681SAndroid Build Coastguard Workerdefine float @fmul_fneg_fneg_f32(float %x, float %y) {
164*9880d681SAndroid Build Coastguard Worker  %x.neg = fsub float -0.0, %x
165*9880d681SAndroid Build Coastguard Worker  %y.neg = fsub float -0.0, %y
166*9880d681SAndroid Build Coastguard Worker  %mul = fmul float %x.neg, %y.neg
167*9880d681SAndroid Build Coastguard Worker  ret float %mul
168*9880d681SAndroid Build Coastguard Worker}
169*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fmul_fneg_fneg_v4f32:
170*9880d681SAndroid Build Coastguard Worker; CHECK: mulps {{%xmm1|\(%rdx\)}}, %xmm0
171*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq
172*9880d681SAndroid Build Coastguard Workerdefine <4 x float> @fmul_fneg_fneg_v4f32(<4 x float> %x, <4 x float> %y) {
173*9880d681SAndroid Build Coastguard Worker  %x.neg = fsub <4 x float> <float -0.0, float -0.0, float -0.0, float -0.0>, %x
174*9880d681SAndroid Build Coastguard Worker  %y.neg = fsub <4 x float> <float -0.0, float -0.0, float -0.0, float -0.0>, %y
175*9880d681SAndroid Build Coastguard Worker  %mul = fmul <4 x float> %x.neg, %y.neg
176*9880d681SAndroid Build Coastguard Worker  ret <4 x float> %mul
177*9880d681SAndroid Build Coastguard Worker}
178*9880d681SAndroid Build Coastguard Worker
179*9880d681SAndroid Build Coastguard Workerattributes #0 = { "less-precise-fpmad"="true" "no-infs-fp-math"="true" "no-nans-fp-math"="true" "unsafe-fp-math"="true" }
180