1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=amdgcn-mesa-mesa3d -mcpu=gfx900 < %s | FileCheck -check-prefix=GCN %s
3; RUN: llc -mtriple=amdgcn-mesa-mesa3d -mcpu=gfx1010 < %s | FileCheck -check-prefix=GFX10 %s
4; RUN: llc -mtriple=amdgcn-mesa-mesa3d -mcpu=gfx1100 -amdgpu-enable-delay-alu=0 < %s | FileCheck -check-prefix=GFX10 %s
5
6define double @v_constained_fma_f64_fpexcept_strict(double %x, double %y, double %z) #0 {
7; GCN-LABEL: v_constained_fma_f64_fpexcept_strict:
8; GCN:       ; %bb.0:
9; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
10; GCN-NEXT:    v_fma_f64 v[0:1], v[0:1], v[2:3], v[4:5]
11; GCN-NEXT:    s_setpc_b64 s[30:31]
12;
13; GFX10-LABEL: v_constained_fma_f64_fpexcept_strict:
14; GFX10:       ; %bb.0:
15; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
16; GFX10-NEXT:    s_waitcnt_vscnt null, 0x0
17; GFX10-NEXT:    v_fma_f64 v[0:1], v[0:1], v[2:3], v[4:5]
18; GFX10-NEXT:    s_setpc_b64 s[30:31]
19  %val = call double @llvm.experimental.constrained.fma.f64(double %x, double %y, double %z, metadata !"round.tonearest", metadata !"fpexcept.strict")
20  ret double %val
21}
22
23define <2 x double> @v_constained_fma_v2f64_fpexcept_strict(<2 x double> %x, <2 x double> %y, <2 x double> %z) #0 {
24; GCN-LABEL: v_constained_fma_v2f64_fpexcept_strict:
25; GCN:       ; %bb.0:
26; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
27; GCN-NEXT:    v_fma_f64 v[0:1], v[0:1], v[4:5], v[8:9]
28; GCN-NEXT:    v_fma_f64 v[2:3], v[2:3], v[6:7], v[10:11]
29; GCN-NEXT:    s_setpc_b64 s[30:31]
30;
31; GFX10-LABEL: v_constained_fma_v2f64_fpexcept_strict:
32; GFX10:       ; %bb.0:
33; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
34; GFX10-NEXT:    s_waitcnt_vscnt null, 0x0
35; GFX10-NEXT:    v_fma_f64 v[0:1], v[0:1], v[4:5], v[8:9]
36; GFX10-NEXT:    v_fma_f64 v[2:3], v[2:3], v[6:7], v[10:11]
37; GFX10-NEXT:    s_setpc_b64 s[30:31]
38  %val = call <2 x double> @llvm.experimental.constrained.fma.v2f64(<2 x double> %x, <2 x double> %y, <2 x double> %z, metadata !"round.tonearest", metadata !"fpexcept.strict")
39  ret <2 x double> %val
40}
41
42define <3 x double> @v_constained_fma_v3f64_fpexcept_strict(<3 x double> %x, <3 x double> %y, <3 x double> %z) #0 {
43; GCN-LABEL: v_constained_fma_v3f64_fpexcept_strict:
44; GCN:       ; %bb.0:
45; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
46; GCN-NEXT:    v_fma_f64 v[0:1], v[0:1], v[6:7], v[12:13]
47; GCN-NEXT:    v_fma_f64 v[2:3], v[2:3], v[8:9], v[14:15]
48; GCN-NEXT:    v_fma_f64 v[4:5], v[4:5], v[10:11], v[16:17]
49; GCN-NEXT:    s_setpc_b64 s[30:31]
50;
51; GFX10-LABEL: v_constained_fma_v3f64_fpexcept_strict:
52; GFX10:       ; %bb.0:
53; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
54; GFX10-NEXT:    s_waitcnt_vscnt null, 0x0
55; GFX10-NEXT:    v_fma_f64 v[0:1], v[0:1], v[6:7], v[12:13]
56; GFX10-NEXT:    v_fma_f64 v[2:3], v[2:3], v[8:9], v[14:15]
57; GFX10-NEXT:    v_fma_f64 v[4:5], v[4:5], v[10:11], v[16:17]
58; GFX10-NEXT:    s_setpc_b64 s[30:31]
59  %val = call <3 x double> @llvm.experimental.constrained.fma.v3f64(<3 x double> %x, <3 x double> %y, <3 x double> %z, metadata !"round.tonearest", metadata !"fpexcept.strict")
60  ret <3 x double> %val
61}
62
63define <4 x double> @v_constained_fma_v4f64_fpexcept_strict(<4 x double> %x, <4 x double> %y, <4 x double> %z) #0 {
64; GCN-LABEL: v_constained_fma_v4f64_fpexcept_strict:
65; GCN:       ; %bb.0:
66; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
67; GCN-NEXT:    v_fma_f64 v[0:1], v[0:1], v[8:9], v[16:17]
68; GCN-NEXT:    v_fma_f64 v[2:3], v[2:3], v[10:11], v[18:19]
69; GCN-NEXT:    v_fma_f64 v[4:5], v[4:5], v[12:13], v[20:21]
70; GCN-NEXT:    v_fma_f64 v[6:7], v[6:7], v[14:15], v[22:23]
71; GCN-NEXT:    s_setpc_b64 s[30:31]
72;
73; GFX10-LABEL: v_constained_fma_v4f64_fpexcept_strict:
74; GFX10:       ; %bb.0:
75; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
76; GFX10-NEXT:    s_waitcnt_vscnt null, 0x0
77; GFX10-NEXT:    v_fma_f64 v[0:1], v[0:1], v[8:9], v[16:17]
78; GFX10-NEXT:    v_fma_f64 v[2:3], v[2:3], v[10:11], v[18:19]
79; GFX10-NEXT:    v_fma_f64 v[4:5], v[4:5], v[12:13], v[20:21]
80; GFX10-NEXT:    v_fma_f64 v[6:7], v[6:7], v[14:15], v[22:23]
81; GFX10-NEXT:    s_setpc_b64 s[30:31]
82  %val = call <4 x double> @llvm.experimental.constrained.fma.v4f64(<4 x double> %x, <4 x double> %y, <4 x double> %z, metadata !"round.tonearest", metadata !"fpexcept.strict")
83  ret <4 x double> %val
84}
85
86define double @v_constained_fma_f64_fpexcept_strict_fneg(double %x, double %y, double %z) #0 {
87; GCN-LABEL: v_constained_fma_f64_fpexcept_strict_fneg:
88; GCN:       ; %bb.0:
89; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
90; GCN-NEXT:    v_fma_f64 v[0:1], v[0:1], v[2:3], -v[4:5]
91; GCN-NEXT:    s_setpc_b64 s[30:31]
92;
93; GFX10-LABEL: v_constained_fma_f64_fpexcept_strict_fneg:
94; GFX10:       ; %bb.0:
95; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
96; GFX10-NEXT:    s_waitcnt_vscnt null, 0x0
97; GFX10-NEXT:    v_fma_f64 v[0:1], v[0:1], v[2:3], -v[4:5]
98; GFX10-NEXT:    s_setpc_b64 s[30:31]
99  %neg.z = fneg double %z
100  %val = call double @llvm.experimental.constrained.fma.f64(double %x, double %y, double %neg.z, metadata !"round.tonearest", metadata !"fpexcept.strict")
101  ret double %val
102}
103
104define double @v_constained_fma_f64_fpexcept_strict_fneg_fneg(double %x, double %y, double %z) #0 {
105; GCN-LABEL: v_constained_fma_f64_fpexcept_strict_fneg_fneg:
106; GCN:       ; %bb.0:
107; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
108; GCN-NEXT:    v_fma_f64 v[0:1], -v[0:1], -v[2:3], v[4:5]
109; GCN-NEXT:    s_setpc_b64 s[30:31]
110;
111; GFX10-LABEL: v_constained_fma_f64_fpexcept_strict_fneg_fneg:
112; GFX10:       ; %bb.0:
113; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
114; GFX10-NEXT:    s_waitcnt_vscnt null, 0x0
115; GFX10-NEXT:    v_fma_f64 v[0:1], -v[0:1], -v[2:3], v[4:5]
116; GFX10-NEXT:    s_setpc_b64 s[30:31]
117  %neg.x = fneg double %x
118  %neg.y = fneg double %y
119  %val = call double @llvm.experimental.constrained.fma.f64(double %neg.x, double %neg.y, double %z, metadata !"round.tonearest", metadata !"fpexcept.strict")
120  ret double %val
121}
122
123define double @v_constained_fma_f64_fpexcept_strict_fabs_fabs(double %x, double %y, double %z) #0 {
124; GCN-LABEL: v_constained_fma_f64_fpexcept_strict_fabs_fabs:
125; GCN:       ; %bb.0:
126; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
127; GCN-NEXT:    v_fma_f64 v[0:1], |v[0:1]|, |v[2:3]|, v[4:5]
128; GCN-NEXT:    s_setpc_b64 s[30:31]
129;
130; GFX10-LABEL: v_constained_fma_f64_fpexcept_strict_fabs_fabs:
131; GFX10:       ; %bb.0:
132; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
133; GFX10-NEXT:    s_waitcnt_vscnt null, 0x0
134; GFX10-NEXT:    v_fma_f64 v[0:1], |v[0:1]|, |v[2:3]|, v[4:5]
135; GFX10-NEXT:    s_setpc_b64 s[30:31]
136  %neg.x = call double @llvm.fabs.f64(double %x)
137  %neg.y = call double @llvm.fabs.f64(double %y)
138  %val = call double @llvm.experimental.constrained.fma.f64(double %neg.x, double %neg.y, double %z, metadata !"round.tonearest", metadata !"fpexcept.strict")
139  ret double %val
140}
141
142define <2 x double> @v_constained_fma_v2f64_fpexcept_strict_fneg_fneg(<2 x double> %x, <2 x double> %y, <2 x double> %z) #0 {
143; GCN-LABEL: v_constained_fma_v2f64_fpexcept_strict_fneg_fneg:
144; GCN:       ; %bb.0:
145; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
146; GCN-NEXT:    v_fma_f64 v[0:1], -v[0:1], -v[4:5], v[8:9]
147; GCN-NEXT:    v_fma_f64 v[2:3], -v[2:3], -v[6:7], v[10:11]
148; GCN-NEXT:    s_setpc_b64 s[30:31]
149;
150; GFX10-LABEL: v_constained_fma_v2f64_fpexcept_strict_fneg_fneg:
151; GFX10:       ; %bb.0:
152; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
153; GFX10-NEXT:    s_waitcnt_vscnt null, 0x0
154; GFX10-NEXT:    v_fma_f64 v[0:1], -v[0:1], -v[4:5], v[8:9]
155; GFX10-NEXT:    v_fma_f64 v[2:3], -v[2:3], -v[6:7], v[10:11]
156; GFX10-NEXT:    s_setpc_b64 s[30:31]
157  %neg.x = fneg <2 x double> %x
158  %neg.y = fneg <2 x double> %y
159  %val = call <2 x double> @llvm.experimental.constrained.fma.v2f64(<2 x double> %neg.x, <2 x double> %neg.y, <2 x double> %z, metadata !"round.tonearest", metadata !"fpexcept.strict")
160  ret <2 x double> %val
161}
162
163declare double @llvm.fabs.f64(double) #1
164declare double @llvm.experimental.constrained.fma.f64(double, double, double, metadata, metadata) #1
165declare <2 x double> @llvm.experimental.constrained.fma.v2f64(<2 x double>, <2 x double>, <2 x double>, metadata, metadata) #1
166declare <3 x double> @llvm.experimental.constrained.fma.v3f64(<3 x double>, <3 x double>, <3 x double>, metadata, metadata) #1
167declare <4 x double> @llvm.experimental.constrained.fma.v4f64(<4 x double>, <4 x double>, <4 x double>, metadata, metadata) #1
168
169attributes #0 = { strictfp }
170attributes #1 = { inaccessiblememonly nounwind willreturn }
171