1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -verify-machineinstrs -mcpu=pwr9 -mtriple=powerpc64le-linux-gnu | FileCheck %s
3
4; Verify that the fold of a*b-c*d respect the uses of a*b
5define double @fsub1(double %a, double %b, double %c, double %d)  {
6; CHECK-LABEL: fsub1:
7; CHECK:       # %bb.0: # %entry
8; CHECK-NEXT:    xsmuldp 0, 2, 1
9; CHECK-NEXT:    fmr 1, 0
10; CHECK-NEXT:    xsnmsubadp 1, 4, 3
11; CHECK-NEXT:    xsmuldp 1, 0, 1
12; CHECK-NEXT:    blr
13entry:
14  %mul = fmul reassoc double %b, %a
15  %mul1 = fmul reassoc double %d, %c
16  %sub = fsub reassoc nsz double %mul, %mul1
17  %mul3 = fmul reassoc double %mul, %sub
18  ret double %mul3
19}
20
21; Verify that the fold of a*b-c*d respect the uses of c*d
22define double @fsub2(double %a, double %b, double %c, double %d)  {
23; CHECK-LABEL: fsub2:
24; CHECK:       # %bb.0: # %entry
25; CHECK-NEXT:    xsmuldp 0, 4, 3
26; CHECK-NEXT:    fmr 3, 0
27; CHECK-NEXT:    xsmsubadp 3, 2, 1
28; CHECK-NEXT:    xsmuldp 1, 0, 3
29; CHECK-NEXT:    blr
30entry:
31  %mul = fmul reassoc double %b, %a
32  %mul1 = fmul reassoc double %d, %c
33  %sub = fsub reassoc double %mul, %mul1
34  %mul3 = fmul reassoc double %mul1, %sub
35  ret double %mul3
36}
37
38; Verify that the fold of a*b-c*d if there is no uses of a*b and c*d
39define double @fsub3(double %a, double %b, double %c, double %d)  {
40; CHECK-LABEL: fsub3:
41; CHECK:       # %bb.0: # %entry
42; CHECK-NEXT:    xsmuldp 0, 4, 3
43; CHECK-NEXT:    xsmsubadp 0, 2, 1
44; CHECK-NEXT:    fmr 1, 0
45; CHECK-NEXT:    blr
46entry:
47  %mul = fmul reassoc double %b, %a
48  %mul1 = fmul reassoc double %d, %c
49  %sub = fsub reassoc double %mul, %mul1
50  ret double %sub
51}
52
53; Verify that the fold of a*b+c*d respect the uses of a*b
54define double @fadd1(double %a, double %b, double %c, double %d)  {
55; CHECK-LABEL: fadd1:
56; CHECK:       # %bb.0: # %entry
57; CHECK-NEXT:    xsmuldp 0, 2, 1
58; CHECK-NEXT:    fmr 1, 0
59; CHECK-NEXT:    xsmaddadp 1, 4, 3
60; CHECK-NEXT:    xsmuldp 1, 0, 1
61; CHECK-NEXT:    blr
62entry:
63  %mul = fmul reassoc double %b, %a
64  %mul1 = fmul reassoc double %d, %c
65  %add = fadd reassoc double %mul1, %mul
66  %mul3 = fmul reassoc double %mul, %add
67  ret double %mul3
68}
69
70; Verify that the fold of a*b+c*d respect the uses of c*d
71define double @fadd2(double %a, double %b, double %c, double %d)  {
72; CHECK-LABEL: fadd2:
73; CHECK:       # %bb.0: # %entry
74; CHECK-NEXT:    xsmuldp 0, 4, 3
75; CHECK-NEXT:    fmr 3, 0
76; CHECK-NEXT:    xsmaddadp 3, 2, 1
77; CHECK-NEXT:    xsmuldp 1, 0, 3
78; CHECK-NEXT:    blr
79entry:
80  %mul = fmul reassoc double %b, %a
81  %mul1 = fmul reassoc double %d, %c
82  %add = fadd reassoc double %mul1, %mul
83  %mul3 = fmul reassoc double %mul1, %add
84  ret double %mul3
85}
86
87; Verify that the fold of a*b+c*d if there is no uses of a*b and c*d
88define double @fadd3(double %a, double %b, double %c, double %d)  {
89; CHECK-LABEL: fadd3:
90; CHECK:       # %bb.0: # %entry
91; CHECK-NEXT:    xsmuldp 1, 2, 1
92; CHECK-NEXT:    xsmaddadp 1, 4, 3
93; CHECK-NEXT:    blr
94entry:
95  %mul = fmul reassoc double %b, %a
96  %mul1 = fmul reassoc double %d, %c
97  %add = fadd reassoc double %mul1, %mul
98  ret double %add
99}
100
101define double @fma_multi_uses1(double %a, double %b, double %c, double %d, double* %p1, double* %p2, double* %p3) {
102; CHECK-LABEL: fma_multi_uses1:
103; CHECK:       # %bb.0:
104; CHECK-NEXT:    xsmuldp 1, 1, 2
105; CHECK-NEXT:    xsmuldp 0, 3, 4
106; CHECK-NEXT:    stfd 1, 0(7)
107; CHECK-NEXT:    stfd 1, 0(8)
108; CHECK-NEXT:    xsnmsubadp 1, 3, 4
109; CHECK-NEXT:    stfd 0, 0(9)
110; CHECK-NEXT:    blr
111  %ab = fmul reassoc double %a, %b
112  %cd = fmul reassoc double %c, %d
113  store double %ab, double* %p1 ; extra use of %ab
114  store double %ab, double* %p2 ; another extra use of %ab
115  store double %cd, double* %p3 ; extra use of %cd
116  %r = fsub reassoc nsz double %ab, %cd
117  ret double %r
118}
119
120define double @fma_multi_uses2(double %a, double %b, double %c, double %d, double* %p1, double* %p2, double* %p3) {
121; CHECK-LABEL: fma_multi_uses2:
122; CHECK:       # %bb.0:
123; CHECK-NEXT:    xsmuldp 5, 1, 2
124; CHECK-NEXT:    xsmuldp 0, 3, 4
125; CHECK-NEXT:    stfd 5, 0(7)
126; CHECK-NEXT:    stfd 0, 0(8)
127; CHECK-NEXT:    stfd 0, 0(9)
128; CHECK-NEXT:    xsmsubadp 0, 1, 2
129; CHECK-NEXT:    fmr 1, 0
130; CHECK-NEXT:    blr
131  %ab = fmul reassoc double %a, %b
132  %cd = fmul reassoc double %c, %d
133  store double %ab, double* %p1 ; extra use of %ab
134  store double %cd, double* %p2 ; extra use of %cd
135  store double %cd, double* %p3 ; another extra use of %cd
136  %r = fsub reassoc double %ab, %cd
137  ret double %r
138}
139
140define double @fma_multi_uses3(double %a, double %b, double %c, double %d, double %f, double %g, double* %p1, double* %p2, double* %p3) {
141; CHECK-LABEL: fma_multi_uses3:
142; CHECK:       # %bb.0:
143; CHECK-NEXT:    xsmuldp 0, 1, 2
144; CHECK-NEXT:    xsmuldp 1, 5, 6
145; CHECK-NEXT:    ld 3, 96(1)
146; CHECK-NEXT:    stfd 0, 0(9)
147; CHECK-NEXT:    stfd 0, 0(10)
148; CHECK-NEXT:    stfd 1, 0(3)
149; CHECK-NEXT:    xsnmsubadp 1, 3, 4
150; CHECK-NEXT:    xsnmsubadp 0, 3, 4
151; CHECK-NEXT:    xsadddp 1, 0, 1
152; CHECK-NEXT:    blr
153  %ab = fmul reassoc double %a, %b
154  %cd = fmul reassoc double %c, %d
155  %fg = fmul reassoc double %f, %g
156  store double %ab, double* %p1 ; extra use of %ab
157  store double %ab, double* %p2 ; another extra use of %ab
158  store double %fg, double* %p3 ; extra use of %fg
159  %q = fsub reassoc nsz double %fg, %cd ; The uses of %cd reduce to 1 after %r is folded. 2 uses of %fg, fold %cd, remove def of %cd
160  %r = fsub reassoc nsz double %ab, %cd ; Fold %r before %q. 3 uses of %ab, 2 uses of %cd, fold %cd
161  %add = fadd reassoc double %r, %q
162  ret double %add
163}
164