1; RUN: llc -march=amdgcn -verify-machineinstrs < %s | FileCheck -check-prefix=GCN %s
2; RUN: llc -march=amdgcn -mcpu=tonga -verify-machineinstrs < %s | FileCheck -check-prefix=GCN %s
3
4; GCN-LABEL: {{^}}test_fmed3:
5; GCN: v_med3_f32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
6define amdgpu_kernel void @test_fmed3(float addrspace(1)* %out, float %src0, float %src1, float %src2) #1 {
7  %med3 = call float @llvm.amdgcn.fmed3.f32(float %src0, float %src1, float %src2)
8  store float %med3, float addrspace(1)* %out
9  ret void
10}
11
12; GCN-LABEL: {{^}}test_fmed3_srcmods:
13; GCN: v_med3_f32 v{{[0-9]+}}, -s{{[0-9]+}}, |v{{[0-9]+}}|, -|v{{[0-9]+}}|
14define amdgpu_kernel void @test_fmed3_srcmods(float addrspace(1)* %out, float %src0, float %src1, float %src2) #1 {
15  %src0.fneg = fsub float -0.0, %src0
16  %src1.fabs = call float @llvm.fabs.f32(float %src1)
17  %src2.fabs = call float @llvm.fabs.f32(float %src2)
18  %src2.fneg.fabs = fsub float -0.0, %src2.fabs
19  %med3 = call float @llvm.amdgcn.fmed3.f32(float %src0.fneg, float %src1.fabs, float %src2.fneg.fabs)
20  store float %med3, float addrspace(1)* %out
21  ret void
22}
23
24; GCN-LABEL: {{^}}test_fneg_fmed3:
25; GCN: v_med3_f32 v{{[0-9]+}}, -s{{[0-9]+}}, -v{{[0-9]+}}, -v{{[0-9]+}}
26define amdgpu_kernel void @test_fneg_fmed3(float addrspace(1)* %out, float %src0, float %src1, float %src2) #1 {
27  %med3 = call float @llvm.amdgcn.fmed3.f32(float %src0, float %src1, float %src2)
28  %neg.med3 = fsub float -0.0, %med3
29  store float %neg.med3, float addrspace(1)* %out
30  ret void
31}
32
33; GCN-LABEL: {{^}}test_fneg_fmed3_multi_use:
34; GCN: v_med3_f32 [[MED3:v[0-9]+]], -s{{[0-9]+}}, -v{{[0-9]+}}, -v{{[0-9]+}}
35; GCN: v_mul_f32_e32 v{{[0-9]+}}, -4.0, [[MED3]]
36define amdgpu_kernel void @test_fneg_fmed3_multi_use(float addrspace(1)* %out, float %src0, float %src1, float %src2) #1 {
37  %med3 = call float @llvm.amdgcn.fmed3.f32(float %src0, float %src1, float %src2)
38  %neg.med3 = fsub float -0.0, %med3
39  %med3.user = fmul float %med3, 4.0
40  store volatile float %med3.user, float addrspace(1)* %out
41  store volatile float %neg.med3, float addrspace(1)* %out
42  ret void
43}
44
45; GCN-LABEL: {{^}}test_fabs_fmed3:
46; GCN: v_med3_f32 [[MED3:v[0-9]+]], s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
47; GCN: v_and_b32_e32 v{{[0-9]+}}, 0x7fffffff, [[MED3]]
48define amdgpu_kernel void @test_fabs_fmed3(float addrspace(1)* %out, float %src0, float %src1, float %src2) #1 {
49  %med3 = call float @llvm.amdgcn.fmed3.f32(float %src0, float %src1, float %src2)
50  %fabs.med3 = call float @llvm.fabs.f32(float %med3)
51  store float %fabs.med3, float addrspace(1)* %out
52  ret void
53}
54
55; GCN-LABEL: {{^}}test_fneg_fmed3_rr_0:
56; GCN: v_bfrev_b32_e32 [[NEG0:v[0-9]+]], 1
57; GCN: v_med3_f32 v{{[0-9]+}}, -s{{[0-9]+}}, -v{{[0-9]+}}, [[NEG0]]
58define amdgpu_kernel void @test_fneg_fmed3_rr_0(float addrspace(1)* %out, float %src0, float %src1) #1 {
59  %med3 = call float @llvm.amdgcn.fmed3.f32(float %src0, float %src1, float 0.0)
60  %neg.med3 = fsub float -0.0, %med3
61  store float %neg.med3, float addrspace(1)* %out
62  ret void
63}
64
65; FIXME: Worse off from folding this
66; GCN-LABEL: {{^}}test_fneg_fmed3_rr_0_foldable_user:
67; GCN: v_bfrev_b32_e32 [[NEG0:v[0-9]+]], 1
68; GCN: v_med3_f32 [[MED3:v[0-9]+]], -s{{[0-9]+}}, -v{{[0-9]+}}, [[NEG0]]
69; GCN: v_mul_f32_e32 v{{[0-9]+}}, s{{[0-9]+}}, [[MED3]]
70define amdgpu_kernel void @test_fneg_fmed3_rr_0_foldable_user(float addrspace(1)* %out, float %src0, float %src1, float %mul.arg) #1 {
71  %med3 = call float @llvm.amdgcn.fmed3.f32(float %src0, float %src1, float 0.0)
72  %neg.med3 = fsub float -0.0, %med3
73  %mul = fmul float %neg.med3, %mul.arg
74  store float %mul, float addrspace(1)* %out
75  ret void
76}
77
78; GCN-LABEL: {{^}}test_fneg_fmed3_r_inv2pi_0:
79; GCN-DAG: v_bfrev_b32_e32 [[NEG0:v[0-9]+]], 1
80; GCN-DAG: v_mov_b32_e32 [[NEG_INV:v[0-9]+]], 0xbe22f983
81; GCN: v_med3_f32 v{{[0-9]+}}, -s{{[0-9]+}}, [[NEG_INV]], [[NEG0]]
82define amdgpu_kernel void @test_fneg_fmed3_r_inv2pi_0(float addrspace(1)* %out, float %src0) #1 {
83  %med3 = call float @llvm.amdgcn.fmed3.f32(float %src0, float 0x3FC45F3060000000, float 0.0)
84  %neg.med3 = fsub float -0.0, %med3
85  store float %neg.med3, float addrspace(1)* %out
86  ret void
87}
88
89; GCN-LABEL: {{^}}test_fneg_fmed3_r_inv2pi_0_foldable_user:
90; GCN-DAG: v_bfrev_b32_e32 [[NEG0:v[0-9]+]], 1
91; GCN-DAG: v_mov_b32_e32 [[NEG_INV:v[0-9]+]], 0xbe22f983
92; GCN: v_med3_f32 [[MED3:v[0-9]+]], -s{{[0-9]+}}, [[NEG_INV]], [[NEG0]]
93; GCN: v_mul_f32_e32 v{{[0-9]+}}, s{{[0-9]+}}, [[MED3]]
94define amdgpu_kernel void @test_fneg_fmed3_r_inv2pi_0_foldable_user(float addrspace(1)* %out, float %src0, float %mul.arg) #1 {
95  %med3 = call float @llvm.amdgcn.fmed3.f32(float %src0, float 0x3FC45F3060000000, float 0.0)
96  %neg.med3 = fsub float -0.0, %med3
97  %mul = fmul float %neg.med3, %mul.arg
98  store float %mul, float addrspace(1)* %out
99  ret void
100}
101
102declare float @llvm.amdgcn.fmed3.f32(float, float, float) #0
103declare float @llvm.fabs.f32(float) #0
104
105attributes #0 = { nounwind readnone }
106attributes #1 = { nounwind }
107