1; RUN: llc -march=amdgcn -mcpu=tonga -denormal-fp-math-f32=preserve-sign -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefixes=GCN,GFX8 %s
2; RUN: llc -march=amdgcn -mcpu=tonga -denormal-fp-math-f32=ieee -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefixes=GCN,GFX8 %s
3; RUN: llc -march=amdgcn -mcpu=gfx900 -denormal-fp-math-f32=ieee -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefixes=GCN,GFX9 %s
4
5declare half @llvm.amdgcn.fmad.ftz.f16(half %a, half %b, half %c)
6
7; GCN-LABEL: {{^}}mad_f16:
8; GCN: v_mac_f16_e32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+$}}
9define amdgpu_kernel void @mad_f16(
10    half addrspace(1)* %r,
11    half addrspace(1)* %a,
12    half addrspace(1)* %b,
13    half addrspace(1)* %c) {
14  %a.val = load half, half addrspace(1)* %a
15  %b.val = load half, half addrspace(1)* %b
16  %c.val = load half, half addrspace(1)* %c
17  %r.val = call half @llvm.amdgcn.fmad.ftz.f16(half %a.val, half %b.val, half %c.val)
18  store half %r.val, half addrspace(1)* %r
19  ret void
20}
21
22; GCN-LABEL: {{^}}mad_f16_imm_a:
23; GCN: v_madmk_f16 {{v[0-9]+}}, {{v[0-9]+}}, 0x4800, {{v[0-9]+}}
24define amdgpu_kernel void @mad_f16_imm_a(
25    half addrspace(1)* %r,
26    half addrspace(1)* %b,
27    half addrspace(1)* %c) {
28  %b.val = load half, half addrspace(1)* %b
29  %c.val = load half, half addrspace(1)* %c
30  %r.val = call half @llvm.amdgcn.fmad.ftz.f16(half 8.0, half %b.val, half %c.val)
31  store half %r.val, half addrspace(1)* %r
32  ret void
33}
34
35; GCN-LABEL: {{^}}mad_f16_imm_b:
36; GCN: v_mac_f16_e32 {{v[0-9]+}}, 0x4800, {{v[0-9]+$}}
37define amdgpu_kernel void @mad_f16_imm_b(
38    half addrspace(1)* %r,
39    half addrspace(1)* %a,
40    half addrspace(1)* %c) {
41  %a.val = load half, half addrspace(1)* %a
42  %c.val = load half, half addrspace(1)* %c
43  %r.val = call half @llvm.amdgcn.fmad.ftz.f16(half %a.val, half 8.0, half %c.val)
44  store half %r.val, half addrspace(1)* %r
45  ret void
46}
47
48; GCN-LABEL: {{^}}mad_f16_imm_c:
49; GCN: v_madak_f16 {{v[0-9]+}}, {{v[0-9]+}}, {{v[0-9]+}}, 0x4800{{$}}
50define amdgpu_kernel void @mad_f16_imm_c(
51    half addrspace(1)* %r,
52    half addrspace(1)* %a,
53    half addrspace(1)* %b) {
54  %a.val = load half, half addrspace(1)* %a
55  %b.val = load half, half addrspace(1)* %b
56  %r.val = call half @llvm.amdgcn.fmad.ftz.f16(half %a.val, half %b.val, half 8.0)
57  store half %r.val, half addrspace(1)* %r
58  ret void
59}
60
61; GCN-LABEL: {{^}}mad_f16_neg_b:
62; GFX8: v_mad_f16 v{{[0-9]+}}, v{{[0-9]+}}, -v{{[0-9]+}}, v{{[0-9]+}}
63; GFX9: v_mad_legacy_f16 v{{[0-9]+}}, v{{[0-9]+}}, -v{{[0-9]+}}, v{{[0-9]+}}
64define amdgpu_kernel void @mad_f16_neg_b(
65    half addrspace(1)* %r,
66    half addrspace(1)* %a,
67    half addrspace(1)* %b,
68    half addrspace(1)* %c) {
69  %a.val = load half, half addrspace(1)* %a
70  %b.val = load half, half addrspace(1)* %b
71  %c.val = load half, half addrspace(1)* %c
72  %neg.b = fsub half -0.0, %b.val
73  %r.val = call half @llvm.amdgcn.fmad.ftz.f16(half %a.val, half %neg.b, half %c.val)
74  store half %r.val, half addrspace(1)* %r
75  ret void
76}
77
78; GCN-LABEL: {{^}}mad_f16_abs_b:
79; GFX8: v_mad_f16 v{{[0-9]+}}, v{{[0-9]+}}, |v{{[0-9]+}}|, v{{[0-9]+}}
80; GFX9: v_mad_legacy_f16 v{{[0-9]+}}, v{{[0-9]+}}, |v{{[0-9]+}}|, v{{[0-9]+}}
81define amdgpu_kernel void @mad_f16_abs_b(
82    half addrspace(1)* %r,
83    half addrspace(1)* %a,
84    half addrspace(1)* %b,
85    half addrspace(1)* %c) {
86  %a.val = load half, half addrspace(1)* %a
87  %b.val = load half, half addrspace(1)* %b
88  %c.val = load half, half addrspace(1)* %c
89  %abs.b = call half @llvm.fabs.f16(half %b.val)
90  %r.val = call half @llvm.amdgcn.fmad.ftz.f16(half %a.val, half %abs.b, half %c.val)
91  store half %r.val, half addrspace(1)* %r
92  ret void
93}
94
95; GCN-LABEL: {{^}}mad_f16_neg_abs_b:
96; GFX8: v_mad_f16 v{{[0-9]+}}, v{{[0-9]+}}, -|v{{[0-9]+}}|, v{{[0-9]+}}
97; GFX9: v_mad_legacy_f16 v{{[0-9]+}}, v{{[0-9]+}}, -|v{{[0-9]+}}|, v{{[0-9]+}}
98define amdgpu_kernel void @mad_f16_neg_abs_b(
99    half addrspace(1)* %r,
100    half addrspace(1)* %a,
101    half addrspace(1)* %b,
102    half addrspace(1)* %c) {
103  %a.val = load half, half addrspace(1)* %a
104  %b.val = load half, half addrspace(1)* %b
105  %c.val = load half, half addrspace(1)* %c
106  %abs.b = call half @llvm.fabs.f16(half %b.val)
107  %neg.abs.b = fsub half -0.0, %abs.b
108  %r.val = call half @llvm.amdgcn.fmad.ftz.f16(half %a.val, half %neg.abs.b, half %c.val)
109  store half %r.val, half addrspace(1)* %r
110  ret void
111}
112
113declare half @llvm.fabs.f16(half)
114