mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-10 02:36:06 +00:00
676af35b38
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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@218553 91177308-0d34-0410-b5e6-96231b3b80d8
219 lines
4.2 KiB
LLVM
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
|
|
}
|
|
|