1; RUN: opt -S -mtriple=amdgcn-- -amdgpu-codegenprepare %s | FileCheck %s 2; RUN: opt -S -amdgpu-codegenprepare %s | FileCheck -check-prefix=NOOP %s 3; Make sure this doesn't crash with no triple 4 5; NOOP-LABEL: @noop_fdiv_fpmath( 6; NOOP: %md.25ulp = fdiv float %a, %b, !fpmath !0 7define void @noop_fdiv_fpmath(float addrspace(1)* %out, float %a, float %b) #3 { 8 %md.25ulp = fdiv float %a, %b, !fpmath !0 9 store volatile float %md.25ulp, float addrspace(1)* %out 10 ret void 11} 12 13; CHECK-LABEL: @fdiv_fpmath( 14; CHECK: %no.md = fdiv float %a, %b{{$}} 15; CHECK: %md.half.ulp = fdiv float %a, %b, !fpmath !1 16; CHECK: %md.1ulp = fdiv float %a, %b, !fpmath !2 17; CHECK: %md.25ulp = call float @llvm.amdgcn.fdiv.fast(float %a, float %b), !fpmath !0 18; CHECK: %md.3ulp = call float @llvm.amdgcn.fdiv.fast(float %a, float %b), !fpmath !3 19; CHECK: %fast.md.25ulp = call fast float @llvm.amdgcn.fdiv.fast(float %a, float %b), !fpmath !0 20; CHECK: arcp.md.25ulp = call arcp float @llvm.amdgcn.fdiv.fast(float %a, float %b), !fpmath !0 21define void @fdiv_fpmath(float addrspace(1)* %out, float %a, float %b) #1 { 22 %no.md = fdiv float %a, %b 23 store volatile float %no.md, float addrspace(1)* %out 24 25 %md.half.ulp = fdiv float %a, %b, !fpmath !1 26 store volatile float %md.half.ulp, float addrspace(1)* %out 27 28 %md.1ulp = fdiv float %a, %b, !fpmath !2 29 store volatile float %md.1ulp, float addrspace(1)* %out 30 31 %md.25ulp = fdiv float %a, %b, !fpmath !0 32 store volatile float %md.25ulp, float addrspace(1)* %out 33 34 %md.3ulp = fdiv float %a, %b, !fpmath !3 35 store volatile float %md.3ulp, float addrspace(1)* %out 36 37 %fast.md.25ulp = fdiv fast float %a, %b, !fpmath !0 38 store volatile float %fast.md.25ulp, float addrspace(1)* %out 39 40 %arcp.md.25ulp = fdiv arcp float %a, %b, !fpmath !0 41 store volatile float %arcp.md.25ulp, float addrspace(1)* %out 42 43 ret void 44} 45 46; CHECK-LABEL: @rcp_fdiv_fpmath( 47; CHECK: %no.md = fdiv float 1.000000e+00, %x{{$}} 48; CHECK: %md.25ulp = fdiv float 1.000000e+00, %x, !fpmath !0 49; CHECK: %md.half.ulp = fdiv float 1.000000e+00, %x, !fpmath !1 50; CHECK: %arcp.no.md = fdiv arcp float 1.000000e+00, %x{{$}} 51; CHECK: %arcp.25ulp = fdiv arcp float 1.000000e+00, %x, !fpmath !0 52; CHECK: %fast.no.md = fdiv fast float 1.000000e+00, %x{{$}} 53; CHECK: %fast.25ulp = fdiv fast float 1.000000e+00, %x, !fpmath !0 54define void @rcp_fdiv_fpmath(float addrspace(1)* %out, float %x) #1 { 55 %no.md = fdiv float 1.0, %x 56 store volatile float %no.md, float addrspace(1)* %out 57 58 %md.25ulp = fdiv float 1.0, %x, !fpmath !0 59 store volatile float %md.25ulp, float addrspace(1)* %out 60 61 %md.half.ulp = fdiv float 1.0, %x, !fpmath !1 62 store volatile float %md.half.ulp, float addrspace(1)* %out 63 64 %arcp.no.md = fdiv arcp float 1.0, %x 65 store volatile float %arcp.no.md, float addrspace(1)* %out 66 67 %arcp.25ulp = fdiv arcp float 1.0, %x, !fpmath !0 68 store volatile float %arcp.25ulp, float addrspace(1)* %out 69 70 %fast.no.md = fdiv fast float 1.0, %x 71 store volatile float %fast.no.md, float addrspace(1)* %out 72 73 %fast.25ulp = fdiv fast float 1.0, %x, !fpmath !0 74 store volatile float %fast.25ulp, float addrspace(1)* %out 75 76 ret void 77} 78 79; CHECK-LABEL: @fdiv_fpmath_vector( 80; CHECK: %no.md = fdiv <2 x float> %a, %b{{$}} 81; CHECK: %md.half.ulp = fdiv <2 x float> %a, %b, !fpmath !1 82; CHECK: %md.1ulp = fdiv <2 x float> %a, %b, !fpmath !2 83 84; CHECK: %[[A0:[0-9]+]] = extractelement <2 x float> %a, i64 0 85; CHECK: %[[B0:[0-9]+]] = extractelement <2 x float> %b, i64 0 86; CHECK: %[[FDIV0:[0-9]+]] = call float @llvm.amdgcn.fdiv.fast(float %[[A0]], float %[[B0]]), !fpmath !0 87; CHECK: %[[INS0:[0-9]+]] = insertelement <2 x float> undef, float %[[FDIV0]], i64 0 88; CHECK: %[[A1:[0-9]+]] = extractelement <2 x float> %a, i64 1 89; CHECK: %[[B1:[0-9]+]] = extractelement <2 x float> %b, i64 1 90; CHECK: %[[FDIV1:[0-9]+]] = call float @llvm.amdgcn.fdiv.fast(float %[[A1]], float %[[B1]]), !fpmath !0 91; CHECK: %md.25ulp = insertelement <2 x float> %[[INS0]], float %[[FDIV1]], i64 1 92define void @fdiv_fpmath_vector(<2 x float> addrspace(1)* %out, <2 x float> %a, <2 x float> %b) #1 { 93 %no.md = fdiv <2 x float> %a, %b 94 store volatile <2 x float> %no.md, <2 x float> addrspace(1)* %out 95 96 %md.half.ulp = fdiv <2 x float> %a, %b, !fpmath !1 97 store volatile <2 x float> %md.half.ulp, <2 x float> addrspace(1)* %out 98 99 %md.1ulp = fdiv <2 x float> %a, %b, !fpmath !2 100 store volatile <2 x float> %md.1ulp, <2 x float> addrspace(1)* %out 101 102 %md.25ulp = fdiv <2 x float> %a, %b, !fpmath !0 103 store volatile <2 x float> %md.25ulp, <2 x float> addrspace(1)* %out 104 105 ret void 106} 107 108; CHECK-LABEL: @rcp_fdiv_fpmath_vector( 109; CHECK: %no.md = fdiv <2 x float> <float 1.000000e+00, float 1.000000e+00>, %x{{$}} 110; CHECK: %md.half.ulp = fdiv <2 x float> <float 1.000000e+00, float 1.000000e+00>, %x, !fpmath !1 111; CHECK: %arcp.no.md = fdiv arcp <2 x float> <float 1.000000e+00, float 1.000000e+00>, %x{{$}} 112; CHECK: %fast.no.md = fdiv fast <2 x float> <float 1.000000e+00, float 1.000000e+00>, %x{{$}} 113 114; CHECK: extractelement <2 x float> %x 115; CHECK: fdiv arcp float 1.000000e+00, %{{[0-9]+}}, !fpmath !0 116; CHECK: extractelement <2 x float> %x 117; CHECK: fdiv arcp float 1.000000e+00, %{{[0-9]+}}, !fpmath !0 118; CHECK: store volatile <2 x float> %arcp.25ulp 119 120; CHECK: fdiv fast float 1.000000e+00, %{{[0-9]+}}, !fpmath !0 121; CHECK: fdiv fast float 1.000000e+00, %{{[0-9]+}}, !fpmath !0 122; CHECK: store volatile <2 x float> %fast.25ulp, <2 x float> addrspace(1)* %out 123define void @rcp_fdiv_fpmath_vector(<2 x float> addrspace(1)* %out, <2 x float> %x) #1 { 124 %no.md = fdiv <2 x float> <float 1.0, float 1.0>, %x 125 store volatile <2 x float> %no.md, <2 x float> addrspace(1)* %out 126 127 %md.half.ulp = fdiv <2 x float> <float 1.0, float 1.0>, %x, !fpmath !1 128 store volatile <2 x float> %md.half.ulp, <2 x float> addrspace(1)* %out 129 130 %arcp.no.md = fdiv arcp <2 x float> <float 1.0, float 1.0>, %x 131 store volatile <2 x float> %arcp.no.md, <2 x float> addrspace(1)* %out 132 133 %fast.no.md = fdiv fast <2 x float> <float 1.0, float 1.0>, %x 134 store volatile <2 x float> %fast.no.md, <2 x float> addrspace(1)* %out 135 136 %arcp.25ulp = fdiv arcp <2 x float> <float 1.0, float 1.0>, %x, !fpmath !0 137 store volatile <2 x float> %arcp.25ulp, <2 x float> addrspace(1)* %out 138 139 %fast.25ulp = fdiv fast <2 x float> <float 1.0, float 1.0>, %x, !fpmath !0 140 store volatile <2 x float> %fast.25ulp, <2 x float> addrspace(1)* %out 141 142 ret void 143} 144 145; CHECK-LABEL: @rcp_fdiv_fpmath_vector_nonsplat( 146; CHECK: %no.md = fdiv <2 x float> <float 1.000000e+00, float 2.000000e+00>, %x 147; CHECK: %arcp.no.md = fdiv arcp <2 x float> <float 1.000000e+00, float 2.000000e+00>, %x 148; CHECK: %fast.no.md = fdiv fast <2 x float> <float 1.000000e+00, float 2.000000e+00>, %x{{$}} 149 150; CHECK: %[[X0:[0-9]+]] = extractelement <2 x float> %x, i64 0 151; CHECK: fdiv arcp float 1.000000e+00, %[[X0]], !fpmath !0 152; CHECK: %[[X1:[0-9]+]] = extractelement <2 x float> %x, i64 1 153; CHECK: fdiv arcp float 2.000000e+00, %[[X1]], !fpmath !0 154; CHECK: store volatile <2 x float> %arcp.25ulp 155 156; CHECK: %[[X0:[0-9]+]] = extractelement <2 x float> %x, i64 0 157; CHECK: fdiv fast float 1.000000e+00, %[[X0]], !fpmath !0 158; CHECK: %[[X1:[0-9]+]] = extractelement <2 x float> %x, i64 1 159; CHECK: fdiv fast float 2.000000e+00, %[[X1]], !fpmath !0 160; CHECK: store volatile <2 x float> %fast.25ulp 161define void @rcp_fdiv_fpmath_vector_nonsplat(<2 x float> addrspace(1)* %out, <2 x float> %x) #1 { 162 %no.md = fdiv <2 x float> <float 1.0, float 2.0>, %x 163 store volatile <2 x float> %no.md, <2 x float> addrspace(1)* %out 164 165 %arcp.no.md = fdiv arcp <2 x float> <float 1.0, float 2.0>, %x 166 store volatile <2 x float> %arcp.no.md, <2 x float> addrspace(1)* %out 167 168 %fast.no.md = fdiv fast <2 x float> <float 1.0, float 2.0>, %x 169 store volatile <2 x float> %fast.no.md, <2 x float> addrspace(1)* %out 170 171 %arcp.25ulp = fdiv arcp <2 x float> <float 1.0, float 2.0>, %x, !fpmath !0 172 store volatile <2 x float> %arcp.25ulp, <2 x float> addrspace(1)* %out 173 174 %fast.25ulp = fdiv fast <2 x float> <float 1.0, float 2.0>, %x, !fpmath !0 175 store volatile <2 x float> %fast.25ulp, <2 x float> addrspace(1)* %out 176 177 ret void 178} 179 180; FIXME: Should be able to get fdiv for 1.0 component 181; CHECK-LABEL: @rcp_fdiv_fpmath_vector_partial_constant( 182; CHECK: call arcp float @llvm.amdgcn.fdiv.fast(float %{{[0-9]+}}, float %{{[0-9]+}}), !fpmath !0 183; CHECK: call arcp float @llvm.amdgcn.fdiv.fast(float %{{[0-9]+}}, float %{{[0-9]+}}), !fpmath !0 184; CHECK: store volatile <2 x float> %arcp.25ulp 185 186; CHECK: call fast float @llvm.amdgcn.fdiv.fast(float %{{[0-9]+}}, float %{{[0-9]+}}), !fpmath !0 187; CHECK: call fast float @llvm.amdgcn.fdiv.fast(float %{{[0-9]+}}, float %{{[0-9]+}}), !fpmath !0 188; CHECK: store volatile <2 x float> %fast.25ulp 189define void @rcp_fdiv_fpmath_vector_partial_constant(<2 x float> addrspace(1)* %out, <2 x float> %x, <2 x float> %y) #1 { 190 %x.insert = insertelement <2 x float> %x, float 1.0, i32 0 191 192 %arcp.25ulp = fdiv arcp <2 x float> %x.insert, %y, !fpmath !0 193 store volatile <2 x float> %arcp.25ulp, <2 x float> addrspace(1)* %out 194 195 %fast.25ulp = fdiv fast <2 x float> %x.insert, %y, !fpmath !0 196 store volatile <2 x float> %fast.25ulp, <2 x float> addrspace(1)* %out 197 198 ret void 199} 200 201; CHECK-LABEL: @fdiv_fpmath_f32_denormals( 202; CHECK: %no.md = fdiv float %a, %b{{$}} 203; CHECK: %md.half.ulp = fdiv float %a, %b, !fpmath !1 204; CHECK: %md.1ulp = fdiv float %a, %b, !fpmath !2 205; CHECK: %md.25ulp = fdiv float %a, %b, !fpmath !0 206; CHECK: %md.3ulp = fdiv float %a, %b, !fpmath !3 207; CHECK: call fast float @llvm.amdgcn.fdiv.fast(float %a, float %b), !fpmath !0 208; CHECK: call arcp float @llvm.amdgcn.fdiv.fast(float %a, float %b), !fpmath !0 209define void @fdiv_fpmath_f32_denormals(float addrspace(1)* %out, float %a, float %b) #2 { 210 %no.md = fdiv float %a, %b 211 store volatile float %no.md, float addrspace(1)* %out 212 213 %md.half.ulp = fdiv float %a, %b, !fpmath !1 214 store volatile float %md.half.ulp, float addrspace(1)* %out 215 216 %md.1ulp = fdiv float %a, %b, !fpmath !2 217 store volatile float %md.1ulp, float addrspace(1)* %out 218 219 %md.25ulp = fdiv float %a, %b, !fpmath !0 220 store volatile float %md.25ulp, float addrspace(1)* %out 221 222 %md.3ulp = fdiv float %a, %b, !fpmath !3 223 store volatile float %md.3ulp, float addrspace(1)* %out 224 225 %fast.md.25ulp = fdiv fast float %a, %b, !fpmath !0 226 store volatile float %fast.md.25ulp, float addrspace(1)* %out 227 228 %arcp.md.25ulp = fdiv arcp float %a, %b, !fpmath !0 229 store volatile float %arcp.md.25ulp, float addrspace(1)* %out 230 231 ret void 232} 233 234attributes #0 = { nounwind optnone noinline } 235attributes #1 = { nounwind } 236attributes #2 = { nounwind "target-features"="+fp32-denormals" } 237 238; CHECK: !0 = !{float 2.500000e+00} 239; CHECK: !1 = !{float 5.000000e-01} 240; CHECK: !2 = !{float 1.000000e+00} 241; CHECK: !3 = !{float 3.000000e+00} 242 243!0 = !{float 2.500000e+00} 244!1 = !{float 5.000000e-01} 245!2 = !{float 1.000000e+00} 246!3 = !{float 3.000000e+00} 247