mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-28 07:05:03 +00:00
4a1535c038
In fast-math mode sqrt(x) is calculated using the fast expansion of the reciprocal of the reciprocal sqrt expansion. The reciprocal and reciprocal sqrt expansions use the associated estimate instructions along with some Newton iterations. Unfortunately, as a result, sqrt(0) was being calculated as NaN, which is not correct. Now we explicitly return a result of zero if the input is zero. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@190624 91177308-0d34-0410-b5e6-96231b3b80d8
230 lines
4.1 KiB
LLVM
230 lines
4.1 KiB
LLVM
; RUN: llc < %s -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr7 -enable-unsafe-fp-math | FileCheck %s
|
|
; RUN: llc < %s -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr7 | FileCheck -check-prefix=CHECK-SAFE %s
|
|
target 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"
|
|
target triple = "powerpc64-unknown-linux-gnu"
|
|
|
|
declare double @llvm.sqrt.f64(double)
|
|
declare float @llvm.sqrt.f32(float)
|
|
declare <4 x float> @llvm.sqrt.v4f32(<4 x float>)
|
|
|
|
define double @foo(double %a, double %b) nounwind {
|
|
entry:
|
|
%x = call double @llvm.sqrt.f64(double %b)
|
|
%r = fdiv double %a, %x
|
|
ret double %r
|
|
|
|
; CHECK: @foo
|
|
; CHECK-DAG: frsqrte
|
|
; CHECK-DAG: fnmsub
|
|
; CHECK: fmul
|
|
; CHECK: fmadd
|
|
; CHECK: fmul
|
|
; CHECK: fmul
|
|
; CHECK: fmadd
|
|
; CHECK: fmul
|
|
; CHECK: fmul
|
|
; CHECK: blr
|
|
|
|
; CHECK-SAFE: @foo
|
|
; CHECK-SAFE: fsqrt
|
|
; CHECK-SAFE: fdiv
|
|
; CHECK-SAFE: blr
|
|
}
|
|
|
|
define double @foof(double %a, float %b) nounwind {
|
|
entry:
|
|
%x = call float @llvm.sqrt.f32(float %b)
|
|
%y = fpext float %x to double
|
|
%r = fdiv double %a, %y
|
|
ret double %r
|
|
|
|
; CHECK: @foof
|
|
; CHECK-DAG: frsqrtes
|
|
; CHECK-DAG: fnmsubs
|
|
; CHECK: fmuls
|
|
; CHECK: fmadds
|
|
; CHECK: fmuls
|
|
; CHECK: fmul
|
|
; CHECK: blr
|
|
|
|
; CHECK-SAFE: @foof
|
|
; CHECK-SAFE: fsqrts
|
|
; CHECK-SAFE: fdiv
|
|
; CHECK-SAFE: blr
|
|
}
|
|
|
|
define float @food(float %a, double %b) nounwind {
|
|
entry:
|
|
%x = call double @llvm.sqrt.f64(double %b)
|
|
%y = fptrunc double %x to float
|
|
%r = fdiv float %a, %y
|
|
ret float %r
|
|
|
|
; CHECK: @foo
|
|
; CHECK-DAG: frsqrte
|
|
; CHECK-DAG: fnmsub
|
|
; CHECK: fmul
|
|
; CHECK: fmadd
|
|
; CHECK: fmul
|
|
; CHECK: fmul
|
|
; CHECK: fmadd
|
|
; CHECK: fmul
|
|
; CHECK: frsp
|
|
; CHECK: fmuls
|
|
; CHECK: blr
|
|
|
|
; CHECK-SAFE: @foo
|
|
; CHECK-SAFE: fsqrt
|
|
; CHECK-SAFE: fdivs
|
|
; CHECK-SAFE: blr
|
|
}
|
|
|
|
define float @goo(float %a, float %b) nounwind {
|
|
entry:
|
|
%x = call float @llvm.sqrt.f32(float %b)
|
|
%r = fdiv float %a, %x
|
|
ret float %r
|
|
|
|
; CHECK: @goo
|
|
; CHECK-DAG: frsqrtes
|
|
; CHECK-DAG: fnmsubs
|
|
; CHECK: fmuls
|
|
; CHECK: fmadds
|
|
; CHECK: fmuls
|
|
; CHECK: fmuls
|
|
; CHECK: blr
|
|
|
|
; CHECK-SAFE: @goo
|
|
; CHECK-SAFE: fsqrts
|
|
; CHECK-SAFE: fdivs
|
|
; CHECK-SAFE: blr
|
|
}
|
|
|
|
define <4 x float> @hoo(<4 x float> %a, <4 x float> %b) nounwind {
|
|
entry:
|
|
%x = call <4 x float> @llvm.sqrt.v4f32(<4 x float> %b)
|
|
%r = fdiv <4 x float> %a, %x
|
|
ret <4 x float> %r
|
|
|
|
; CHECK: @hoo
|
|
; CHECK: vrsqrtefp
|
|
|
|
; CHECK-SAFE: @hoo
|
|
; CHECK-SAFE-NOT: vrsqrtefp
|
|
; CHECK-SAFE: blr
|
|
}
|
|
|
|
define double @foo2(double %a, double %b) nounwind {
|
|
entry:
|
|
%r = fdiv double %a, %b
|
|
ret double %r
|
|
|
|
; CHECK: @foo2
|
|
; CHECK-DAG: fre
|
|
; CHECK-DAG: fnmsub
|
|
; CHECK: fmadd
|
|
; CHECK: fnmsub
|
|
; CHECK: fmadd
|
|
; CHECK: fmul
|
|
; CHECK: blr
|
|
|
|
; CHECK-SAFE: @foo2
|
|
; CHECK-SAFE: fdiv
|
|
; CHECK-SAFE: blr
|
|
}
|
|
|
|
define float @goo2(float %a, float %b) nounwind {
|
|
entry:
|
|
%r = fdiv float %a, %b
|
|
ret float %r
|
|
|
|
; CHECK: @goo2
|
|
; CHECK-DAG: fres
|
|
; CHECK-DAG: fnmsubs
|
|
; CHECK: fmadds
|
|
; CHECK: fmuls
|
|
; CHECK: blr
|
|
|
|
; CHECK-SAFE: @goo2
|
|
; CHECK-SAFE: fdivs
|
|
; CHECK-SAFE: blr
|
|
}
|
|
|
|
define <4 x float> @hoo2(<4 x float> %a, <4 x float> %b) nounwind {
|
|
entry:
|
|
%r = fdiv <4 x float> %a, %b
|
|
ret <4 x float> %r
|
|
|
|
; CHECK: @hoo2
|
|
; CHECK: vrefp
|
|
|
|
; CHECK-SAFE: @hoo2
|
|
; CHECK-SAFE-NOT: vrefp
|
|
; CHECK-SAFE: blr
|
|
}
|
|
|
|
define double @foo3(double %a) nounwind {
|
|
entry:
|
|
%r = call double @llvm.sqrt.f64(double %a)
|
|
ret double %r
|
|
|
|
; CHECK: @foo3
|
|
; CHECK: fcmpu
|
|
; CHECK-DAG: frsqrte
|
|
; CHECK-DAG: fnmsub
|
|
; CHECK: fmul
|
|
; CHECK: fmadd
|
|
; CHECK: fmul
|
|
; CHECK: fmul
|
|
; CHECK: fmadd
|
|
; CHECK: fmul
|
|
; CHECK: fre
|
|
; CHECK: fnmsub
|
|
; CHECK: fmadd
|
|
; CHECK: fnmsub
|
|
; CHECK: fmadd
|
|
; CHECK: blr
|
|
|
|
; CHECK-SAFE: @foo3
|
|
; CHECK-SAFE: fsqrt
|
|
; CHECK-SAFE: blr
|
|
}
|
|
|
|
define float @goo3(float %a) nounwind {
|
|
entry:
|
|
%r = call float @llvm.sqrt.f32(float %a)
|
|
ret float %r
|
|
|
|
; CHECK: @goo3
|
|
; CHECK: fcmpu
|
|
; CHECK-DAG: frsqrtes
|
|
; CHECK-DAG: fnmsubs
|
|
; CHECK: fmuls
|
|
; CHECK: fmadds
|
|
; CHECK: fmuls
|
|
; CHECK: fres
|
|
; CHECK: fnmsubs
|
|
; CHECK: fmadds
|
|
; CHECK: blr
|
|
|
|
; CHECK-SAFE: @goo3
|
|
; CHECK-SAFE: fsqrts
|
|
; CHECK-SAFE: blr
|
|
}
|
|
|
|
define <4 x float> @hoo3(<4 x float> %a) nounwind {
|
|
entry:
|
|
%r = call <4 x float> @llvm.sqrt.v4f32(<4 x float> %a)
|
|
ret <4 x float> %r
|
|
|
|
; CHECK: @hoo3
|
|
; CHECK: vrsqrtefp
|
|
; CHECK-DAG: vrefp
|
|
; CHECK-DAG: vcmpeqfp
|
|
|
|
; CHECK-SAFE: @hoo3
|
|
; CHECK-SAFE-NOT: vrsqrtefp
|
|
; CHECK-SAFE: blr
|
|
}
|
|
|