mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-15 20:29:48 +00:00
0056820a48
As discussed here: http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140609/220598.html And again here: http://lists.cs.uiuc.edu/pipermail/llvmdev/2014-September/077168.html The sqrt of a negative number when using the llvm intrinsic is undefined. We should return undef rather than 0.0 to match the definition in the LLVM IR lang ref. This change should not affect any code that isn't using "no-nans-fp-math"; ie, no-nans is a requirement for generating the llvm intrinsic in place of a sqrt function call. Unfortunately, the behavior introduced by this patch will not match current gcc, xlc, icc, and possibly other compilers. The current clang/llvm behavior of returning 0.0 doesn't either. We knowingly approve of this difference with the other compilers in an attempt to flag code that is invoking undefined behavior. A front-end warning should also try to convince the user that the program will fail: http://llvm.org/bugs/show_bug.cgi?id=21093 Differential Revision: http://reviews.llvm.org/D5527 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@218803 91177308-0d34-0410-b5e6-96231b3b80d8
57 lines
1.9 KiB
LLVM
57 lines
1.9 KiB
LLVM
; RUN: opt -S -instcombine < %s | FileCheck %s
|
|
|
|
declare float @llvm.fma.f32(float, float, float) #0
|
|
declare float @llvm.fmuladd.f32(float, float, float) #0
|
|
declare <4 x float> @llvm.fma.v4f32(<4 x float>, <4 x float>, <4 x float>) #0
|
|
|
|
declare double @llvm.fma.f64(double, double, double) #0
|
|
declare double @llvm.fmuladd.f64(double, double, double) #0
|
|
|
|
declare double @llvm.sqrt.f64(double) #0
|
|
|
|
|
|
; CHECK-LABEL: @constant_fold_fma_f32
|
|
; CHECK-NEXT: ret float 6.000000e+00
|
|
define float @constant_fold_fma_f32() #0 {
|
|
%x = call float @llvm.fma.f32(float 1.0, float 2.0, float 4.0) #0
|
|
ret float %x
|
|
}
|
|
|
|
; CHECK-LABEL: @constant_fold_fma_v4f32
|
|
; CHECK-NEXT: ret <4 x float> <float 1.200000e+01, float 1.400000e+01, float 1.600000e+01, float 1.800000e+01>
|
|
define <4 x float> @constant_fold_fma_v4f32() #0 {
|
|
%x = call <4 x float> @llvm.fma.v4f32(<4 x float> <float 1.0, float 2.0, float 3.0, float 4.0>, <4 x float> <float 2.0, float 2.0, float 2.0, float 2.0>, <4 x float> <float 10.0, float 10.0, float 10.0, float 10.0>)
|
|
ret <4 x float> %x
|
|
}
|
|
|
|
; CHECK-LABEL: @constant_fold_fmuladd_f32
|
|
; CHECK-NEXT: ret float 6.000000e+00
|
|
define float @constant_fold_fmuladd_f32() #0 {
|
|
%x = call float @llvm.fmuladd.f32(float 1.0, float 2.0, float 4.0) #0
|
|
ret float %x
|
|
}
|
|
|
|
; CHECK-LABEL: @constant_fold_fma_f64
|
|
; CHECK-NEXT: ret double 6.000000e+00
|
|
define double @constant_fold_fma_f64() #0 {
|
|
%x = call double @llvm.fma.f64(double 1.0, double 2.0, double 4.0) #0
|
|
ret double %x
|
|
}
|
|
|
|
; CHECK-LABEL: @constant_fold_fmuladd_f64
|
|
; CHECK-NEXT: ret double 6.000000e+00
|
|
define double @constant_fold_fmuladd_f64() #0 {
|
|
%x = call double @llvm.fmuladd.f64(double 1.0, double 2.0, double 4.0) #0
|
|
ret double %x
|
|
}
|
|
|
|
; The sqrt intrinsic is undefined for negative inputs besides -0.0.
|
|
; CHECK-LABEL: @bad_sqrt
|
|
; CHECK-NEXT: ret double undef
|
|
define double @bad_sqrt() {
|
|
%x = call double @llvm.sqrt.f64(double -2.000000e+00)
|
|
ret double %x
|
|
}
|
|
|
|
attributes #0 = { nounwind readnone }
|