1; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr7 -mattr=-vsx | FileCheck %s 2 3target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64" 4target triple = "powerpc64-unknown-linux-gnu" 5 6declare double @llvm.sqrt.f64(double) 7declare float @llvm.sqrt.f32(float) 8declare <4 x float> @llvm.sqrt.v4f32(<4 x float>) 9 10define double @foo_fmf(double %a, double %b) nounwind { 11; CHECK: @foo_fmf 12; CHECK: frsqrte 13; CHECK: fmul 14; CHECK-NEXT: fmadd 15; CHECK-NEXT: fmul 16; CHECK-NEXT: fmul 17; CHECK-NEXT: fmul 18; CHECK-NEXT: fmadd 19; CHECK-NEXT: fmul 20; CHECK-NEXT: fmul 21; CHECK-NEXT: fmul 22; CHECK: blr 23 %x = call fast double @llvm.sqrt.f64(double %b) 24 %r = fdiv fast double %a, %x 25 ret double %r 26} 27 28define double @foo_safe(double %a, double %b) nounwind { 29; CHECK: @foo_safe 30; CHECK: fsqrt 31; CHECK: fdiv 32; CHECK: blr 33 %x = call double @llvm.sqrt.f64(double %b) 34 %r = fdiv double %a, %x 35 ret double %r 36} 37 38define double @no_estimate_refinement_f64(double %a, double %b) #0 { 39; CHECK-LABEL: @no_estimate_refinement_f64 40; CHECK: frsqrte 41; CHECK-NOT: fmadd 42; CHECK: fmul 43; CHECK-NOT: fmadd 44; CHECK: blr 45 %x = call fast double @llvm.sqrt.f64(double %b) 46 %r = fdiv fast double %a, %x 47 ret double %r 48} 49 50define double @foof_fmf(double %a, float %b) nounwind { 51; CHECK: @foof_fmf 52; CHECK-DAG: frsqrtes 53; CHECK: fmuls 54; CHECK-NEXT: fmadds 55; CHECK-NEXT: fmuls 56; CHECK-NEXT: fmuls 57; CHECK-NEXT: fmul 58; CHECK-NEXT: blr 59 %x = call fast float @llvm.sqrt.f32(float %b) 60 %y = fpext float %x to double 61 %r = fdiv fast double %a, %y 62 ret double %r 63} 64 65define double @foof_safe(double %a, float %b) nounwind { 66; CHECK: @foof_safe 67; CHECK: fsqrts 68; CHECK: fdiv 69; CHECK: blr 70 %x = call float @llvm.sqrt.f32(float %b) 71 %y = fpext float %x to double 72 %r = fdiv double %a, %y 73 ret double %r 74} 75 76define float @food_fmf(float %a, double %b) nounwind { 77; CHECK: @food_fmf 78; CHECK-DAG: frsqrte 79; CHECK: fmul 80; CHECK-NEXT: fmadd 81; CHECK-NEXT: fmul 82; CHECK-NEXT: fmul 83; CHECK-NEXT: fmul 84; CHECK-NEXT: fmadd 85; CHECK-NEXT: fmul 86; CHECK-NEXT: fmul 87; CHECK-NEXT: frsp 88; CHECK-NEXT: fmuls 89; CHECK-NEXT: blr 90 %x = call fast double @llvm.sqrt.f64(double %b) 91 %y = fptrunc double %x to float 92 %r = fdiv fast float %a, %y 93 ret float %r 94} 95 96define float @food_safe(float %a, double %b) nounwind { 97; CHECK: @food_safe 98; CHECK: fsqrt 99; CHECK: fdivs 100; CHECK: blr 101 %x = call double @llvm.sqrt.f64(double %b) 102 %y = fptrunc double %x to float 103 %r = fdiv float %a, %y 104 ret float %r 105} 106 107define float @goo_fmf(float %a, float %b) nounwind { 108; CHECK: @goo_fmf 109; CHECK-DAG: frsqrtes 110; CHECK: fmuls 111; CHECK-NEXT: fmadds 112; CHECK-NEXT: fmuls 113; CHECK-NEXT: fmuls 114; CHECK-NEXT: fmuls 115; CHECK-NEXT: blr 116 %x = call fast float @llvm.sqrt.f32(float %b) 117 %r = fdiv fast float %a, %x 118 ret float %r 119} 120 121define float @goo_safe(float %a, float %b) nounwind { 122; CHECK: @goo_safe 123; CHECK: fsqrts 124; CHECK: fdivs 125; CHECK: blr 126 %x = call float @llvm.sqrt.f32(float %b) 127 %r = fdiv float %a, %x 128 ret float %r 129} 130 131define float @no_estimate_refinement_f32(float %a, float %b) #0 { 132; CHECK-LABEL: @no_estimate_refinement_f32 133; CHECK: frsqrtes 134; CHECK-NOT: fmadds 135; CHECK: fmuls 136; CHECK-NOT: fmadds 137; CHECK: blr 138 %x = call fast float @llvm.sqrt.f32(float %b) 139 %r = fdiv fast float %a, %x 140 ret float %r 141} 142 143; Recognize that this is rsqrt(a) * rcp(b) * c, 144; not 1 / ( 1 / sqrt(a)) * rcp(b) * c. 145define float @rsqrt_fmul_fmf(float %a, float %b, float %c) { 146; CHECK: @rsqrt_fmul_fmf 147; CHECK-DAG: frsqrtes 148; CHECK-DAG: fres 149; CHECK-DAG: fnmsubs 150; CHECK-DAG: fmuls 151; CHECK-DAG: fmadds 152; CHECK-DAG: fmadds 153; CHECK: fmuls 154; CHECK-NEXT: fmuls 155; CHECK-NEXT: fmuls 156; CHECK-NEXT: blr 157 %x = call fast float @llvm.sqrt.f32(float %a) 158 %y = fmul fast float %x, %b 159 %z = fdiv fast float %c, %y 160 ret float %z 161} 162 163; Recognize that this is rsqrt(a) * rcp(b) * c, 164; not 1 / ( 1 / sqrt(a)) * rcp(b) * c. 165define float @rsqrt_fmul_safe(float %a, float %b, float %c) { 166; CHECK: @rsqrt_fmul_safe 167; CHECK: fsqrts 168; CHECK: fmuls 169; CHECK: fdivs 170; CHECK: blr 171 %x = call float @llvm.sqrt.f32(float %a) 172 %y = fmul float %x, %b 173 %z = fdiv float %c, %y 174 ret float %z 175} 176 177define <4 x float> @hoo_fmf(<4 x float> %a, <4 x float> %b) nounwind { 178; CHECK: @hoo_fmf 179; CHECK: vrsqrtefp 180 %x = call fast <4 x float> @llvm.sqrt.v4f32(<4 x float> %b) 181 %r = fdiv fast <4 x float> %a, %x 182 ret <4 x float> %r 183} 184 185define <4 x float> @hoo_safe(<4 x float> %a, <4 x float> %b) nounwind { 186; CHECK: @hoo_safe 187; CHECK-NOT: vrsqrtefp 188; CHECK: blr 189 %x = call <4 x float> @llvm.sqrt.v4f32(<4 x float> %b) 190 %r = fdiv <4 x float> %a, %x 191 ret <4 x float> %r 192} 193 194define double @foo2_fmf(double %a, double %b) nounwind { 195; CHECK: @foo2_fmf 196; CHECK-DAG: fre 197; CHECK-DAG: fnmsub 198; CHECK: fmadd 199; CHECK-NEXT: fnmsub 200; CHECK-NEXT: fmadd 201; CHECK-NEXT: fmul 202; CHECK-NEXT: blr 203 %r = fdiv fast double %a, %b 204 ret double %r 205} 206 207define double @foo2_safe(double %a, double %b) nounwind { 208; CHECK: @foo2_safe 209; CHECK: fdiv 210; CHECK: blr 211 %r = fdiv double %a, %b 212 ret double %r 213} 214 215define float @goo2_fmf(float %a, float %b) nounwind { 216; CHECK: @goo2_fmf 217; CHECK-DAG: fres 218; CHECK-DAG: fnmsubs 219; CHECK: fmadds 220; CHECK-NEXT: fmuls 221; CHECK-NEXT: blr 222 %r = fdiv fast float %a, %b 223 ret float %r 224} 225 226define float @goo2_safe(float %a, float %b) nounwind { 227; CHECK: @goo2_safe 228; CHECK: fdivs 229; CHECK: blr 230 %r = fdiv float %a, %b 231 ret float %r 232} 233 234define <4 x float> @hoo2_fmf(<4 x float> %a, <4 x float> %b) nounwind { 235; CHECK: @hoo2_fmf 236; CHECK: vrefp 237 %r = fdiv fast <4 x float> %a, %b 238 ret <4 x float> %r 239} 240 241define <4 x float> @hoo2_safe(<4 x float> %a, <4 x float> %b) nounwind { 242; CHECK: @hoo2_safe 243; CHECK-NOT: vrefp 244; CHECK: blr 245 %r = fdiv <4 x float> %a, %b 246 ret <4 x float> %r 247} 248 249define double @foo3_fmf(double %a) nounwind { 250; CHECK: @foo3_fmf 251; CHECK: fcmpu 252; CHECK-DAG: frsqrte 253; CHECK: fmul 254; CHECK-NEXT: fmadd 255; CHECK-NEXT: fmul 256; CHECK-NEXT: fmul 257; CHECK-NEXT: fmul 258; CHECK-NEXT: fmadd 259; CHECK-NEXT: fmul 260; CHECK-NEXT: fmul 261; CHECK: blr 262 %r = call fast double @llvm.sqrt.f64(double %a) 263 ret double %r 264} 265 266define double @foo3_safe(double %a) nounwind { 267; CHECK: @foo3_safe 268; CHECK: fsqrt 269; CHECK: blr 270 %r = call double @llvm.sqrt.f64(double %a) 271 ret double %r 272} 273 274define float @goo3_fmf(float %a) nounwind { 275; CHECK: @goo3_fmf 276; CHECK: fcmpu 277; CHECK-DAG: frsqrtes 278; CHECK: fmuls 279; CHECK-NEXT: fmadds 280; CHECK-NEXT: fmuls 281; CHECK-NEXT: fmuls 282; CHECK: blr 283 %r = call fast float @llvm.sqrt.f32(float %a) 284 ret float %r 285} 286 287define float @goo3_safe(float %a) nounwind { 288; CHECK: @goo3_safe 289; CHECK: fsqrts 290; CHECK: blr 291 %r = call float @llvm.sqrt.f32(float %a) 292 ret float %r 293} 294 295define <4 x float> @hoo3_fmf(<4 x float> %a) nounwind { 296; CHECK: @hoo3_fmf 297; CHECK: vrsqrtefp 298; CHECK-DAG: vcmpeqfp 299 %r = call fast <4 x float> @llvm.sqrt.v4f32(<4 x float> %a) 300 ret <4 x float> %r 301} 302 303define <4 x float> @hoo3_safe(<4 x float> %a) nounwind { 304; CHECK: @hoo3_safe 305; CHECK-NOT: vrsqrtefp 306; CHECK: blr 307 %r = call <4 x float> @llvm.sqrt.v4f32(<4 x float> %a) 308 ret <4 x float> %r 309} 310 311attributes #0 = { nounwind "reciprocal-estimates"="sqrtf:0,sqrtd:0" } 312