1; RUN: llc < %s -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr7 -enable-unsafe-fp-math -mattr=-vsx | FileCheck %s 2; RUN: llc < %s -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr7 -enable-unsafe-fp-math -mattr=-vsx -recip=sqrtf:0,sqrtd:0 | FileCheck %s -check-prefix=CHECK-NONR 3; RUN: llc < %s -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr7 -mattr=-vsx | FileCheck -check-prefix=CHECK-SAFE %s 4target 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" 5target triple = "powerpc64-unknown-linux-gnu" 6 7declare double @llvm.sqrt.f64(double) 8declare float @llvm.sqrt.f32(float) 9declare <4 x float> @llvm.sqrt.v4f32(<4 x float>) 10 11define double @foo(double %a, double %b) nounwind { 12 %x = call double @llvm.sqrt.f64(double %b) 13 %r = fdiv double %a, %x 14 ret double %r 15 16; CHECK: @foo 17; CHECK-DAG: frsqrte 18; CHECK-DAG: fnmsub 19; CHECK: fmul 20; CHECK-NEXT: fmadd 21; CHECK-NEXT: fmul 22; CHECK-NEXT: fmul 23; CHECK-NEXT: fmadd 24; CHECK-NEXT: fmul 25; CHECK-NEXT: fmul 26; CHECK: blr 27 28; CHECK-NONR: @foo 29; CHECK-NONR: frsqrte 30; CHECK-NONR-NOT: fmadd 31; CHECK-NONR: fmul 32; CHECK-NONR-NOT: fmadd 33; CHECK-NONR: blr 34 35; CHECK-SAFE: @foo 36; CHECK-SAFE: fsqrt 37; CHECK-SAFE: fdiv 38; CHECK-SAFE: blr 39} 40 41define double @foof(double %a, float %b) nounwind { 42 %x = call float @llvm.sqrt.f32(float %b) 43 %y = fpext float %x to double 44 %r = fdiv double %a, %y 45 ret double %r 46 47; CHECK: @foof 48; CHECK-DAG: frsqrtes 49; CHECK-DAG: fnmsubs 50; CHECK: fmuls 51; CHECK-NEXT: fmadds 52; CHECK-NEXT: fmuls 53; CHECK-NEXT: fmul 54; CHECK-NEXT: blr 55 56; CHECK-SAFE: @foof 57; CHECK-SAFE: fsqrts 58; CHECK-SAFE: fdiv 59; CHECK-SAFE: blr 60} 61 62define float @food(float %a, double %b) nounwind { 63 %x = call double @llvm.sqrt.f64(double %b) 64 %y = fptrunc double %x to float 65 %r = fdiv float %a, %y 66 ret float %r 67 68; CHECK: @foo 69; CHECK-DAG: frsqrte 70; CHECK-DAG: fnmsub 71; CHECK: fmul 72; CHECK-NEXT: fmadd 73; CHECK-NEXT: fmul 74; CHECK-NEXT: fmul 75; CHECK-NEXT: fmadd 76; CHECK-NEXT: fmul 77; CHECK-NEXT: frsp 78; CHECK-NEXT: fmuls 79; CHECK-NEXT: blr 80 81; CHECK-SAFE: @foo 82; CHECK-SAFE: fsqrt 83; CHECK-SAFE: fdivs 84; CHECK-SAFE: blr 85} 86 87define float @goo(float %a, float %b) nounwind { 88 %x = call float @llvm.sqrt.f32(float %b) 89 %r = fdiv float %a, %x 90 ret float %r 91 92; CHECK: @goo 93; CHECK-DAG: frsqrtes 94; CHECK-DAG: fnmsubs 95; CHECK: fmuls 96; CHECK-NEXT: fmadds 97; CHECK-NEXT: fmuls 98; CHECK-NEXT: fmuls 99; CHECK-NEXT: blr 100 101; CHECK-NONR: @goo 102; CHECK-NONR: frsqrtes 103; CHECK-NONR-NOT: fmadds 104; CHECK-NONR: fmuls 105; CHECK-NONR-NOT: fmadds 106; CHECK-NONR: blr 107 108; CHECK-SAFE: @goo 109; CHECK-SAFE: fsqrts 110; CHECK-SAFE: fdivs 111; CHECK-SAFE: blr 112} 113 114; Recognize that this is rsqrt(a) * rcp(b) * c, 115; not 1 / ( 1 / sqrt(a)) * rcp(b) * c. 116define float @rsqrt_fmul(float %a, float %b, float %c) { 117 %x = call float @llvm.sqrt.f32(float %a) 118 %y = fmul float %x, %b 119 %z = fdiv float %c, %y 120 ret float %z 121 122; CHECK: @rsqrt_fmul 123; CHECK-DAG: frsqrtes 124; CHECK-DAG: fres 125; CHECK-DAG: fnmsubs 126; CHECK-DAG: fmuls 127; CHECK-DAG: fnmsubs 128; CHECK-DAG: fmadds 129; CHECK-DAG: fmadds 130; CHECK: fmuls 131; CHECK-NEXT: fmuls 132; CHECK-NEXT: fmuls 133; CHECK-NEXT: blr 134 135; CHECK-SAFE: @rsqrt_fmul 136; CHECK-SAFE: fsqrts 137; CHECK-SAFE: fmuls 138; CHECK-SAFE: fdivs 139; CHECK-SAFE: blr 140} 141 142define <4 x float> @hoo(<4 x float> %a, <4 x float> %b) nounwind { 143 %x = call <4 x float> @llvm.sqrt.v4f32(<4 x float> %b) 144 %r = fdiv <4 x float> %a, %x 145 ret <4 x float> %r 146 147; CHECK: @hoo 148; CHECK: vrsqrtefp 149 150; CHECK-SAFE: @hoo 151; CHECK-SAFE-NOT: vrsqrtefp 152; CHECK-SAFE: blr 153} 154 155define double @foo2(double %a, double %b) nounwind { 156 %r = fdiv double %a, %b 157 ret double %r 158 159; CHECK: @foo2 160; CHECK-DAG: fre 161; CHECK-DAG: fnmsub 162; CHECK: fmadd 163; CHECK-NEXT: fnmsub 164; CHECK-NEXT: fmadd 165; CHECK-NEXT: fmul 166; CHECK-NEXT: blr 167 168; CHECK-SAFE: @foo2 169; CHECK-SAFE: fdiv 170; CHECK-SAFE: blr 171} 172 173define float @goo2(float %a, float %b) nounwind { 174 %r = fdiv float %a, %b 175 ret float %r 176 177; CHECK: @goo2 178; CHECK-DAG: fres 179; CHECK-DAG: fnmsubs 180; CHECK: fmadds 181; CHECK-NEXT: fmuls 182; CHECK-NEXT: blr 183 184; CHECK-SAFE: @goo2 185; CHECK-SAFE: fdivs 186; CHECK-SAFE: blr 187} 188 189define <4 x float> @hoo2(<4 x float> %a, <4 x float> %b) nounwind { 190 %r = fdiv <4 x float> %a, %b 191 ret <4 x float> %r 192 193; CHECK: @hoo2 194; CHECK: vrefp 195 196; CHECK-SAFE: @hoo2 197; CHECK-SAFE-NOT: vrefp 198; CHECK-SAFE: blr 199} 200 201define double @foo3(double %a) nounwind { 202 %r = call double @llvm.sqrt.f64(double %a) 203 ret double %r 204 205; CHECK: @foo3 206; CHECK: fcmpu 207; CHECK-DAG: frsqrte 208; CHECK-DAG: fnmsub 209; CHECK: fmul 210; CHECK-NEXT: fmadd 211; CHECK-NEXT: fmul 212; CHECK-NEXT: fmul 213; CHECK-NEXT: fmadd 214; CHECK-NEXT: fmul 215; CHECK-NEXT: fmul 216; CHECK: blr 217 218; CHECK-SAFE: @foo3 219; CHECK-SAFE: fsqrt 220; CHECK-SAFE: blr 221} 222 223define float @goo3(float %a) nounwind { 224 %r = call float @llvm.sqrt.f32(float %a) 225 ret float %r 226 227; CHECK: @goo3 228; CHECK: fcmpu 229; CHECK-DAG: frsqrtes 230; CHECK-DAG: fnmsubs 231; CHECK: fmuls 232; CHECK-NEXT: fmadds 233; CHECK-NEXT: fmuls 234; CHECK-NEXT: fmuls 235; CHECK: blr 236 237; CHECK-SAFE: @goo3 238; CHECK-SAFE: fsqrts 239; CHECK-SAFE: blr 240} 241 242define <4 x float> @hoo3(<4 x float> %a) nounwind { 243 %r = call <4 x float> @llvm.sqrt.v4f32(<4 x float> %a) 244 ret <4 x float> %r 245 246; CHECK: @hoo3 247; CHECK: vrsqrtefp 248; CHECK-DAG: vcmpeqfp 249 250; CHECK-SAFE: @hoo3 251; CHECK-SAFE-NOT: vrsqrtefp 252; CHECK-SAFE: blr 253} 254 255