Changeset View
Changeset View
Standalone View
Standalone View
test/Feature/fp-intrinsics.ll
; RUN: opt -O3 -S < %s | FileCheck %s | |||||
; Test to verify that constants aren't folded when the rounding mode is unknown. | |||||
; CHECK-LABEL: @f1 | |||||
; CHECK: call double @llvm.experimental.constrained.fdiv.f64 | |||||
define double @f1() { | |||||
entry: | |||||
%div = call double @llvm.experimental.constrained.fdiv.f64( | |||||
double 1.000000e+00, | |||||
double 1.000000e+01, | |||||
metadata !"round.dynamic", | |||||
metadata !"fpexcept.strict") | |||||
ret double %div | |||||
} | |||||
; Verify that 'a - 0' isn't simplified to 'a' when the rounding mode is unknown. | |||||
; | |||||
; double f2(double a) { | |||||
; // Because the result of '0 - 0' is negative zero if rounding mode is | |||||
; // downward, this shouldn't be simplified. | |||||
; return a - 0.0; | |||||
; } | |||||
; | |||||
; CHECK-LABEL: @f2 | |||||
; CHECK: call double @llvm.experimental.constrained.fsub.f64 | |||||
define double @f2(double %a) { | |||||
entry: | |||||
%div = call double @llvm.experimental.constrained.fsub.f64( | |||||
double %a, double 0.000000e+00, | |||||
metadata !"round.dynamic", | |||||
metadata !"fpexcept.strict") | |||||
ret double %div | |||||
} | |||||
; Verify that '-((-a)*b)' isn't simplified to 'a*b' when the rounding mode is | |||||
; unknown. | |||||
; | |||||
; double f3(double a, double b) { | |||||
; // Because the intermediate value involved in this calculation may require | |||||
; // rounding, this shouldn't be simplified. | |||||
; return -((-a)*b); | |||||
; } | |||||
; | |||||
; CHECK-LABEL: @f3 | |||||
; CHECK: call double @llvm.experimental.constrained.fsub.f64 | |||||
; CHECK: call double @llvm.experimental.constrained.fmul.f64 | |||||
; CHECK: call double @llvm.experimental.constrained.fsub.f64 | |||||
define double @f3(double %a, double %b) { | |||||
entry: | |||||
%sub = call double @llvm.experimental.constrained.fsub.f64( | |||||
double -0.000000e+00, double %a, | |||||
metadata !"round.dynamic", | |||||
metadata !"fpexcept.strict") | |||||
%mul = call double @llvm.experimental.constrained.fmul.f64( | |||||
double %sub, double %b, | |||||
metadata !"round.dynamic", | |||||
metadata !"fpexcept.strict") | |||||
%ret = call double @llvm.experimental.constrained.fsub.f64( | |||||
double -0.000000e+00, | |||||
double %mul, | |||||
metadata !"round.dynamic", | |||||
metadata !"fpexcept.strict") | |||||
ret double %ret | |||||
} | |||||
; Verify that FP operations are not performed speculatively when FP exceptions | |||||
; are not being ignored. | |||||
; | |||||
; double f4(int n, double a) { | |||||
; // Because a + 1 may overflow, this should not be simplified. | |||||
; if (n > 0) | |||||
; return a + 1.0; | |||||
; return a; | |||||
; } | |||||
; | |||||
; | |||||
; CHECK-LABEL: @f4 | |||||
; CHECK-NOT: select | |||||
; CHECK: br i1 %cmp | |||||
define double @f4(i32 %n, double %a) { | |||||
entry: | |||||
%cmp = icmp sgt i32 %n, 0 | |||||
br i1 %cmp, label %if.then, label %if.end | |||||
if.then: | |||||
%add = call double @llvm.experimental.constrained.fadd.f64( | |||||
double 1.000000e+00, double %a, | |||||
metadata !"round.dynamic", | |||||
metadata !"fpexcept.strict") | |||||
br label %if.end | |||||
if.end: | |||||
%a.0 = phi double [%add, %if.then], [ %a, %entry ] | |||||
ret double %a.0 | |||||
} | |||||
@llvm.fp.env = thread_local global i8 zeroinitializer, section "llvm.metadata" | |||||
declare double @llvm.experimental.constrained.fdiv.f64(double, double, metadata, metadata) | |||||
declare double @llvm.experimental.constrained.fmul.f64(double, double, metadata, metadata) | |||||
declare double @llvm.experimental.constrained.fadd.f64(double, double, metadata, metadata) | |||||
declare double @llvm.experimental.constrained.fsub.f64(double, double, metadata, metadata) |