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