Skip to content

Commit

Permalink
Define a new intrinsic @llvm.canonicalize.
Browse files Browse the repository at this point in the history
This is used the canonicalize floating point values, which is useful for
implementing certain numeric primitives.  See the LangRef changes for
the full details of its semantics.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@241977 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
resistor committed Jul 11, 2015
1 parent c51f300 commit acea229
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 0 deletions.
69 changes: 69 additions & 0 deletions docs/LangRef.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10199,6 +10199,75 @@ Examples:
Specialised Arithmetic Intrinsics
---------------------------------

'``llvm.canonicalize.*``' Intrinsic
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Syntax:
"""""""

::

declare float @llvm.canonicalize.f32(float %a)
declare double @llvm.canonicalize.f64(double %b)

Overview:
"""""""""

The '``llvm.canonicalize.*``' intrinsic returns the platform specific canonical
encoding of a floating point number. This canonicalization is useful for
implementing certain numeric primitives such as frexp. The canonical encoding is
defined by IEEE-754-2008 to be:

::

2.1.8 canonical encoding: The preferred encoding of a floating-point
representation in a format. Applied to declets, significands of finite
numbers, infinities, and NaNs, especially in decimal formats.

This operation can also be considered equivalent to the IEEE-754-2008
conversion of a floating-point value to the same format. NaNs are handled
according to section 6.2.

Examples of non-canonical encodings:

- x87 pseudo denormals, pseudo NaNs, pseudo Infinity, Unnormals. These are
converted to a canonical representation per hardware-specific protocol.
- Many normal decimal floating point numbers have non-canonical alternative
encodings.
- Some machines, like GPUs or ARMv7 NEON, do not support subnormal values.
These are treated as non-canonical encodings of zero and with be flushed to
a zero of the same sign by this operation.

Note that per IEEE-754-2008 6.2, systems that support signaling NaNs with
default exception handling must signal an invalid exception, and produce a
quiet NaN result.

This function should always be implementable as multiplication by 1.0, provided
that the compiler does not constant fold the operation. Likewise, division by
1.0 and ``llvm.minnum(x, x)`` are possible implementations. Addition with
-0.0 is also sufficient provided that the rounding mode is not -Infinity.

``@llvm.canonicalize`` must preserve the equality relation. That is:

- ``(@llvm.canonicalize(x) == x)`` is equivalent to ``(x == x)``
- ``(@llvm.canonicalize(x) == @llvm.canonicalize(y))`` is equivalent to
to ``(x == y)``

Additionally, the sign of zero must be conserved:
``@llvm.canonicalize(-0.0) = -0.0`` and ``@llvm.canonicalize(+0.0) = +0.0``

The payload bits of a NaN must be conserved, with two exceptions.
First, environments which use only a single canonical representation of NaN
must perform said canonicalization. Second, SNaNs must be quieted per the
usual methods.

The canonicalization operation may be optimized away if:

- The input is known to be canonical. For example, it was produced by a
floating-point operation that is required by the standard to be canonical.
- The result is consumed only by (or fused with) other floating-point
operations. That is, the bits of the floating point value are not examined.

'``llvm.fmuladd.*``' Intrinsic
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Expand Down
2 changes: 2 additions & 0 deletions include/llvm/IR/Intrinsics.td
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,8 @@ let Properties = [IntrNoMem] in {
def int_rint : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
def int_nearbyint : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
def int_round : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
def int_canonicalize : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>],
[IntrNoMem]>;
}

// NOTE: these are internal interfaces.
Expand Down

0 comments on commit acea229

Please sign in to comment.