xref: /llvm-project/llvm/test/Transforms/InstCombine/AMDGPU/fmed3.ll (revision 8f3e64624c2e49b61ee578aec493260a59a35e80)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
2; Unknown/default target
3; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -passes=instcombine < %s | FileCheck -check-prefixes=NO-FMED3F16,UNKNOWN %s
4
5; Known target, no med3_f16
6; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -mcpu=fiji -passes=instcombine < %s | FileCheck -check-prefixes=NO-FMED3F16,GFX8 %s
7
8; Has med3_f16
9; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 -passes=instcombine < %s | FileCheck -check-prefixes=GFX9 %s
10
11
12declare float @llvm.fabs.f32(float) #0
13declare half @llvm.fabs.f16(half) #0
14declare float @llvm.amdgcn.fmed3.f32(float, float, float) #0
15
16define float @fmed3_f32_fpext_f16(half %arg0, half %arg1, half %arg2) #1 {
17; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16
18; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1:[0-9]+]] {
19; NO-FMED3F16-NEXT:    [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float
20; NO-FMED3F16-NEXT:    [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float
21; NO-FMED3F16-NEXT:    [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float
22; NO-FMED3F16-NEXT:    [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]])
23; NO-FMED3F16-NEXT:    ret float [[MED3]]
24;
25; GFX9-LABEL: define float @fmed3_f32_fpext_f16
26; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1:[0-9]+]] {
27; GFX9-NEXT:    [[MED31:%.*]] = call half @llvm.amdgcn.fmed3.f16(half [[ARG0]], half [[ARG1]], half [[ARG2]])
28; GFX9-NEXT:    [[MED3:%.*]] = fpext half [[MED31]] to float
29; GFX9-NEXT:    ret float [[MED3]]
30;
31  %arg0.ext = fpext half %arg0 to float
32  %arg1.ext = fpext half %arg1 to float
33  %arg2.ext = fpext half %arg2 to float
34  %med3 = call float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float %arg1.ext, float %arg2.ext)
35  ret float %med3
36}
37
38define float @fmed3_f32_fpext_f16_flags(half %arg0, half %arg1, half %arg2) #1 {
39; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_flags
40; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] {
41; NO-FMED3F16-NEXT:    [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float
42; NO-FMED3F16-NEXT:    [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float
43; NO-FMED3F16-NEXT:    [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float
44; NO-FMED3F16-NEXT:    [[MED3:%.*]] = call nsz float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]])
45; NO-FMED3F16-NEXT:    ret float [[MED3]]
46;
47; GFX9-LABEL: define float @fmed3_f32_fpext_f16_flags
48; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] {
49; GFX9-NEXT:    [[MED31:%.*]] = call nsz half @llvm.amdgcn.fmed3.f16(half [[ARG0]], half [[ARG1]], half [[ARG2]])
50; GFX9-NEXT:    [[MED3:%.*]] = fpext half [[MED31]] to float
51; GFX9-NEXT:    ret float [[MED3]]
52;
53  %arg0.ext = fpext half %arg0 to float
54  %arg1.ext = fpext half %arg1 to float
55  %arg2.ext = fpext half %arg2 to float
56  %med3 = call nsz float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float %arg1.ext, float %arg2.ext)
57  ret float %med3
58}
59
60define float @fmed3_f32_fpext_f16_k0(half %arg1, half %arg2) #1 {
61; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_k0
62; NO-FMED3F16-SAME: (half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] {
63; NO-FMED3F16-NEXT:    [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float
64; NO-FMED3F16-NEXT:    [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float
65; NO-FMED3F16-NEXT:    [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG1_EXT]], float [[ARG2_EXT]], float 2.000000e+00)
66; NO-FMED3F16-NEXT:    ret float [[MED3]]
67;
68; GFX9-LABEL: define float @fmed3_f32_fpext_f16_k0
69; GFX9-SAME: (half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] {
70; GFX9-NEXT:    [[MED31:%.*]] = call half @llvm.amdgcn.fmed3.f16(half [[ARG1]], half [[ARG2]], half 0xH4000)
71; GFX9-NEXT:    [[MED3:%.*]] = fpext half [[MED31]] to float
72; GFX9-NEXT:    ret float [[MED3]]
73;
74  %arg1.ext = fpext half %arg1 to float
75  %arg2.ext = fpext half %arg2 to float
76  %med3 = call float @llvm.amdgcn.fmed3.f32(float 2.0, float %arg1.ext, float %arg2.ext)
77  ret float %med3
78}
79
80define float @fmed3_f32_fpext_f16_k1(half %arg0, half %arg2) #1 {
81; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_k1
82; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] {
83; NO-FMED3F16-NEXT:    [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float
84; NO-FMED3F16-NEXT:    [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float
85; NO-FMED3F16-NEXT:    [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG2_EXT]], float 2.000000e+00)
86; NO-FMED3F16-NEXT:    ret float [[MED3]]
87;
88; GFX9-LABEL: define float @fmed3_f32_fpext_f16_k1
89; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] {
90; GFX9-NEXT:    [[MED31:%.*]] = call half @llvm.amdgcn.fmed3.f16(half [[ARG0]], half [[ARG2]], half 0xH4000)
91; GFX9-NEXT:    [[MED3:%.*]] = fpext half [[MED31]] to float
92; GFX9-NEXT:    ret float [[MED3]]
93;
94  %arg0.ext = fpext half %arg0 to float
95  %arg2.ext = fpext half %arg2 to float
96  %med3 = call float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float 2.0, float %arg2.ext)
97  ret float %med3
98}
99
100define float @fmed3_f32_fpext_f16_k2(half %arg0, half %arg1) #1 {
101; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_k2
102; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]]) #[[ATTR1]] {
103; NO-FMED3F16-NEXT:    [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float
104; NO-FMED3F16-NEXT:    [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float
105; NO-FMED3F16-NEXT:    [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float 2.000000e+00)
106; NO-FMED3F16-NEXT:    ret float [[MED3]]
107;
108; GFX9-LABEL: define float @fmed3_f32_fpext_f16_k2
109; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]]) #[[ATTR1]] {
110; GFX9-NEXT:    [[MED31:%.*]] = call half @llvm.amdgcn.fmed3.f16(half [[ARG0]], half [[ARG1]], half 0xH4000)
111; GFX9-NEXT:    [[MED3:%.*]] = fpext half [[MED31]] to float
112; GFX9-NEXT:    ret float [[MED3]]
113;
114  %arg0.ext = fpext half %arg0 to float
115  %arg1.ext = fpext half %arg1 to float
116  %med3 = call float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float %arg1.ext, float 2.0)
117  ret float %med3
118}
119
120define float @fmed3_f32_fpext_f16_k0_k1(half %arg2) #1 {
121; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_k0_k1
122; NO-FMED3F16-SAME: (half [[ARG2:%.*]]) #[[ATTR1]] {
123; NO-FMED3F16-NEXT:    [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float
124; NO-FMED3F16-NEXT:    [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG2_EXT]], float 0.000000e+00, float 1.600000e+01)
125; NO-FMED3F16-NEXT:    ret float [[MED3]]
126;
127; GFX9-LABEL: define float @fmed3_f32_fpext_f16_k0_k1
128; GFX9-SAME: (half [[ARG2:%.*]]) #[[ATTR1]] {
129; GFX9-NEXT:    [[MED31:%.*]] = call half @llvm.amdgcn.fmed3.f16(half [[ARG2]], half 0xH0000, half 0xH4C00)
130; GFX9-NEXT:    [[MED3:%.*]] = fpext half [[MED31]] to float
131; GFX9-NEXT:    ret float [[MED3]]
132;
133  %arg2.ext = fpext half %arg2 to float
134  %med3 = call float @llvm.amdgcn.fmed3.f32(float 0.0, float 16.0, float %arg2.ext)
135  ret float %med3
136}
137
138define float @fmed3_f32_fpext_f16_k0_k2(half %arg1) #1 {
139; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_k0_k2
140; NO-FMED3F16-SAME: (half [[ARG1:%.*]]) #[[ATTR1]] {
141; NO-FMED3F16-NEXT:    [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float
142; NO-FMED3F16-NEXT:    [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG1_EXT]], float 0.000000e+00, float 2.000000e+00)
143; NO-FMED3F16-NEXT:    ret float [[MED3]]
144;
145; GFX9-LABEL: define float @fmed3_f32_fpext_f16_k0_k2
146; GFX9-SAME: (half [[ARG1:%.*]]) #[[ATTR1]] {
147; GFX9-NEXT:    [[MED31:%.*]] = call half @llvm.amdgcn.fmed3.f16(half [[ARG1]], half 0xH0000, half 0xH4000)
148; GFX9-NEXT:    [[MED3:%.*]] = fpext half [[MED31]] to float
149; GFX9-NEXT:    ret float [[MED3]]
150;
151  %arg1.ext = fpext half %arg1 to float
152  %med3 = call float @llvm.amdgcn.fmed3.f32(float 0.0, float %arg1.ext, float 2.0)
153  ret float %med3
154}
155
156define float @fmed3_f32_fpext_f16_fabs(half %arg0, half %arg1, half %arg2) #1 {
157; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_fabs
158; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] {
159; NO-FMED3F16-NEXT:    [[FABS_ARG0:%.*]] = call half @llvm.fabs.f16(half [[ARG0]])
160; NO-FMED3F16-NEXT:    [[FABS_ARG1:%.*]] = call half @llvm.fabs.f16(half [[ARG1]])
161; NO-FMED3F16-NEXT:    [[FABS_ARG2:%.*]] = call half @llvm.fabs.f16(half [[ARG2]])
162; NO-FMED3F16-NEXT:    [[ARG0_EXT:%.*]] = fpext half [[FABS_ARG0]] to float
163; NO-FMED3F16-NEXT:    [[ARG1_EXT:%.*]] = fpext half [[FABS_ARG1]] to float
164; NO-FMED3F16-NEXT:    [[ARG2_EXT:%.*]] = fpext half [[FABS_ARG2]] to float
165; NO-FMED3F16-NEXT:    [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]])
166; NO-FMED3F16-NEXT:    ret float [[MED3]]
167;
168; GFX9-LABEL: define float @fmed3_f32_fpext_f16_fabs
169; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] {
170; GFX9-NEXT:    [[FABS_ARG0:%.*]] = call half @llvm.fabs.f16(half [[ARG0]])
171; GFX9-NEXT:    [[FABS_ARG1:%.*]] = call half @llvm.fabs.f16(half [[ARG1]])
172; GFX9-NEXT:    [[FABS_ARG2:%.*]] = call half @llvm.fabs.f16(half [[ARG2]])
173; GFX9-NEXT:    [[MED31:%.*]] = call half @llvm.amdgcn.fmed3.f16(half [[FABS_ARG0]], half [[FABS_ARG1]], half [[FABS_ARG2]])
174; GFX9-NEXT:    [[MED3:%.*]] = fpext half [[MED31]] to float
175; GFX9-NEXT:    ret float [[MED3]]
176;
177  %fabs.arg0 = call half @llvm.fabs.f16(half %arg0)
178  %fabs.arg1 = call half @llvm.fabs.f16(half %arg1)
179  %fabs.arg2 = call half @llvm.fabs.f16(half %arg2)
180  %arg0.ext = fpext half %fabs.arg0 to float
181  %arg1.ext = fpext half %fabs.arg1 to float
182  %arg2.ext = fpext half %fabs.arg2 to float
183  %med3 = call float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float %arg1.ext, float %arg2.ext)
184  ret float %med3
185}
186
187define float @fmed3_fabs_f32_fpext_f16(half %arg0, half %arg1, half %arg2) #1 {
188; NO-FMED3F16-LABEL: define float @fmed3_fabs_f32_fpext_f16
189; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] {
190; NO-FMED3F16-NEXT:    [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[ARG0]])
191; NO-FMED3F16-NEXT:    [[FABS_EXT_ARG0:%.*]] = fpext half [[TMP1]] to float
192; NO-FMED3F16-NEXT:    [[TMP2:%.*]] = call half @llvm.fabs.f16(half [[ARG1]])
193; NO-FMED3F16-NEXT:    [[FABS_EXT_ARG1:%.*]] = fpext half [[TMP2]] to float
194; NO-FMED3F16-NEXT:    [[TMP3:%.*]] = call half @llvm.fabs.f16(half [[ARG2]])
195; NO-FMED3F16-NEXT:    [[FABS_EXT_ARG2:%.*]] = fpext half [[TMP3]] to float
196; NO-FMED3F16-NEXT:    [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[FABS_EXT_ARG0]], float [[FABS_EXT_ARG1]], float [[FABS_EXT_ARG2]])
197; NO-FMED3F16-NEXT:    ret float [[MED3]]
198;
199; GFX9-LABEL: define float @fmed3_fabs_f32_fpext_f16
200; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] {
201; GFX9-NEXT:    [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[ARG0]])
202; GFX9-NEXT:    [[TMP2:%.*]] = call half @llvm.fabs.f16(half [[ARG1]])
203; GFX9-NEXT:    [[TMP3:%.*]] = call half @llvm.fabs.f16(half [[ARG2]])
204; GFX9-NEXT:    [[MED31:%.*]] = call half @llvm.amdgcn.fmed3.f16(half [[TMP1]], half [[TMP2]], half [[TMP3]])
205; GFX9-NEXT:    [[MED3:%.*]] = fpext half [[MED31]] to float
206; GFX9-NEXT:    ret float [[MED3]]
207;
208  %arg0.ext = fpext half %arg0 to float
209  %arg1.ext = fpext half %arg1 to float
210  %arg2.ext = fpext half %arg2 to float
211  %fabs.ext.arg0 = call float @llvm.fabs.f32(float %arg0.ext)
212  %fabs.ext.arg1 = call float @llvm.fabs.f32(float %arg1.ext)
213  %fabs.ext.arg2 = call float @llvm.fabs.f32(float %arg2.ext)
214  %med3 = call float @llvm.amdgcn.fmed3.f32(float %fabs.ext.arg0, float %fabs.ext.arg1, float %fabs.ext.arg2)
215  ret float %med3
216}
217
218define float @fmed3_f32_fpext_f16_fneg(half %arg0, half %arg1, half %arg2) #1 {
219; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_fneg
220; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] {
221; NO-FMED3F16-NEXT:    [[FNEG_ARG0:%.*]] = fneg half [[ARG0]]
222; NO-FMED3F16-NEXT:    [[FNEG_ARG1:%.*]] = fneg half [[ARG1]]
223; NO-FMED3F16-NEXT:    [[FNEG_ARG2:%.*]] = fneg half [[ARG2]]
224; NO-FMED3F16-NEXT:    [[ARG0_EXT:%.*]] = fpext half [[FNEG_ARG0]] to float
225; NO-FMED3F16-NEXT:    [[ARG1_EXT:%.*]] = fpext half [[FNEG_ARG1]] to float
226; NO-FMED3F16-NEXT:    [[ARG2_EXT:%.*]] = fpext half [[FNEG_ARG2]] to float
227; NO-FMED3F16-NEXT:    [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]])
228; NO-FMED3F16-NEXT:    ret float [[MED3]]
229;
230; GFX9-LABEL: define float @fmed3_f32_fpext_f16_fneg
231; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] {
232; GFX9-NEXT:    [[FNEG_ARG0:%.*]] = fneg half [[ARG0]]
233; GFX9-NEXT:    [[FNEG_ARG1:%.*]] = fneg half [[ARG1]]
234; GFX9-NEXT:    [[FNEG_ARG2:%.*]] = fneg half [[ARG2]]
235; GFX9-NEXT:    [[MED31:%.*]] = call half @llvm.amdgcn.fmed3.f16(half [[FNEG_ARG0]], half [[FNEG_ARG1]], half [[FNEG_ARG2]])
236; GFX9-NEXT:    [[MED3:%.*]] = fpext half [[MED31]] to float
237; GFX9-NEXT:    ret float [[MED3]]
238;
239  %fneg.arg0 = fneg half %arg0
240  %fneg.arg1 = fneg half %arg1
241  %fneg.arg2 = fneg half %arg2
242  %arg0.ext = fpext half %fneg.arg0 to float
243  %arg1.ext = fpext half %fneg.arg1 to float
244  %arg2.ext = fpext half %fneg.arg2 to float
245  %med3 = call float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float %arg1.ext, float %arg2.ext)
246  ret float %med3
247}
248
249define float @fmed3_fneg_f32_fpext_f16(half %arg0, half %arg1, half %arg2) #1 {
250; NO-FMED3F16-LABEL: define float @fmed3_fneg_f32_fpext_f16
251; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] {
252; NO-FMED3F16-NEXT:    [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float
253; NO-FMED3F16-NEXT:    [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float
254; NO-FMED3F16-NEXT:    [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float
255; NO-FMED3F16-NEXT:    [[FNEG_EXT_ARG0:%.*]] = fneg float [[ARG0_EXT]]
256; NO-FMED3F16-NEXT:    [[FNEG_EXT_ARG1:%.*]] = fneg float [[ARG1_EXT]]
257; NO-FMED3F16-NEXT:    [[FNEG_EXT_ARG2:%.*]] = fneg float [[ARG2_EXT]]
258; NO-FMED3F16-NEXT:    [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[FNEG_EXT_ARG0]], float [[FNEG_EXT_ARG1]], float [[FNEG_EXT_ARG2]])
259; NO-FMED3F16-NEXT:    ret float [[MED3]]
260;
261; GFX9-LABEL: define float @fmed3_fneg_f32_fpext_f16
262; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] {
263; GFX9-NEXT:    [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float
264; GFX9-NEXT:    [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float
265; GFX9-NEXT:    [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float
266; GFX9-NEXT:    [[FNEG_EXT_ARG0:%.*]] = fneg float [[ARG0_EXT]]
267; GFX9-NEXT:    [[FNEG_EXT_ARG1:%.*]] = fneg float [[ARG1_EXT]]
268; GFX9-NEXT:    [[FNEG_EXT_ARG2:%.*]] = fneg float [[ARG2_EXT]]
269; GFX9-NEXT:    [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[FNEG_EXT_ARG0]], float [[FNEG_EXT_ARG1]], float [[FNEG_EXT_ARG2]])
270; GFX9-NEXT:    ret float [[MED3]]
271;
272  %arg0.ext = fpext half %arg0 to float
273  %arg1.ext = fpext half %arg1 to float
274  %arg2.ext = fpext half %arg2 to float
275  %fneg.ext.arg0 = fneg float %arg0.ext
276  %fneg.ext.arg1 = fneg float %arg1.ext
277  %fneg.ext.arg2 = fneg float %arg2.ext
278  %med3 = call float @llvm.amdgcn.fmed3.f32(float %fneg.ext.arg0, float %fneg.ext.arg1, float %fneg.ext.arg2)
279  ret float %med3
280}
281
282define float @fmed3_f32_fpext_f16_fneg_fabs(half %arg0, half %arg1, half %arg2) #1 {
283; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_fneg_fabs
284; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] {
285; NO-FMED3F16-NEXT:    [[FABS_ARG0:%.*]] = call half @llvm.fabs.f16(half [[ARG0]])
286; NO-FMED3F16-NEXT:    [[FABS_ARG1:%.*]] = call half @llvm.fabs.f16(half [[ARG1]])
287; NO-FMED3F16-NEXT:    [[FABS_ARG2:%.*]] = call half @llvm.fabs.f16(half [[ARG2]])
288; NO-FMED3F16-NEXT:    [[FNEG_FABS_ARG0:%.*]] = fneg half [[FABS_ARG0]]
289; NO-FMED3F16-NEXT:    [[FNEG_FABS_ARG1:%.*]] = fneg half [[FABS_ARG1]]
290; NO-FMED3F16-NEXT:    [[FNEG_FABS_ARG2:%.*]] = fneg half [[FABS_ARG2]]
291; NO-FMED3F16-NEXT:    [[ARG0_EXT:%.*]] = fpext half [[FNEG_FABS_ARG0]] to float
292; NO-FMED3F16-NEXT:    [[ARG1_EXT:%.*]] = fpext half [[FNEG_FABS_ARG1]] to float
293; NO-FMED3F16-NEXT:    [[ARG2_EXT:%.*]] = fpext half [[FNEG_FABS_ARG2]] to float
294; NO-FMED3F16-NEXT:    [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]])
295; NO-FMED3F16-NEXT:    ret float [[MED3]]
296;
297; GFX9-LABEL: define float @fmed3_f32_fpext_f16_fneg_fabs
298; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] {
299; GFX9-NEXT:    [[FABS_ARG0:%.*]] = call half @llvm.fabs.f16(half [[ARG0]])
300; GFX9-NEXT:    [[FABS_ARG1:%.*]] = call half @llvm.fabs.f16(half [[ARG1]])
301; GFX9-NEXT:    [[FABS_ARG2:%.*]] = call half @llvm.fabs.f16(half [[ARG2]])
302; GFX9-NEXT:    [[FNEG_FABS_ARG0:%.*]] = fneg half [[FABS_ARG0]]
303; GFX9-NEXT:    [[FNEG_FABS_ARG1:%.*]] = fneg half [[FABS_ARG1]]
304; GFX9-NEXT:    [[FNEG_FABS_ARG2:%.*]] = fneg half [[FABS_ARG2]]
305; GFX9-NEXT:    [[MED31:%.*]] = call half @llvm.amdgcn.fmed3.f16(half [[FNEG_FABS_ARG0]], half [[FNEG_FABS_ARG1]], half [[FNEG_FABS_ARG2]])
306; GFX9-NEXT:    [[MED3:%.*]] = fpext half [[MED31]] to float
307; GFX9-NEXT:    ret float [[MED3]]
308;
309  %fabs.arg0 = call half @llvm.fabs.f16(half %arg0)
310  %fabs.arg1 = call half @llvm.fabs.f16(half %arg1)
311  %fabs.arg2 = call half @llvm.fabs.f16(half %arg2)
312  %fneg.fabs.arg0 = fneg half %fabs.arg0
313  %fneg.fabs.arg1 = fneg half %fabs.arg1
314  %fneg.fabs.arg2 = fneg half %fabs.arg2
315  %arg0.ext = fpext half %fneg.fabs.arg0 to float
316  %arg1.ext = fpext half %fneg.fabs.arg1 to float
317  %arg2.ext = fpext half %fneg.fabs.arg2 to float
318  %med3 = call float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float %arg1.ext, float %arg2.ext)
319  ret float %med3
320}
321
322define float @fmed3_fneg_fabs_f32_fpext_f16(half %arg0, half %arg1, half %arg2) #1 {
323; NO-FMED3F16-LABEL: define float @fmed3_fneg_fabs_f32_fpext_f16
324; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] {
325; NO-FMED3F16-NEXT:    [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[ARG0]])
326; NO-FMED3F16-NEXT:    [[FABS_EXT_ARG0:%.*]] = fpext half [[TMP1]] to float
327; NO-FMED3F16-NEXT:    [[TMP2:%.*]] = call half @llvm.fabs.f16(half [[ARG1]])
328; NO-FMED3F16-NEXT:    [[FABS_EXT_ARG1:%.*]] = fpext half [[TMP2]] to float
329; NO-FMED3F16-NEXT:    [[TMP3:%.*]] = call half @llvm.fabs.f16(half [[ARG2]])
330; NO-FMED3F16-NEXT:    [[FABS_EXT_ARG2:%.*]] = fpext half [[TMP3]] to float
331; NO-FMED3F16-NEXT:    [[FNEG_FABS_EXT_ARG0:%.*]] = fneg float [[FABS_EXT_ARG0]]
332; NO-FMED3F16-NEXT:    [[FNEG_FABS_EXT_ARG1:%.*]] = fneg float [[FABS_EXT_ARG1]]
333; NO-FMED3F16-NEXT:    [[FNEG_FABS_EXT_ARG2:%.*]] = fneg float [[FABS_EXT_ARG2]]
334; NO-FMED3F16-NEXT:    [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[FNEG_FABS_EXT_ARG0]], float [[FNEG_FABS_EXT_ARG1]], float [[FNEG_FABS_EXT_ARG2]])
335; NO-FMED3F16-NEXT:    ret float [[MED3]]
336;
337; GFX9-LABEL: define float @fmed3_fneg_fabs_f32_fpext_f16
338; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] {
339; GFX9-NEXT:    [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[ARG0]])
340; GFX9-NEXT:    [[FABS_EXT_ARG0:%.*]] = fpext half [[TMP1]] to float
341; GFX9-NEXT:    [[TMP2:%.*]] = call half @llvm.fabs.f16(half [[ARG1]])
342; GFX9-NEXT:    [[FABS_EXT_ARG1:%.*]] = fpext half [[TMP2]] to float
343; GFX9-NEXT:    [[TMP3:%.*]] = call half @llvm.fabs.f16(half [[ARG2]])
344; GFX9-NEXT:    [[FABS_EXT_ARG2:%.*]] = fpext half [[TMP3]] to float
345; GFX9-NEXT:    [[FNEG_FABS_EXT_ARG0:%.*]] = fneg float [[FABS_EXT_ARG0]]
346; GFX9-NEXT:    [[FNEG_FABS_EXT_ARG1:%.*]] = fneg float [[FABS_EXT_ARG1]]
347; GFX9-NEXT:    [[FNEG_FABS_EXT_ARG2:%.*]] = fneg float [[FABS_EXT_ARG2]]
348; GFX9-NEXT:    [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[FNEG_FABS_EXT_ARG0]], float [[FNEG_FABS_EXT_ARG1]], float [[FNEG_FABS_EXT_ARG2]])
349; GFX9-NEXT:    ret float [[MED3]]
350;
351  %arg0.ext = fpext half %arg0 to float
352  %arg1.ext = fpext half %arg1 to float
353  %arg2.ext = fpext half %arg2 to float
354  %fabs.ext.arg0 = call float @llvm.fabs.f32(float %arg0.ext)
355  %fabs.ext.arg1 = call float @llvm.fabs.f32(float %arg1.ext)
356  %fabs.ext.arg2 = call float @llvm.fabs.f32(float %arg2.ext)
357  %fneg.fabs.ext.arg0 = fneg float %fabs.ext.arg0
358  %fneg.fabs.ext.arg1 = fneg float %fabs.ext.arg1
359  %fneg.fabs.ext.arg2 = fneg float %fabs.ext.arg2
360  %med3 = call float @llvm.amdgcn.fmed3.f32(float %fneg.fabs.ext.arg0, float %fneg.fabs.ext.arg1, float %fneg.fabs.ext.arg2)
361  ret float %med3
362}
363
364; --------------------------------------------------------------------------------
365; Negative tests
366; --------------------------------------------------------------------------------
367
368define float @fmed3_f32_fpext_f16_multi_use_0(half %arg0, half %arg1, half %arg2, ptr addrspace(1) %ptr) #1 {
369; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_multi_use_0
370; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]], ptr addrspace(1) [[PTR:%.*]]) #[[ATTR1]] {
371; NO-FMED3F16-NEXT:    [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float
372; NO-FMED3F16-NEXT:    store float [[ARG0_EXT]], ptr addrspace(1) [[PTR]], align 4
373; NO-FMED3F16-NEXT:    [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float
374; NO-FMED3F16-NEXT:    [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float
375; NO-FMED3F16-NEXT:    [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]])
376; NO-FMED3F16-NEXT:    ret float [[MED3]]
377;
378; GFX9-LABEL: define float @fmed3_f32_fpext_f16_multi_use_0
379; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]], ptr addrspace(1) [[PTR:%.*]]) #[[ATTR1]] {
380; GFX9-NEXT:    [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float
381; GFX9-NEXT:    store float [[ARG0_EXT]], ptr addrspace(1) [[PTR]], align 4
382; GFX9-NEXT:    [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float
383; GFX9-NEXT:    [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float
384; GFX9-NEXT:    [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]])
385; GFX9-NEXT:    ret float [[MED3]]
386;
387  %arg0.ext = fpext half %arg0 to float
388  store float %arg0.ext, ptr addrspace(1) %ptr
389  %arg1.ext = fpext half %arg1 to float
390  %arg2.ext = fpext half %arg2 to float
391  %med3 = call float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float %arg1.ext, float %arg2.ext)
392  ret float %med3
393}
394
395define float @fmed3_f32_fpext_f16_multi_use_1(half %arg0, half %arg1, half %arg2, ptr addrspace(1) %ptr) #1 {
396; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_multi_use_1
397; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]], ptr addrspace(1) [[PTR:%.*]]) #[[ATTR1]] {
398; NO-FMED3F16-NEXT:    [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float
399; NO-FMED3F16-NEXT:    [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float
400; NO-FMED3F16-NEXT:    store float [[ARG1_EXT]], ptr addrspace(1) [[PTR]], align 4
401; NO-FMED3F16-NEXT:    [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float
402; NO-FMED3F16-NEXT:    [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]])
403; NO-FMED3F16-NEXT:    ret float [[MED3]]
404;
405; GFX9-LABEL: define float @fmed3_f32_fpext_f16_multi_use_1
406; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]], ptr addrspace(1) [[PTR:%.*]]) #[[ATTR1]] {
407; GFX9-NEXT:    [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float
408; GFX9-NEXT:    [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float
409; GFX9-NEXT:    store float [[ARG1_EXT]], ptr addrspace(1) [[PTR]], align 4
410; GFX9-NEXT:    [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float
411; GFX9-NEXT:    [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]])
412; GFX9-NEXT:    ret float [[MED3]]
413;
414  %arg0.ext = fpext half %arg0 to float
415  %arg1.ext = fpext half %arg1 to float
416  store float %arg1.ext, ptr addrspace(1) %ptr
417  %arg2.ext = fpext half %arg2 to float
418  %med3 = call float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float %arg1.ext, float %arg2.ext)
419  ret float %med3
420}
421
422define float @fmed3_f32_fpext_f16_multi_use_2(half %arg0, half %arg1, half %arg2, ptr addrspace(1) %ptr) #1 {
423; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_multi_use_2
424; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]], ptr addrspace(1) [[PTR:%.*]]) #[[ATTR1]] {
425; NO-FMED3F16-NEXT:    [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float
426; NO-FMED3F16-NEXT:    [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float
427; NO-FMED3F16-NEXT:    [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float
428; NO-FMED3F16-NEXT:    store float [[ARG2_EXT]], ptr addrspace(1) [[PTR]], align 4
429; NO-FMED3F16-NEXT:    [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]])
430; NO-FMED3F16-NEXT:    ret float [[MED3]]
431;
432; GFX9-LABEL: define float @fmed3_f32_fpext_f16_multi_use_2
433; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]], ptr addrspace(1) [[PTR:%.*]]) #[[ATTR1]] {
434; GFX9-NEXT:    [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float
435; GFX9-NEXT:    [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float
436; GFX9-NEXT:    [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float
437; GFX9-NEXT:    store float [[ARG2_EXT]], ptr addrspace(1) [[PTR]], align 4
438; GFX9-NEXT:    [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]])
439; GFX9-NEXT:    ret float [[MED3]]
440;
441  %arg0.ext = fpext half %arg0 to float
442  %arg1.ext = fpext half %arg1 to float
443  %arg2.ext = fpext half %arg2 to float
444  store float %arg2.ext, ptr addrspace(1) %ptr
445  %med3 = call float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float %arg1.ext, float %arg2.ext)
446  ret float %med3
447}
448
449define float @fmed3_f32_fpext_bf16(bfloat %arg0, bfloat %arg1, bfloat %arg2) #1 {
450; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_bf16
451; NO-FMED3F16-SAME: (bfloat [[ARG0:%.*]], bfloat [[ARG1:%.*]], bfloat [[ARG2:%.*]]) #[[ATTR1]] {
452; NO-FMED3F16-NEXT:    [[ARG0_EXT:%.*]] = fpext bfloat [[ARG0]] to float
453; NO-FMED3F16-NEXT:    [[ARG1_EXT:%.*]] = fpext bfloat [[ARG1]] to float
454; NO-FMED3F16-NEXT:    [[ARG2_EXT:%.*]] = fpext bfloat [[ARG2]] to float
455; NO-FMED3F16-NEXT:    [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]])
456; NO-FMED3F16-NEXT:    ret float [[MED3]]
457;
458; GFX9-LABEL: define float @fmed3_f32_fpext_bf16
459; GFX9-SAME: (bfloat [[ARG0:%.*]], bfloat [[ARG1:%.*]], bfloat [[ARG2:%.*]]) #[[ATTR1]] {
460; GFX9-NEXT:    [[ARG0_EXT:%.*]] = fpext bfloat [[ARG0]] to float
461; GFX9-NEXT:    [[ARG1_EXT:%.*]] = fpext bfloat [[ARG1]] to float
462; GFX9-NEXT:    [[ARG2_EXT:%.*]] = fpext bfloat [[ARG2]] to float
463; GFX9-NEXT:    [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]])
464; GFX9-NEXT:    ret float [[MED3]]
465;
466  %arg0.ext = fpext bfloat %arg0 to float
467  %arg1.ext = fpext bfloat %arg1 to float
468  %arg2.ext = fpext bfloat %arg2 to float
469  %med3 = call float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float %arg1.ext, float %arg2.ext)
470  ret float %med3
471}
472
473define float @fmed3_f32_fpext_f16_bf16_0(bfloat %arg0, half %arg1, half %arg2) #1 {
474; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_bf16_0
475; NO-FMED3F16-SAME: (bfloat [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] {
476; NO-FMED3F16-NEXT:    [[ARG0_EXT:%.*]] = fpext bfloat [[ARG0]] to float
477; NO-FMED3F16-NEXT:    [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float
478; NO-FMED3F16-NEXT:    [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float
479; NO-FMED3F16-NEXT:    [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]])
480; NO-FMED3F16-NEXT:    ret float [[MED3]]
481;
482; GFX9-LABEL: define float @fmed3_f32_fpext_f16_bf16_0
483; GFX9-SAME: (bfloat [[ARG0:%.*]], half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] {
484; GFX9-NEXT:    [[ARG0_EXT:%.*]] = fpext bfloat [[ARG0]] to float
485; GFX9-NEXT:    [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float
486; GFX9-NEXT:    [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float
487; GFX9-NEXT:    [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]])
488; GFX9-NEXT:    ret float [[MED3]]
489;
490  %arg0.ext = fpext bfloat %arg0 to float
491  %arg1.ext = fpext half %arg1 to float
492  %arg2.ext = fpext half %arg2 to float
493  %med3 = call float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float %arg1.ext, float %arg2.ext)
494  ret float %med3
495}
496
497define float @fmed3_f32_fpext_f16_bf16_1(half %arg0, bfloat %arg1, half %arg2) #1 {
498; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_bf16_1
499; NO-FMED3F16-SAME: (half [[ARG0:%.*]], bfloat [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] {
500; NO-FMED3F16-NEXT:    [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float
501; NO-FMED3F16-NEXT:    [[ARG1_EXT:%.*]] = fpext bfloat [[ARG1]] to float
502; NO-FMED3F16-NEXT:    [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float
503; NO-FMED3F16-NEXT:    [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]])
504; NO-FMED3F16-NEXT:    ret float [[MED3]]
505;
506; GFX9-LABEL: define float @fmed3_f32_fpext_f16_bf16_1
507; GFX9-SAME: (half [[ARG0:%.*]], bfloat [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] {
508; GFX9-NEXT:    [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float
509; GFX9-NEXT:    [[ARG1_EXT:%.*]] = fpext bfloat [[ARG1]] to float
510; GFX9-NEXT:    [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float
511; GFX9-NEXT:    [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]])
512; GFX9-NEXT:    ret float [[MED3]]
513;
514  %arg0.ext = fpext half %arg0 to float
515  %arg1.ext = fpext bfloat %arg1 to float
516  %arg2.ext = fpext half %arg2 to float
517  %med3 = call float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float %arg1.ext, float %arg2.ext)
518  ret float %med3
519}
520
521define float @fmed3_f32_fpext_f16_bf16_2(half %arg0, half %arg1, bfloat %arg2) #1 {
522; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_bf16_2
523; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], bfloat [[ARG2:%.*]]) #[[ATTR1]] {
524; NO-FMED3F16-NEXT:    [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float
525; NO-FMED3F16-NEXT:    [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float
526; NO-FMED3F16-NEXT:    [[ARG2_EXT:%.*]] = fpext bfloat [[ARG2]] to float
527; NO-FMED3F16-NEXT:    [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]])
528; NO-FMED3F16-NEXT:    ret float [[MED3]]
529;
530; GFX9-LABEL: define float @fmed3_f32_fpext_f16_bf16_2
531; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]], bfloat [[ARG2:%.*]]) #[[ATTR1]] {
532; GFX9-NEXT:    [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float
533; GFX9-NEXT:    [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float
534; GFX9-NEXT:    [[ARG2_EXT:%.*]] = fpext bfloat [[ARG2]] to float
535; GFX9-NEXT:    [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float [[ARG2_EXT]])
536; GFX9-NEXT:    ret float [[MED3]]
537;
538  %arg0.ext = fpext half %arg0 to float
539  %arg1.ext = fpext half %arg1 to float
540  %arg2.ext = fpext bfloat %arg2 to float
541  %med3 = call float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float %arg1.ext, float %arg2.ext)
542  ret float %med3
543}
544
545define float @fmed3_f32_fpext_f16_unrepresentable_k0(half %arg1, half %arg2) #1 {
546; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_unrepresentable_k0
547; NO-FMED3F16-SAME: (half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] {
548; NO-FMED3F16-NEXT:    [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float
549; NO-FMED3F16-NEXT:    [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float
550; NO-FMED3F16-NEXT:    [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG1_EXT]], float [[ARG2_EXT]], float 0x41F0000000000000)
551; NO-FMED3F16-NEXT:    ret float [[MED3]]
552;
553; GFX9-LABEL: define float @fmed3_f32_fpext_f16_unrepresentable_k0
554; GFX9-SAME: (half [[ARG1:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] {
555; GFX9-NEXT:    [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float
556; GFX9-NEXT:    [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float
557; GFX9-NEXT:    [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG1_EXT]], float [[ARG2_EXT]], float 0x41F0000000000000)
558; GFX9-NEXT:    ret float [[MED3]]
559;
560  %arg1.ext = fpext half %arg1 to float
561  %arg2.ext = fpext half %arg2 to float
562  %med3 = call float @llvm.amdgcn.fmed3.f32(float 0x41f0000000000000, float %arg1.ext, float %arg2.ext)
563  ret float %med3
564}
565
566define float @fmed3_f32_fpext_f16_unrepresentable_k1(half %arg0, half %arg2) #1 {
567; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_unrepresentable_k1
568; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] {
569; NO-FMED3F16-NEXT:    [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float
570; NO-FMED3F16-NEXT:    [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float
571; NO-FMED3F16-NEXT:    [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG2_EXT]], float 0x41F0000000000000)
572; NO-FMED3F16-NEXT:    ret float [[MED3]]
573;
574; GFX9-LABEL: define float @fmed3_f32_fpext_f16_unrepresentable_k1
575; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG2:%.*]]) #[[ATTR1]] {
576; GFX9-NEXT:    [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float
577; GFX9-NEXT:    [[ARG2_EXT:%.*]] = fpext half [[ARG2]] to float
578; GFX9-NEXT:    [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG2_EXT]], float 0x41F0000000000000)
579; GFX9-NEXT:    ret float [[MED3]]
580;
581  %arg0.ext = fpext half %arg0 to float
582  %arg2.ext = fpext half %arg2 to float
583  %med3 = call float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float 0x41f0000000000000, float %arg2.ext)
584  ret float %med3
585}
586
587define float @fmed3_f32_fpext_f16_unrepresentable_k2(half %arg0, half %arg1) #1 {
588; NO-FMED3F16-LABEL: define float @fmed3_f32_fpext_f16_unrepresentable_k2
589; NO-FMED3F16-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]]) #[[ATTR1]] {
590; NO-FMED3F16-NEXT:    [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float
591; NO-FMED3F16-NEXT:    [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float
592; NO-FMED3F16-NEXT:    [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float 0x41F0000000000000)
593; NO-FMED3F16-NEXT:    ret float [[MED3]]
594;
595; GFX9-LABEL: define float @fmed3_f32_fpext_f16_unrepresentable_k2
596; GFX9-SAME: (half [[ARG0:%.*]], half [[ARG1:%.*]]) #[[ATTR1]] {
597; GFX9-NEXT:    [[ARG0_EXT:%.*]] = fpext half [[ARG0]] to float
598; GFX9-NEXT:    [[ARG1_EXT:%.*]] = fpext half [[ARG1]] to float
599; GFX9-NEXT:    [[MED3:%.*]] = call float @llvm.amdgcn.fmed3.f32(float [[ARG0_EXT]], float [[ARG1_EXT]], float 0x41F0000000000000)
600; GFX9-NEXT:    ret float [[MED3]]
601;
602  %arg0.ext = fpext half %arg0 to float
603  %arg1.ext = fpext half %arg1 to float
604  %med3 = call float @llvm.amdgcn.fmed3.f32(float %arg0.ext, float %arg1.ext, float 0x41f0000000000000)
605  ret float %med3
606}
607
608
609attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
610attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn }
611;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
612; GFX8: {{.*}}
613; UNKNOWN: {{.*}}
614