[PATCH] D28797: [LangRef] Make @llvm.sqrt(x) return undef, rather than have UB, for negative x.
Justin Lebar via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 17 00:15:43 PST 2017
jlebar created this revision.
Herald added a subscriber: wdng.
Some frontends emit a speculate-and-select idiom for sqrt, wherein they compute
sqrt(x), check if x is negative, and select NaN if it is:
%cmp = fcmp olt double %a, -0.000000e+00
%sqrt = call double @llvm.sqrt.f64(double %a)
%ret = select i1 %cmp, double 0x7FF8000000000000, double %sqrt
This is technically UB as the LangRef is written today if %a is ever less than
-0. But emitting code that's compliant with the current definition of sqrt
would require a branch, which would then prevent us from matching this idiom in
SelectionDAG (which we do today -- ISD::FSQRT has defined behavior on negative
inputs), because SelectionDAG looks at one BB at a time.
Nothing in LLVM takes advantage of this undefined behavior, as far as we can
tell, and the fact that llvm.sqrt has UB dates from its initial addition to the
@@ -10061,7 +10061,7 @@
The '``llvm.sqrt``' intrinsics return the sqrt of the specified operand,
returning the same value as the libm '``sqrt``' functions would. Unlike
-``sqrt`` in libm, however, ``llvm.sqrt`` has undefined behavior for
+``sqrt`` in libm, however, ``llvm.sqrt`` returns undefined for
negative numbers other than -0.0 (which allows for better optimization,
because there is no need to worry about errno being set).
``llvm.sqrt(-0.0)`` is defined to return -0.0 like IEEE sqrt.
-------------- next part --------------
A non-text attachment was scrubbed...
Size: 650 bytes
Desc: not available
More information about the llvm-commits