1; RUN: llc < %s -march=nvptx -mcpu=sm_20 | FileCheck %s 2; RUN: %if ptxas %{ llc < %s -march=nvptx -mcpu=sm_20 | %ptxas-verify %} 3 4declare float @llvm.sqrt.f32(float) 5declare double @llvm.sqrt.f64(double) 6 7; CHECK-LABEL: sqrt_div( 8; CHECK: sqrt.rn.f32 9; CHECK: div.rn.f32 10define float @sqrt_div(float %a, float %b) { 11 %t1 = tail call float @llvm.sqrt.f32(float %a) 12 %t2 = fdiv float %t1, %b 13 ret float %t2 14} 15 16; CHECK-LABEL: sqrt_div_fast( 17; CHECK: sqrt.rn.f32 18; CHECK: div.approx.f32 19define float @sqrt_div_fast(float %a, float %b) #0 { 20 %t1 = tail call float @llvm.sqrt.f32(float %a) 21 %t2 = fdiv float %t1, %b 22 ret float %t2 23} 24 25; CHECK-LABEL: sqrt_div_fast_ninf( 26; CHECK: sqrt.approx.f32 27; CHECK: div.approx.f32 28define float @sqrt_div_fast_ninf(float %a, float %b) #0 { 29 %t1 = tail call ninf afn float @llvm.sqrt.f32(float %a) 30 %t2 = fdiv float %t1, %b 31 ret float %t2 32} 33 34; CHECK-LABEL: sqrt_div_ftz( 35; CHECK: sqrt.rn.ftz.f32 36; CHECK: div.rn.ftz.f32 37define float @sqrt_div_ftz(float %a, float %b) #1 { 38 %t1 = tail call float @llvm.sqrt.f32(float %a) 39 %t2 = fdiv float %t1, %b 40 ret float %t2 41} 42 43; CHECK-LABEL: sqrt_div_fast_ftz( 44; CHECK: sqrt.rn.ftz.f32 45; CHECK: div.approx.ftz.f32 46define float @sqrt_div_fast_ftz(float %a, float %b) #0 #1 { 47 %t1 = tail call float @llvm.sqrt.f32(float %a) 48 %t2 = fdiv float %t1, %b 49 ret float %t2 50} 51 52; CHECK-LABEL: sqrt_div_fast_ftz_ninf( 53; CHECK: sqrt.approx.ftz.f32 54; CHECK: div.approx.ftz.f32 55define float @sqrt_div_fast_ftz_ninf(float %a, float %b) #0 #1 { 56 %t1 = tail call ninf afn float @llvm.sqrt.f32(float %a) 57 %t2 = fdiv float %t1, %b 58 ret float %t2 59} 60 61; There are no fast-math or ftz versions of sqrt and div for f64. We use 62; reciprocal(rsqrt(x)) for sqrt(x), and emit a vanilla divide. 63 64; CHECK-LABEL: sqrt_div_fast_ftz_f64( 65; CHECK: sqrt.rn.f64 66; CHECK: div.rn.f64 67define double @sqrt_div_fast_ftz_f64(double %a, double %b) #0 #1 { 68 %t1 = tail call double @llvm.sqrt.f64(double %a) 69 %t2 = fdiv double %t1, %b 70 ret double %t2 71} 72 73; CHECK-LABEL: sqrt_div_fast_ftz_f64_ninf( 74; CHECK: rsqrt.approx.f64 75; CHECK: rcp.approx.ftz.f64 76; CHECK: div.rn.f64 77define double @sqrt_div_fast_ftz_f64_ninf(double %a, double %b) #0 #1 { 78 %t1 = tail call ninf afn double @llvm.sqrt.f64(double %a) 79 %t2 = fdiv double %t1, %b 80 ret double %t2 81} 82 83; CHECK-LABEL: rsqrt( 84; CHECK-NOT: rsqrt.approx 85; CHECK: sqrt.rn.f32 86; CHECK-NOT: rsqrt.approx 87define float @rsqrt(float %a) { 88 %b = tail call float @llvm.sqrt.f32(float %a) 89 %ret = fdiv float 1.0, %b 90 ret float %ret 91} 92 93; CHECK-LABEL: rsqrt_fast( 94; CHECK-NOT: div. 95; CHECK-NOT: sqrt. 96; CHECK: rsqrt.approx.f32 97; CHECK-NOT: div. 98; CHECK-NOT: sqrt. 99define float @rsqrt_fast(float %a) #0 { 100 %b = tail call float @llvm.sqrt.f32(float %a) 101 %ret = fdiv float 1.0, %b 102 ret float %ret 103} 104 105; CHECK-LABEL: rsqrt_fast_ftz( 106; CHECK-NOT: div. 107; CHECK-NOT: sqrt. 108; CHECK: rsqrt.approx.ftz.f32 109; CHECK-NOT: div. 110; CHECK-NOT: sqrt. 111define float @rsqrt_fast_ftz(float %a) #0 #1 { 112 %b = tail call float @llvm.sqrt.f32(float %a) 113 %ret = fdiv float 1.0, %b 114 ret float %ret 115} 116 117; CHECK-LABEL: fadd 118; CHECK: add.rn.f32 119define float @fadd(float %a, float %b) { 120 %t1 = fadd float %a, %b 121 ret float %t1 122} 123 124; CHECK-LABEL: fadd_ftz 125; CHECK: add.rn.ftz.f32 126define float @fadd_ftz(float %a, float %b) #1 { 127 %t1 = fadd float %a, %b 128 ret float %t1 129} 130 131declare float @llvm.sin.f32(float) 132declare float @llvm.cos.f32(float) 133 134; CHECK-LABEL: fsin_approx 135; CHECK: sin.approx.f32 136define float @fsin_approx(float %a) #0 { 137 %r = tail call float @llvm.sin.f32(float %a) 138 ret float %r 139} 140 141; CHECK-LABEL: fcos_approx 142; CHECK: cos.approx.f32 143define float @fcos_approx(float %a) #0 { 144 %r = tail call float @llvm.cos.f32(float %a) 145 ret float %r 146} 147 148; CHECK-LABEL: repeated_div_recip_allowed 149define float @repeated_div_recip_allowed(i1 %pred, float %a, float %b, float %divisor) { 150; CHECK: rcp.rn.f32 151; CHECK: mul.rn.f32 152; CHECK: mul.rn.f32 153; CHECK: mul.rn.f32 154; CHECK: selp.f32 155 %x = fdiv arcp float %a, %divisor 156 %y = fdiv arcp float %b, %divisor 157 %z = fmul float %x, %y 158 %w = select i1 %pred, float %z, float %y 159 ret float %w 160} 161 162; CHECK-LABEL: repeated_div_recip_allowed_sel 163define float @repeated_div_recip_allowed_sel(i1 %pred, float %a, float %b, float %divisor) { 164; CHECK: selp.f32 165; CHECK: div.rn.f32 166 %x = fdiv arcp float %a, %divisor 167 %y = fdiv arcp float %b, %divisor 168 %w = select i1 %pred, float %x, float %y 169 ret float %w 170} 171 172; CHECK-LABEL: repeated_div_recip_allowed_ftz 173define float @repeated_div_recip_allowed_ftz(i1 %pred, float %a, float %b, float %divisor) #1 { 174; CHECK: rcp.rn.ftz.f32 175; CHECK: mul.rn.ftz.f32 176; CHECK: mul.rn.ftz.f32 177; CHECK: mul.rn.ftz.f32 178; CHECK: selp.f32 179 %x = fdiv arcp float %a, %divisor 180 %y = fdiv arcp float %b, %divisor 181 %z = fmul float %x, %y 182 %w = select i1 %pred, float %z, float %y 183 ret float %w 184} 185 186; CHECK-LABEL: repeated_div_recip_allowed_ftz_sel 187define float @repeated_div_recip_allowed_ftz_sel(i1 %pred, float %a, float %b, float %divisor) #1 { 188; CHECK: selp.f32 189; CHECK: div.rn.ftz.f32 190 %x = fdiv arcp float %a, %divisor 191 %y = fdiv arcp float %b, %divisor 192 %w = select i1 %pred, float %x, float %y 193 ret float %w 194} 195 196; CHECK-LABEL: repeated_div_fast 197define float @repeated_div_fast(i1 %pred, float %a, float %b, float %divisor) #0 { 198; CHECK: rcp.approx.f32 199; CHECK: mul.f32 200; CHECK: mul.f32 201; CHECK: mul.f32 202; CHECK: selp.f32 203 %x = fdiv float %a, %divisor 204 %y = fdiv float %b, %divisor 205 %z = fmul float %x, %y 206 %w = select i1 %pred, float %z, float %y 207 ret float %w 208} 209 210; CHECK-LABEL: repeated_div_fast_sel 211define float @repeated_div_fast_sel(i1 %pred, float %a, float %b, float %divisor) #0 { 212; CHECK: selp.f32 213; CHECK: div.approx.f32 214 %x = fdiv float %a, %divisor 215 %y = fdiv float %b, %divisor 216 %w = select i1 %pred, float %x, float %y 217 ret float %w 218} 219 220; CHECK-LABEL: repeated_div_fast_ftz 221define float @repeated_div_fast_ftz(i1 %pred, float %a, float %b, float %divisor) #0 #1 { 222; CHECK: rcp.approx.ftz.f32 223; CHECK: mul.ftz.f32 224; CHECK: mul.ftz.f32 225; CHECK: mul.ftz.f32 226; CHECK: selp.f32 227 %x = fdiv float %a, %divisor 228 %y = fdiv float %b, %divisor 229 %z = fmul float %x, %y 230 %w = select i1 %pred, float %z, float %y 231 ret float %w 232} 233 234; CHECK-LABEL: repeated_div_fast_ftz_sel 235define float @repeated_div_fast_ftz_sel(i1 %pred, float %a, float %b, float %divisor) #0 #1 { 236; CHECK: selp.f32 237; CHECK: div.approx.ftz.f32 238 %x = fdiv float %a, %divisor 239 %y = fdiv float %b, %divisor 240 %w = select i1 %pred, float %x, float %y 241 ret float %w 242} 243 244attributes #0 = { "unsafe-fp-math" = "true" } 245attributes #1 = { "denormal-fp-math-f32" = "preserve-sign" } 246