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
5define double @v_constained_fma_f64_fpexcept_strict(double %x, double %y, double %z) #0 {
6; GCN-LABEL: v_constained_fma_f64_fpexcept_strict:
7; GCN:       ; %bb.0:
8; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
9; GCN-NEXT:    v_fma_f64 v[0:1], v[0:1], v[2:3], v[4:5]
10; GCN-NEXT:    s_setpc_b64 s[30:31]
11;
12; GFX10-LABEL: v_constained_fma_f64_fpexcept_strict:
13; GFX10:       ; %bb.0:
14; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
15; GFX10-NEXT:    s_waitcnt_vscnt null, 0x0
16; GFX10-NEXT:    v_fma_f64 v[0:1], v[0:1], v[2:3], v[4:5]
17; GFX10-NEXT:    s_setpc_b64 s[30:31]
18  %val = call double @llvm.experimental.constrained.fma.f64(double %x, double %y, double %z, metadata !"round.tonearest", metadata !"fpexcept.strict")
19  ret double %val
20}
21
22define <2 x double> @v_constained_fma_v2f64_fpexcept_strict(<2 x double> %x, <2 x double> %y, <2 x double> %z) #0 {
23; GCN-LABEL: v_constained_fma_v2f64_fpexcept_strict:
24; GCN:       ; %bb.0:
25; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
26; GCN-NEXT:    v_fma_f64 v[0:1], v[0:1], v[4:5], v[8:9]
27; GCN-NEXT:    v_fma_f64 v[2:3], v[2:3], v[6:7], v[10:11]
28; GCN-NEXT:    s_setpc_b64 s[30:31]
29;
30; GFX10-LABEL: v_constained_fma_v2f64_fpexcept_strict:
31; GFX10:       ; %bb.0:
32; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
33; GFX10-NEXT:    s_waitcnt_vscnt null, 0x0
34; GFX10-NEXT:    v_mov_b32_e32 v13, v3
35; GFX10-NEXT:    v_mov_b32_e32 v12, v2
36; GFX10-NEXT:    v_mov_b32_e32 v15, v1
37; GFX10-NEXT:    v_mov_b32_e32 v14, v0
38; GFX10-NEXT:    v_fma_f64 v[2:3], v[12:13], v[6:7], v[10:11]
39; GFX10-NEXT:    v_fma_f64 v[0:1], v[14:15], v[4:5], v[8:9]
40; GFX10-NEXT:    s_setpc_b64 s[30:31]
41  %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")
42  ret <2 x double> %val
43}
44
45define <3 x double> @v_constained_fma_v3f64_fpexcept_strict(<3 x double> %x, <3 x double> %y, <3 x double> %z) #0 {
46; GCN-LABEL: v_constained_fma_v3f64_fpexcept_strict:
47; GCN:       ; %bb.0:
48; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
49; GCN-NEXT:    v_fma_f64 v[0:1], v[0:1], v[6:7], v[12:13]
50; GCN-NEXT:    v_fma_f64 v[2:3], v[2:3], v[8:9], v[14:15]
51; GCN-NEXT:    v_fma_f64 v[4:5], v[4:5], v[10:11], v[16:17]
52; GCN-NEXT:    s_setpc_b64 s[30:31]
53;
54; GFX10-LABEL: v_constained_fma_v3f64_fpexcept_strict:
55; GFX10:       ; %bb.0:
56; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
57; GFX10-NEXT:    s_waitcnt_vscnt null, 0x0
58; GFX10-NEXT:    v_fma_f64 v[0:1], v[0:1], v[6:7], v[12:13]
59; GFX10-NEXT:    v_fma_f64 v[2:3], v[2:3], v[8:9], v[14:15]
60; GFX10-NEXT:    v_fma_f64 v[4:5], v[4:5], v[10:11], v[16:17]
61; GFX10-NEXT:    s_setpc_b64 s[30:31]
62  %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")
63  ret <3 x double> %val
64}
65
66define <4 x double> @v_constained_fma_v4f64_fpexcept_strict(<4 x double> %x, <4 x double> %y, <4 x double> %z) #0 {
67; GCN-LABEL: v_constained_fma_v4f64_fpexcept_strict:
68; GCN:       ; %bb.0:
69; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
70; GCN-NEXT:    v_fma_f64 v[0:1], v[0:1], v[8:9], v[16:17]
71; GCN-NEXT:    v_fma_f64 v[2:3], v[2:3], v[10:11], v[18:19]
72; GCN-NEXT:    v_fma_f64 v[4:5], v[4:5], v[12:13], v[20:21]
73; GCN-NEXT:    v_fma_f64 v[6:7], v[6:7], v[14:15], v[22:23]
74; GCN-NEXT:    s_setpc_b64 s[30:31]
75;
76; GFX10-LABEL: v_constained_fma_v4f64_fpexcept_strict:
77; GFX10:       ; %bb.0:
78; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
79; GFX10-NEXT:    s_waitcnt_vscnt null, 0x0
80; GFX10-NEXT:    v_mov_b32_e32 v29, v7
81; GFX10-NEXT:    v_mov_b32_e32 v28, v6
82; GFX10-NEXT:    v_mov_b32_e32 v31, v5
83; GFX10-NEXT:    v_mov_b32_e32 v30, v4
84; GFX10-NEXT:    v_mov_b32_e32 v25, v3
85; GFX10-NEXT:    v_mov_b32_e32 v24, v2
86; GFX10-NEXT:    v_mov_b32_e32 v27, v1
87; GFX10-NEXT:    v_mov_b32_e32 v26, v0
88; GFX10-NEXT:    v_fma_f64 v[4:5], v[30:31], v[12:13], v[20:21]
89; GFX10-NEXT:    v_fma_f64 v[6:7], v[28:29], v[14:15], v[22:23]
90; GFX10-NEXT:    v_fma_f64 v[2:3], v[24:25], v[10:11], v[18:19]
91; GFX10-NEXT:    v_fma_f64 v[0:1], v[26:27], v[8:9], v[16:17]
92; GFX10-NEXT:    s_setpc_b64 s[30:31]
93  %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")
94  ret <4 x double> %val
95}
96
97define double @v_constained_fma_f64_fpexcept_strict_fneg(double %x, double %y, double %z) #0 {
98; GCN-LABEL: v_constained_fma_f64_fpexcept_strict_fneg:
99; GCN:       ; %bb.0:
100; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
101; GCN-NEXT:    v_fma_f64 v[0:1], v[0:1], v[2:3], -v[4:5]
102; GCN-NEXT:    s_setpc_b64 s[30:31]
103;
104; GFX10-LABEL: v_constained_fma_f64_fpexcept_strict_fneg:
105; GFX10:       ; %bb.0:
106; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
107; GFX10-NEXT:    s_waitcnt_vscnt null, 0x0
108; GFX10-NEXT:    v_fma_f64 v[0:1], v[0:1], v[2:3], -v[4:5]
109; GFX10-NEXT:    s_setpc_b64 s[30:31]
110  %neg.z = fneg double %z
111  %val = call double @llvm.experimental.constrained.fma.f64(double %x, double %y, double %neg.z, metadata !"round.tonearest", metadata !"fpexcept.strict")
112  ret double %val
113}
114
115define double @v_constained_fma_f64_fpexcept_strict_fneg_fneg(double %x, double %y, double %z) #0 {
116; GCN-LABEL: v_constained_fma_f64_fpexcept_strict_fneg_fneg:
117; GCN:       ; %bb.0:
118; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
119; GCN-NEXT:    v_fma_f64 v[0:1], -v[0:1], -v[2:3], v[4:5]
120; GCN-NEXT:    s_setpc_b64 s[30:31]
121;
122; GFX10-LABEL: v_constained_fma_f64_fpexcept_strict_fneg_fneg:
123; GFX10:       ; %bb.0:
124; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
125; GFX10-NEXT:    s_waitcnt_vscnt null, 0x0
126; GFX10-NEXT:    v_fma_f64 v[0:1], -v[0:1], -v[2:3], v[4:5]
127; GFX10-NEXT:    s_setpc_b64 s[30:31]
128  %neg.x = fneg double %x
129  %neg.y = fneg double %y
130  %val = call double @llvm.experimental.constrained.fma.f64(double %neg.x, double %neg.y, double %z, metadata !"round.tonearest", metadata !"fpexcept.strict")
131  ret double %val
132}
133
134define double @v_constained_fma_f64_fpexcept_strict_fabs_fabs(double %x, double %y, double %z) #0 {
135; GCN-LABEL: v_constained_fma_f64_fpexcept_strict_fabs_fabs:
136; GCN:       ; %bb.0:
137; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
138; GCN-NEXT:    v_fma_f64 v[0:1], |v[0:1]|, |v[2:3]|, v[4:5]
139; GCN-NEXT:    s_setpc_b64 s[30:31]
140;
141; GFX10-LABEL: v_constained_fma_f64_fpexcept_strict_fabs_fabs:
142; GFX10:       ; %bb.0:
143; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
144; GFX10-NEXT:    s_waitcnt_vscnt null, 0x0
145; GFX10-NEXT:    v_fma_f64 v[0:1], |v[0:1]|, |v[2:3]|, v[4:5]
146; GFX10-NEXT:    s_setpc_b64 s[30:31]
147  %neg.x = call double @llvm.fabs.f64(double %x)
148  %neg.y = call double @llvm.fabs.f64(double %y)
149  %val = call double @llvm.experimental.constrained.fma.f64(double %neg.x, double %neg.y, double %z, metadata !"round.tonearest", metadata !"fpexcept.strict")
150  ret double %val
151}
152
153define <2 x double> @v_constained_fma_v2f64_fpexcept_strict_fneg_fneg(<2 x double> %x, <2 x double> %y, <2 x double> %z) #0 {
154; GCN-LABEL: v_constained_fma_v2f64_fpexcept_strict_fneg_fneg:
155; GCN:       ; %bb.0:
156; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
157; GCN-NEXT:    v_fma_f64 v[0:1], -v[0:1], -v[4:5], v[8:9]
158; GCN-NEXT:    v_fma_f64 v[2:3], -v[2:3], -v[6:7], v[10:11]
159; GCN-NEXT:    s_setpc_b64 s[30:31]
160;
161; GFX10-LABEL: v_constained_fma_v2f64_fpexcept_strict_fneg_fneg:
162; GFX10:       ; %bb.0:
163; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
164; GFX10-NEXT:    s_waitcnt_vscnt null, 0x0
165; GFX10-NEXT:    v_mov_b32_e32 v13, v3
166; GFX10-NEXT:    v_mov_b32_e32 v12, v2
167; GFX10-NEXT:    v_mov_b32_e32 v15, v1
168; GFX10-NEXT:    v_mov_b32_e32 v14, v0
169; GFX10-NEXT:    v_fma_f64 v[2:3], -v[12:13], -v[6:7], v[10:11]
170; GFX10-NEXT:    v_fma_f64 v[0:1], -v[14:15], -v[4:5], v[8:9]
171; GFX10-NEXT:    s_setpc_b64 s[30:31]
172  %neg.x = fneg <2 x double> %x
173  %neg.y = fneg <2 x double> %y
174  %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")
175  ret <2 x double> %val
176}
177
178declare double @llvm.fabs.f64(double) #1
179declare double @llvm.experimental.constrained.fma.f64(double, double, double, metadata, metadata) #1
180declare <2 x double> @llvm.experimental.constrained.fma.v2f64(<2 x double>, <2 x double>, <2 x double>, metadata, metadata) #1
181declare <3 x double> @llvm.experimental.constrained.fma.v3f64(<3 x double>, <3 x double>, <3 x double>, metadata, metadata) #1
182declare <4 x double> @llvm.experimental.constrained.fma.v4f64(<4 x double>, <4 x double>, <4 x double>, metadata, metadata) #1
183
184attributes #0 = { strictfp }
185attributes #1 = { inaccessiblememonly nounwind willreturn }
186