1; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -fp-contract=fast | FileCheck %s
2; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s -check-prefix=CHECK-NOFAST
3
4declare float @llvm.fma.f32(float, float, float)
5declare double @llvm.fma.f64(double, double, double)
6
7define float @test_fmadd(float %a, float %b, float %c) {
8; CHECK-LABEL: test_fmadd:
9; CHECK-NOFAST-LABEL: test_fmadd:
10  %val = call float @llvm.fma.f32(float %a, float %b, float %c)
11; CHECK: fmadd {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
12; CHECK-NOFAST: fmadd {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
13  ret float %val
14}
15
16define float @test_fmsub(float %a, float %b, float %c) {
17; CHECK-LABEL: test_fmsub:
18; CHECK-NOFAST-LABEL: test_fmsub:
19  %nega = fsub float -0.0, %a
20  %val = call float @llvm.fma.f32(float %nega, float %b, float %c)
21; CHECK: fmsub {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
22; CHECK-NOFAST: fmsub {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
23  ret float %val
24}
25
26define float @test_fnmadd(float %a, float %b, float %c) {
27; CHECK-LABEL: test_fnmadd:
28; CHECK-NOFAST-LABEL: test_fnmadd:
29  %negc = fsub float -0.0, %c
30  %val = call float @llvm.fma.f32(float %a, float %b, float %negc)
31; CHECK: fnmadd {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
32; CHECK-NOFAST: fnmadd {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
33  ret float %val
34}
35
36define float @test_fnmsub(float %a, float %b, float %c) {
37; CHECK-LABEL: test_fnmsub:
38; CHECK-NOFAST-LABEL: test_fnmsub:
39  %nega = fsub float -0.0, %a
40  %negc = fsub float -0.0, %c
41  %val = call float @llvm.fma.f32(float %nega, float %b, float %negc)
42; CHECK: fnmsub {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
43; CHECK-NOFAST: fnmsub {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
44  ret float %val
45}
46
47define double @testd_fmadd(double %a, double %b, double %c) {
48; CHECK-LABEL: testd_fmadd:
49; CHECK-NOFAST-LABEL: testd_fmadd:
50  %val = call double @llvm.fma.f64(double %a, double %b, double %c)
51; CHECK: fmadd {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
52; CHECK-NOFAST: fmadd {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
53  ret double %val
54}
55
56define double @testd_fmsub(double %a, double %b, double %c) {
57; CHECK-LABEL: testd_fmsub:
58; CHECK-NOFAST-LABEL: testd_fmsub:
59  %nega = fsub double -0.0, %a
60  %val = call double @llvm.fma.f64(double %nega, double %b, double %c)
61; CHECK: fmsub {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
62; CHECK-NOFAST: fmsub {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
63  ret double %val
64}
65
66define double @testd_fnmadd(double %a, double %b, double %c) {
67; CHECK-LABEL: testd_fnmadd:
68; CHECK-NOFAST-LABEL: testd_fnmadd:
69  %negc = fsub double -0.0, %c
70  %val = call double @llvm.fma.f64(double %a, double %b, double %negc)
71; CHECK: fnmadd {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
72; CHECK-NOFAST: fnmadd {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
73  ret double %val
74}
75
76define double @testd_fnmsub(double %a, double %b, double %c) {
77; CHECK-LABEL: testd_fnmsub:
78; CHECK-NOFAST-LABEL: testd_fnmsub:
79  %nega = fsub double -0.0, %a
80  %negc = fsub double -0.0, %c
81  %val = call double @llvm.fma.f64(double %nega, double %b, double %negc)
82; CHECK: fnmsub {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
83; CHECK-NOFAST: fnmsub {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
84  ret double %val
85}
86
87define float @test_fmadd_unfused(float %a, float %b, float %c) {
88; CHECK-LABEL: test_fmadd_unfused:
89; CHECK-NOFAST-LABEL: test_fmadd_unfused:
90  %prod = fmul float %b, %c
91  %sum = fadd float %a, %prod
92; CHECK: fmadd {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
93; CHECK-NOFAST-NOT: fmadd {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
94; CHECK-NOFAST: fmul {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
95; CHECK-NOFAST: fadd {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
96  ret float %sum
97}
98
99define float @test_fmsub_unfused(float %a, float %b, float %c) {
100; CHECK-LABEL: test_fmsub_unfused:
101; CHECK-NOFAST-LABEL: test_fmsub_unfused:
102  %prod = fmul float %b, %c
103  %diff = fsub float %a, %prod
104; CHECK: fmsub {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
105; CHECK-NOFAST-NOT: fmsub {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
106; CHECK-NOFAST: fmul {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
107; CHECK-NOFAST: fsub {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
108  ret float %diff
109}
110
111define float @test_fnmadd_unfused(float %a, float %b, float %c) {
112; CHECK-LABEL: test_fnmadd_unfused:
113; CHECK-NOFAST-LABEL: test_fnmadd_unfused:
114  %nega = fsub float -0.0, %a
115  %prod = fmul float %b, %c
116  %sum = fadd float %nega, %prod
117; CHECK: fnmadd {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
118; CHECK-NOFAST-NOT: fnmadd {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
119; CHECK-NOFAST: fmul {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
120; CHECK-NOFAST: fsub {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
121  ret float %sum
122}
123
124define float @test_fnmsub_unfused(float %a, float %b, float %c) {
125; CHECK-LABEL: test_fnmsub_unfused:
126; CHECK-NOFAST-LABEL: test_fnmsub_unfused:
127  %nega = fsub float -0.0, %a
128  %prod = fmul float %b, %c
129  %diff = fsub float %nega, %prod
130; CHECK: fnmsub {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
131; CHECK-NOFAST-NOT: fnmsub {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
132; CHECK-NOFAST-DAG: fmul {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
133; CHECK-NOFAST-DAG: fneg {{s[0-9]+}}, {{s[0-9]+}}
134; CHECK-NOFAST-DAG: fsub {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
135; CHECK-NOFAST: ret
136  ret float %diff
137}
138