1; RUN: llc -march=amdgcn -verify-machineinstrs < %s | FileCheck -check-prefix=NOSNAN -check-prefix=GCN %s 2; RUN: llc -march=amdgcn -mattr=+fp-exceptions -verify-machineinstrs < %s | FileCheck -check-prefix=SNAN -check-prefix=GCN %s 3 4declare i32 @llvm.amdgcn.workitem.id.x() #0 5declare float @llvm.minnum.f32(float, float) #0 6declare float @llvm.maxnum.f32(float, float) #0 7declare double @llvm.minnum.f64(double, double) #0 8declare double @llvm.maxnum.f64(double, double) #0 9 10; GCN-LABEL: {{^}}v_test_fmed3_r_i_i_f32: 11; NOSNAN: v_med3_f32 v{{[0-9]+}}, v{{[0-9]+}}, 2.0, 4.0 12 13; SNAN: v_max_f32_e32 v{{[0-9]+}}, 2.0, v{{[0-9]+}} 14; SNAN: v_min_f32_e32 v{{[0-9]+}}, 4.0, v{{[0-9]+}} 15define void @v_test_fmed3_r_i_i_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #1 { 16 %tid = call i32 @llvm.amdgcn.workitem.id.x() 17 %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid 18 %outgep = getelementptr float, float addrspace(1)* %out, i32 %tid 19 %a = load float, float addrspace(1)* %gep0 20 21 %max = call float @llvm.maxnum.f32(float %a, float 2.0) 22 %med = call float @llvm.minnum.f32(float %max, float 4.0) 23 24 store float %med, float addrspace(1)* %outgep 25 ret void 26} 27 28; GCN-LABEL: {{^}}v_test_fmed3_r_i_i_commute0_f32: 29; NOSNAN: v_med3_f32 v{{[0-9]+}}, v{{[0-9]+}}, 2.0, 4.0 30 31; SNAN: v_max_f32_e32 v{{[0-9]+}}, 2.0, v{{[0-9]+}} 32; SNAN: v_min_f32_e32 v{{[0-9]+}}, 4.0, v{{[0-9]+}} 33define void @v_test_fmed3_r_i_i_commute0_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #1 { 34 %tid = call i32 @llvm.amdgcn.workitem.id.x() 35 %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid 36 %outgep = getelementptr float, float addrspace(1)* %out, i32 %tid 37 %a = load float, float addrspace(1)* %gep0 38 39 %max = call float @llvm.maxnum.f32(float 2.0, float %a) 40 %med = call float @llvm.minnum.f32(float 4.0, float %max) 41 42 store float %med, float addrspace(1)* %outgep 43 ret void 44} 45 46; GCN-LABEL: {{^}}v_test_fmed3_r_i_i_commute1_f32: 47; NOSNAN: v_med3_f32 v{{[0-9]+}}, v{{[0-9]+}}, 2.0, 4.0 48 49; SNAN: v_max_f32_e32 v{{[0-9]+}}, 2.0, v{{[0-9]+}} 50; SNAN: v_min_f32_e32 v{{[0-9]+}}, 4.0, v{{[0-9]+}} 51define void @v_test_fmed3_r_i_i_commute1_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #1 { 52 %tid = call i32 @llvm.amdgcn.workitem.id.x() 53 %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid 54 %outgep = getelementptr float, float addrspace(1)* %out, i32 %tid 55 %a = load float, float addrspace(1)* %gep0 56 57 %max = call float @llvm.maxnum.f32(float %a, float 2.0) 58 %med = call float @llvm.minnum.f32(float 4.0, float %max) 59 60 store float %med, float addrspace(1)* %outgep 61 ret void 62} 63 64; GCN-LABEL: {{^}}v_test_fmed3_r_i_i_constant_order_f32: 65; GCN: v_max_f32_e32 v{{[0-9]+}}, 4.0, v{{[0-9]+}} 66; GCN: v_min_f32_e32 v{{[0-9]+}}, 2.0, v{{[0-9]+}} 67define void @v_test_fmed3_r_i_i_constant_order_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #1 { 68 %tid = call i32 @llvm.amdgcn.workitem.id.x() 69 %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid 70 %outgep = getelementptr float, float addrspace(1)* %out, i32 %tid 71 %a = load float, float addrspace(1)* %gep0 72 73 %max = call float @llvm.maxnum.f32(float %a, float 4.0) 74 %med = call float @llvm.minnum.f32(float %max, float 2.0) 75 76 store float %med, float addrspace(1)* %outgep 77 ret void 78} 79 80 81; GCN-LABEL: {{^}}v_test_fmed3_r_i_i_multi_use_f32: 82; GCN: v_max_f32_e32 v{{[0-9]+}}, 2.0, v{{[0-9]+}} 83; GCN: v_min_f32_e32 v{{[0-9]+}}, 4.0, v{{[0-9]+}} 84define void @v_test_fmed3_r_i_i_multi_use_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #1 { 85 %tid = call i32 @llvm.amdgcn.workitem.id.x() 86 %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid 87 %outgep = getelementptr float, float addrspace(1)* %out, i32 %tid 88 %a = load float, float addrspace(1)* %gep0 89 90 %max = call float @llvm.maxnum.f32(float %a, float 2.0) 91 %med = call float @llvm.minnum.f32(float %max, float 4.0) 92 93 store volatile float %med, float addrspace(1)* %outgep 94 store volatile float %max, float addrspace(1)* %outgep 95 ret void 96} 97 98; GCN-LABEL: {{^}}v_test_fmed3_r_i_i_f64: 99; GCN: v_max_f64 {{v\[[0-9]+:[0-9]+\]}}, {{v\[[0-9]+:[0-9]+\]}}, 2.0 100; GCN: v_min_f64 {{v\[[0-9]+:[0-9]+\]}}, {{v\[[0-9]+:[0-9]+\]}}, 4.0 101define void @v_test_fmed3_r_i_i_f64(double addrspace(1)* %out, double addrspace(1)* %aptr) #1 { 102 %tid = call i32 @llvm.amdgcn.workitem.id.x() 103 %gep0 = getelementptr double, double addrspace(1)* %aptr, i32 %tid 104 %outgep = getelementptr double, double addrspace(1)* %out, i32 %tid 105 %a = load double, double addrspace(1)* %gep0 106 107 %max = call double @llvm.maxnum.f64(double %a, double 2.0) 108 %med = call double @llvm.minnum.f64(double %max, double 4.0) 109 110 store double %med, double addrspace(1)* %outgep 111 ret void 112} 113 114; GCN-LABEL: {{^}}v_test_fmed3_r_i_i_no_nans_f32: 115; GCN: v_med3_f32 v{{[0-9]+}}, v{{[0-9]+}}, 2.0, 4.0 116define void @v_test_fmed3_r_i_i_no_nans_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #2 { 117 %tid = call i32 @llvm.amdgcn.workitem.id.x() 118 %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid 119 %outgep = getelementptr float, float addrspace(1)* %out, i32 %tid 120 %a = load float, float addrspace(1)* %gep0 121 122 %max = call float @llvm.maxnum.f32(float %a, float 2.0) 123 %med = call float @llvm.minnum.f32(float %max, float 4.0) 124 125 store float %med, float addrspace(1)* %outgep 126 ret void 127} 128 129; GCN-LABEL: {{^}}v_test_legacy_fmed3_r_i_i_f32: 130; NOSNAN: v_med3_f32 v{{[0-9]+}}, v{{[0-9]+}}, 2.0, 4.0 131 132; SNAN: v_max_f32_e32 v{{[0-9]+}}, 2.0, v{{[0-9]+}} 133; SNAN: v_min_f32_e32 v{{[0-9]+}}, 4.0, v{{[0-9]+}} 134define void @v_test_legacy_fmed3_r_i_i_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #1 { 135 %tid = call i32 @llvm.amdgcn.workitem.id.x() 136 %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid 137 %outgep = getelementptr float, float addrspace(1)* %out, i32 %tid 138 %a = load float, float addrspace(1)* %gep0 139 140 ; fmax_legacy 141 %cmp0 = fcmp ule float %a, 2.0 142 %max = select i1 %cmp0, float 2.0, float %a 143 144 ; fmin_legacy 145 %cmp1 = fcmp uge float %max, 4.0 146 %med = select i1 %cmp1, float 4.0, float %max 147 148 store float %med, float addrspace(1)* %outgep 149 ret void 150} 151 152attributes #0 = { nounwind readnone } 153attributes #1 = { nounwind "unsafe-fp-math"="false" "no-nans-fp-math"="false" } 154attributes #2 = { nounwind "unsafe-fp-math"="false" "no-nans-fp-math"="true" } 155