Skip to content

Commit

Permalink
Allow speculating llvm.sqrt, fma and fmuladd
Browse files Browse the repository at this point in the history
This doesn't set errno, so this should be OK.
Also update the documentation to explicitly state
that errno are not set.

llvm-svn: 200501
  • Loading branch information
arsenm committed Jan 31, 2014
1 parent f33d8b9 commit ee364ee
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 2 deletions.
5 changes: 3 additions & 2 deletions llvm/docs/LangRef.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7490,7 +7490,7 @@ Semantics:
""""""""""

This function returns the same values as the libm ``fma`` functions
would.
would, and does not set errno.

'``llvm.fabs.*``' Intrinsic
^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down Expand Up @@ -8298,7 +8298,8 @@ is equivalent to the expression a \* b + c, except that rounding will
not be performed between the multiplication and addition steps if the
code generator fuses the operations. Fusion is not guaranteed, even if
the target platform supports it. If a fused multiply-add is required the
corresponding llvm.fma.\* intrinsic function should be used instead.
corresponding llvm.fma.\* intrinsic function should be used
instead. This never sets errno, just as '``llvm.fma.*``'.

Examples:
"""""""""
Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/Analysis/ValueTracking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2036,6 +2036,12 @@ bool llvm::isSafeToSpeculativelyExecute(const Value *V,
case Intrinsic::umul_with_overflow:
case Intrinsic::usub_with_overflow:
return true;
// Sqrt should be OK, since the llvm sqrt intrinsic isn't defined to set
// errno like libm sqrt would.
case Intrinsic::sqrt:
case Intrinsic::fma:
case Intrinsic::fmuladd:
return true;
// TODO: some fp intrinsics are marked as having the same error handling
// as libm. They're safe to speculate when they won't error.
// TODO: are convert_{from,to}_fp16 safe?
Expand Down
58 changes: 58 additions & 0 deletions llvm/test/Transforms/SimplifyCFG/speculate-math.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
; RUN: opt -S -simplifycfg -phi-node-folding-threshold=2 < %s | FileCheck %s

declare float @llvm.sqrt.f32(float) nounwind readonly
declare float @llvm.fma.f32(float, float, float) nounwind readonly
declare float @llvm.fmuladd.f32(float, float, float) nounwind readonly

; CHECK-LABEL: @sqrt_test(
; CHECK: select
define void @sqrt_test(float addrspace(1)* noalias nocapture %out, float %a) nounwind {
entry:
%cmp.i = fcmp olt float %a, 0.000000e+00
br i1 %cmp.i, label %test_sqrt.exit, label %cond.else.i

cond.else.i: ; preds = %entry
%0 = tail call float @llvm.sqrt.f32(float %a) nounwind readnone
br label %test_sqrt.exit

test_sqrt.exit: ; preds = %cond.else.i, %entry
%cond.i = phi float [ %0, %cond.else.i ], [ 0x7FF8000000000000, %entry ]
store float %cond.i, float addrspace(1)* %out, align 4
ret void
}


; CHECK-LABEL: @fma_test(
; CHECK: select
define void @fma_test(float addrspace(1)* noalias nocapture %out, float %a, float %b, float %c) nounwind {
entry:
%cmp.i = fcmp olt float %a, 0.000000e+00
br i1 %cmp.i, label %test_fma.exit, label %cond.else.i

cond.else.i: ; preds = %entry
%0 = tail call float @llvm.fma.f32(float %a, float %b, float %c) nounwind readnone
br label %test_fma.exit

test_fma.exit: ; preds = %cond.else.i, %entry
%cond.i = phi float [ %0, %cond.else.i ], [ 0x7FF8000000000000, %entry ]
store float %cond.i, float addrspace(1)* %out, align 4
ret void
}

; CHECK-LABEL: @fmuladd_test(
; CHECK: select
define void @fmuladd_test(float addrspace(1)* noalias nocapture %out, float %a, float %b, float %c) nounwind {
entry:
%cmp.i = fcmp olt float %a, 0.000000e+00
br i1 %cmp.i, label %test_fmuladd.exit, label %cond.else.i

cond.else.i: ; preds = %entry
%0 = tail call float @llvm.fmuladd.f32(float %a, float %b, float %c) nounwind readnone
br label %test_fmuladd.exit

test_fmuladd.exit: ; preds = %cond.else.i, %entry
%cond.i = phi float [ %0, %cond.else.i ], [ 0x7FF8000000000000, %entry ]
store float %cond.i, float addrspace(1)* %out, align 4
ret void
}

0 comments on commit ee364ee

Please sign in to comment.