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