[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



Index: llvm/docs/LangRef.rst
--- llvm/docs/LangRef.rst
+++ llvm/docs/LangRef.rst
@@ -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...
Name: D28797.84640.patch
Type: text/x-patch
Size: 650 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170117/1dd8670f/attachment.bin>

More information about the llvm-commits mailing list