1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-23 04:52:54 +02:00
llvm-mirror/test/CodeGen/PowerPC/recipest.ll
Sanjay Patel 98a98574c5 Refactor reciprocal and reciprocal square root estimate into target-independent functions (part 2).
This is purely refactoring. No functional changes intended. PowerPC is the only target
that is currently using this interface.

The ultimate goal is to allow targets other than PowerPC (certainly X86 and Aarch64) to turn this:

z = y / sqrt(x)

into:

z = y * rsqrte(x)

And:

z = y / x

into:

z = y * rcpe(x)

using whatever HW magic they can use. See http://llvm.org/bugs/show_bug.cgi?id=20900 .

There is one hook in TargetLowering to get the target-specific opcode for an estimate instruction
along with the number of refinement steps needed to make the estimate usable.

Differential Revision: http://reviews.llvm.org/D5484

llvm-svn: 218553
2014-09-26 23:01:47 +00:00

219 lines
4.2 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 {
%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-NEXT: fmadd
; CHECK-NEXT: fmul
; CHECK-NEXT: fmul
; CHECK-NEXT: fmadd
; CHECK-NEXT: fmul
; CHECK-NEXT: fmul
; CHECK: blr
; CHECK-SAFE: @foo
; CHECK-SAFE: fsqrt
; CHECK-SAFE: fdiv
; CHECK-SAFE: blr
}
define double @foof(double %a, float %b) nounwind {
%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-NEXT: fmadds
; CHECK-NEXT: fmuls
; CHECK-NEXT: fmul
; CHECK-NEXT: blr
; CHECK-SAFE: @foof
; CHECK-SAFE: fsqrts
; CHECK-SAFE: fdiv
; CHECK-SAFE: blr
}
define float @food(float %a, double %b) nounwind {
%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-NEXT: fmadd
; CHECK-NEXT: fmul
; CHECK-NEXT: fmul
; CHECK-NEXT: fmadd
; CHECK-NEXT: fmul
; CHECK-NEXT: frsp
; CHECK-NEXT: fmuls
; CHECK-NEXT: blr
; CHECK-SAFE: @foo
; CHECK-SAFE: fsqrt
; CHECK-SAFE: fdivs
; CHECK-SAFE: blr
}
define float @goo(float %a, float %b) nounwind {
%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-NEXT: fmadds
; CHECK-NEXT: fmuls
; CHECK-NEXT: fmuls
; CHECK-NEXT: 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 {
%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 {
%r = fdiv double %a, %b
ret double %r
; CHECK: @foo2
; CHECK-DAG: fre
; CHECK-DAG: fnmsub
; CHECK: fmadd
; CHECK-NEXT: fnmsub
; CHECK-NEXT: fmadd
; CHECK-NEXT: fmul
; CHECK-NEXT: blr
; CHECK-SAFE: @foo2
; CHECK-SAFE: fdiv
; CHECK-SAFE: blr
}
define float @goo2(float %a, float %b) nounwind {
%r = fdiv float %a, %b
ret float %r
; CHECK: @goo2
; CHECK-DAG: fres
; CHECK-DAG: fnmsubs
; CHECK: fmadds
; CHECK-NEXT: fmuls
; CHECK-NEXT: blr
; CHECK-SAFE: @goo2
; CHECK-SAFE: fdivs
; CHECK-SAFE: blr
}
define <4 x float> @hoo2(<4 x float> %a, <4 x float> %b) nounwind {
%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 {
%r = call double @llvm.sqrt.f64(double %a)
ret double %r
; CHECK: @foo3
; CHECK: fcmpu
; CHECK-DAG: frsqrte
; CHECK-DAG: fnmsub
; CHECK: fmul
; CHECK-NEXT: fmadd
; CHECK-NEXT: fmul
; CHECK-NEXT: fmul
; CHECK-NEXT: fmadd
; CHECK-NEXT: fmul
; CHECK-NEXT: fre
; CHECK-NEXT: fnmsub
; CHECK-NEXT: fmadd
; CHECK-NEXT: fnmsub
; CHECK-NEXT: fmadd
; CHECK: blr
; CHECK-SAFE: @foo3
; CHECK-SAFE: fsqrt
; CHECK-SAFE: blr
}
define float @goo3(float %a) nounwind {
%r = call float @llvm.sqrt.f32(float %a)
ret float %r
; CHECK: @goo3
; CHECK: fcmpu
; CHECK-DAG: frsqrtes
; CHECK-DAG: fnmsubs
; CHECK: fmuls
; CHECK-NEXT: fmadds
; CHECK-NEXT: fmuls
; CHECK-NEXT: fres
; CHECK-NEXT: fnmsubs
; CHECK-NEXT: fmadds
; CHECK: blr
; CHECK-SAFE: @goo3
; CHECK-SAFE: fsqrts
; CHECK-SAFE: blr
}
define <4 x float> @hoo3(<4 x float> %a) nounwind {
%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
}