mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-30 16:17:05 +00:00 
			
		
		
		
	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
 | |
| }
 | |
| 
 |