1; RUN: llc -march=amdgcn -mcpu=tahiti -verify-machineinstrs < %s | FileCheck -check-prefix=GCN -check-prefix=FUNC %s 2; RUN: llc -march=amdgcn -mcpu=hawaii -verify-machineinstrs < %s | FileCheck -check-prefix=GCN -check-prefix=FUNC %s 3; RUN: llc -march=amdgcn -mcpu=fiji -verify-machineinstrs < %s | FileCheck -check-prefix=GCN -check-prefix=FUNC %s 4; RUN: llc -march=r600 -mcpu=redwood < %s | FileCheck -check-prefix=R600 -check-prefix=FUNC %s 5 6; These tests check that fdiv is expanded correctly and also test that the 7; scheduler is scheduling the RECIP_IEEE and MUL_IEEE instructions in separate 8; instruction groups. 9 10; These test check that fdiv using unsafe_fp_math, coarse fp div, and IEEE754 fp div. 11 12; FUNC-LABEL: {{^}}fdiv_f32: 13; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW]}}, KC0[2].W 14; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW]}}, KC0[2].Z, PS 15 16; GCN: v_div_scale_f32 [[NUM_SCALE:v[0-9]+]] 17; GCN-DAG: v_div_scale_f32 [[DEN_SCALE:v[0-9]+]] 18; GCN-DAG: v_rcp_f32_e32 [[NUM_RCP:v[0-9]+]], [[NUM_SCALE]] 19 20; GCN: s_setreg_imm32_b32 hwreg(HW_REG_MODE, 4, 2), 3 21; GCN: v_fma_f32 [[A:v[0-9]+]], -[[NUM_SCALE]], [[NUM_RCP]], 1.0 22; GCN: v_fma_f32 [[B:v[0-9]+]], [[A]], [[NUM_RCP]], [[NUM_RCP]] 23; GCN: v_mul_f32_e32 [[C:v[0-9]+]], [[B]], [[DEN_SCALE]] 24; GCN: v_fma_f32 [[D:v[0-9]+]], -[[NUM_SCALE]], [[C]], [[DEN_SCALE]] 25; GCN: v_fma_f32 [[E:v[0-9]+]], [[D]], [[B]], [[C]] 26; GCN: v_fma_f32 [[F:v[0-9]+]], -[[NUM_SCALE]], [[E]], [[DEN_SCALE]] 27; GCN: s_setreg_imm32_b32 hwreg(HW_REG_MODE, 4, 2), 0 28; GCN: v_div_fmas_f32 [[FMAS:v[0-9]+]], [[F]], [[B]], [[E]] 29; GCN: v_div_fixup_f32 v{{[0-9]+}}, [[FMAS]], 30define void @fdiv_f32(float addrspace(1)* %out, float %a, float %b) #0 { 31entry: 32 %fdiv = fdiv float %a, %b 33 store float %fdiv, float addrspace(1)* %out 34 ret void 35} 36 37; FUNC-LABEL: {{^}}fdiv_f32_denormals: 38; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW]}}, KC0[2].W 39; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW]}}, KC0[2].Z, PS 40 41; GCN: v_div_scale_f32 [[NUM_SCALE:v[0-9]+]] 42; GCN-DAG: v_div_scale_f32 [[DEN_SCALE:v[0-9]+]] 43; GCN-DAG: v_rcp_f32_e32 [[NUM_RCP:v[0-9]+]], [[NUM_SCALE]] 44 45; GCN-NOT: s_setreg 46; GCN: v_fma_f32 [[A:v[0-9]+]], -[[NUM_SCALE]], [[NUM_RCP]], 1.0 47; GCN: v_fma_f32 [[B:v[0-9]+]], [[A]], [[NUM_RCP]], [[NUM_RCP]] 48; GCN: v_mul_f32_e32 [[C:v[0-9]+]], [[B]], [[DEN_SCALE]] 49; GCN: v_fma_f32 [[D:v[0-9]+]], -[[NUM_SCALE]], [[C]], [[DEN_SCALE]] 50; GCN: v_fma_f32 [[E:v[0-9]+]], [[D]], [[B]], [[C]] 51; GCN: v_fma_f32 [[F:v[0-9]+]], -[[NUM_SCALE]], [[E]], [[DEN_SCALE]] 52; GCN-NOT: s_setreg 53; GCN: v_div_fmas_f32 [[FMAS:v[0-9]+]], [[F]], [[B]], [[E]] 54; GCN: v_div_fixup_f32 v{{[0-9]+}}, [[FMAS]], 55define void @fdiv_f32_denormals(float addrspace(1)* %out, float %a, float %b) #2 { 56entry: 57 %fdiv = fdiv float %a, %b 58 store float %fdiv, float addrspace(1)* %out 59 ret void 60} 61 62; FUNC-LABEL: {{^}}fdiv_25ulp_f32: 63; GCN: v_cndmask_b32 64; GCN: v_mul_f32 65; GCN: v_rcp_f32 66; GCN: v_mul_f32 67; GCN: v_mul_f32 68define void @fdiv_25ulp_f32(float addrspace(1)* %out, float %a, float %b) #0 { 69entry: 70 %fdiv = fdiv float %a, %b, !fpmath !0 71 store float %fdiv, float addrspace(1)* %out 72 ret void 73} 74 75; Use correct fdiv 76; FUNC-LABEL: {{^}}fdiv_25ulp_denormals_f32: 77; GCN: v_fma_f32 78; GCN: v_div_fmas_f32 79; GCN: v_div_fixup_f32 80define void @fdiv_25ulp_denormals_f32(float addrspace(1)* %out, float %a, float %b) #2 { 81entry: 82 %fdiv = fdiv float %a, %b, !fpmath !0 83 store float %fdiv, float addrspace(1)* %out 84 ret void 85} 86 87; FUNC-LABEL: {{^}}fdiv_fast_denormals_f32: 88; GCN: v_rcp_f32_e32 [[RCP:v[0-9]+]], s{{[0-9]+}} 89; GCN: v_mul_f32_e32 [[RESULT:v[0-9]+]], s{{[0-9]+}}, [[RCP]] 90; GCN-NOT: [[RESULT]] 91; GCN: buffer_store_dword [[RESULT]] 92define void @fdiv_fast_denormals_f32(float addrspace(1)* %out, float %a, float %b) #2 { 93entry: 94 %fdiv = fdiv fast float %a, %b 95 store float %fdiv, float addrspace(1)* %out 96 ret void 97} 98 99; FUNC-LABEL: {{^}}fdiv_f32_fast_math: 100; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW]}}, KC0[2].W 101; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW]}}, KC0[2].Z, PS 102 103; GCN: v_rcp_f32_e32 [[RCP:v[0-9]+]], s{{[0-9]+}} 104; GCN: v_mul_f32_e32 [[RESULT:v[0-9]+]], s{{[0-9]+}}, [[RCP]] 105; GCN-NOT: [[RESULT]] 106; GCN: buffer_store_dword [[RESULT]] 107define void @fdiv_f32_fast_math(float addrspace(1)* %out, float %a, float %b) #0 { 108entry: 109 %fdiv = fdiv fast float %a, %b 110 store float %fdiv, float addrspace(1)* %out 111 ret void 112} 113 114; FUNC-LABEL: {{^}}fdiv_f32_arcp_math: 115; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW]}}, KC0[2].W 116; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW]}}, KC0[2].Z, PS 117 118; GCN: v_rcp_f32_e32 [[RCP:v[0-9]+]], s{{[0-9]+}} 119; GCN: v_mul_f32_e32 [[RESULT:v[0-9]+]], s{{[0-9]+}}, [[RCP]] 120; GCN-NOT: [[RESULT]] 121; GCN: buffer_store_dword [[RESULT]] 122define void @fdiv_f32_arcp_math(float addrspace(1)* %out, float %a, float %b) #0 { 123entry: 124 %fdiv = fdiv arcp float %a, %b 125 store float %fdiv, float addrspace(1)* %out 126 ret void 127} 128 129; FUNC-LABEL: {{^}}fdiv_v2f32: 130; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW]}}, KC0[3].Z 131; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW]}}, KC0[3].Y 132; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW]}}, KC0[3].X, PS 133; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW]}}, KC0[2].W, PS 134 135; GCN: v_div_scale_f32 136; GCN: v_div_scale_f32 137; GCN: v_div_scale_f32 138; GCN: v_div_scale_f32 139define void @fdiv_v2f32(<2 x float> addrspace(1)* %out, <2 x float> %a, <2 x float> %b) #0 { 140entry: 141 %fdiv = fdiv <2 x float> %a, %b 142 store <2 x float> %fdiv, <2 x float> addrspace(1)* %out 143 ret void 144} 145 146; FUNC-LABEL: {{^}}fdiv_ulp25_v2f32: 147; GCN: v_cmp_gt_f32 148; GCN: v_cmp_gt_f32 149define void @fdiv_ulp25_v2f32(<2 x float> addrspace(1)* %out, <2 x float> %a, <2 x float> %b) #0 { 150entry: 151 %fdiv = fdiv arcp <2 x float> %a, %b, !fpmath !0 152 store <2 x float> %fdiv, <2 x float> addrspace(1)* %out 153 ret void 154} 155 156; FUNC-LABEL: {{^}}fdiv_v2f32_fast_math: 157; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW]}}, KC0[3].Z 158; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW]}}, KC0[3].Y 159; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW]}}, KC0[3].X, PS 160; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW]}}, KC0[2].W, PS 161 162; GCN: v_rcp_f32 163; GCN: v_rcp_f32 164define void @fdiv_v2f32_fast_math(<2 x float> addrspace(1)* %out, <2 x float> %a, <2 x float> %b) #0 { 165entry: 166 %fdiv = fdiv fast <2 x float> %a, %b 167 store <2 x float> %fdiv, <2 x float> addrspace(1)* %out 168 ret void 169} 170 171; FUNC-LABEL: {{^}}fdiv_v2f32_arcp_math: 172; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW]}}, KC0[3].Z 173; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW]}}, KC0[3].Y 174; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW]}}, KC0[3].X, PS 175; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW]}}, KC0[2].W, PS 176 177; GCN: v_rcp_f32 178; GCN: v_rcp_f32 179define void @fdiv_v2f32_arcp_math(<2 x float> addrspace(1)* %out, <2 x float> %a, <2 x float> %b) #0 { 180entry: 181 %fdiv = fdiv arcp <2 x float> %a, %b 182 store <2 x float> %fdiv, <2 x float> addrspace(1)* %out 183 ret void 184} 185 186; FUNC-LABEL: {{^}}fdiv_v4f32: 187; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} 188; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} 189; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} 190; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} 191; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}, PS 192; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}, PS 193; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}, PS 194; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}, PS 195 196; GCN: v_div_fixup_f32 197; GCN: v_div_fixup_f32 198; GCN: v_div_fixup_f32 199; GCN: v_div_fixup_f32 200define void @fdiv_v4f32(<4 x float> addrspace(1)* %out, <4 x float> addrspace(1)* %in) #0 { 201 %b_ptr = getelementptr <4 x float>, <4 x float> addrspace(1)* %in, i32 1 202 %a = load <4 x float>, <4 x float> addrspace(1) * %in 203 %b = load <4 x float>, <4 x float> addrspace(1) * %b_ptr 204 %result = fdiv <4 x float> %a, %b 205 store <4 x float> %result, <4 x float> addrspace(1)* %out 206 ret void 207} 208 209; FUNC-LABEL: {{^}}fdiv_v4f32_fast_math: 210; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} 211; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} 212; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} 213; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} 214; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}, PS 215; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}, PS 216; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}, PS 217; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}, PS 218 219; GCN: v_rcp_f32 220; GCN: v_rcp_f32 221; GCN: v_rcp_f32 222; GCN: v_rcp_f32 223define void @fdiv_v4f32_fast_math(<4 x float> addrspace(1)* %out, <4 x float> addrspace(1)* %in) #0 { 224 %b_ptr = getelementptr <4 x float>, <4 x float> addrspace(1)* %in, i32 1 225 %a = load <4 x float>, <4 x float> addrspace(1) * %in 226 %b = load <4 x float>, <4 x float> addrspace(1) * %b_ptr 227 %result = fdiv fast <4 x float> %a, %b 228 store <4 x float> %result, <4 x float> addrspace(1)* %out 229 ret void 230} 231 232; FUNC-LABEL: {{^}}fdiv_v4f32_arcp_math: 233; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} 234; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} 235; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} 236; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} 237; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}, PS 238; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}, PS 239; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}, PS 240; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}, PS 241 242; GCN: v_rcp_f32 243; GCN: v_rcp_f32 244; GCN: v_rcp_f32 245; GCN: v_rcp_f32 246define void @fdiv_v4f32_arcp_math(<4 x float> addrspace(1)* %out, <4 x float> addrspace(1)* %in) #0 { 247 %b_ptr = getelementptr <4 x float>, <4 x float> addrspace(1)* %in, i32 1 248 %a = load <4 x float>, <4 x float> addrspace(1) * %in 249 %b = load <4 x float>, <4 x float> addrspace(1) * %b_ptr 250 %result = fdiv arcp <4 x float> %a, %b 251 store <4 x float> %result, <4 x float> addrspace(1)* %out 252 ret void 253} 254 255attributes #0 = { nounwind "enable-unsafe-fp-math"="false" "target-features"="-fp32-denormals" } 256attributes #1 = { nounwind "enable-unsafe-fp-math"="true" "target-features"="-fp32-denormals" } 257attributes #2 = { nounwind "enable-unsafe-fp-math"="false" "target-features"="+fp32-denormals" } 258 259!0 = !{float 2.500000e+00} 260