[llvm] r317488 - [IR] redefine 'UnsafeAlgebra' / 'reassoc' fast-math-flags and add 'trans' fast-math-flag

David Jones via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 6 15:53:09 PST 2017


So it turns out there are some users of this API outside of LLVM/Clang:

https://cgit.freedesktop.org/mesa/mesa/tree/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp#n833
https://github.com/tensorflow/tensorflow/blob/master/tensorflow/compiler/xla/service/cpu/llvm_ir_runtime.cc#L55

It looks like they may be straightforward to change, but do you think it
might be worth adding back setUnsafeAlgebra() as a wrapper? (i.e., just to
set the bits for the same result as before)


On Mon, Nov 6, 2017 at 8:27 AM Sanjay Patel via llvm-commits <
llvm-commits at lists.llvm.org> wrote:

> Author: spatel
> Date: Mon Nov  6 08:27:15 2017
> New Revision: 317488
>
> URL: http://llvm.org/viewvc/llvm-project?rev=317488&view=rev
> Log:
> [IR] redefine 'UnsafeAlgebra' / 'reassoc' fast-math-flags and add 'trans'
> fast-math-flag
>
> As discussed on llvm-dev:
> http://lists.llvm.org/pipermail/llvm-dev/2016-November/107104.html
> and again more recently:
> http://lists.llvm.org/pipermail/llvm-dev/2017-October/118118.html
>
> ...this is a step in cleaning up our fast-math-flags implementation in IR
> to better match
> the capabilities of both clang's user-visible flags and the backend's
> flags for SDNode.
>
> As proposed in the above threads, we're replacing the 'UnsafeAlgebra' bit
> (which had the
> 'umbrella' meaning that all flags are set) with a new bit that only
> applies to algebraic
> reassociation - 'AllowReassoc'.
>
> We're also adding a bit to allow approximations for library functions
> called 'ApproxFunc'
> (this was initially proposed as 'libm' or similar).
>
> ...and we're out of bits. 7 bits ought to be enough for anyone, right? :)
> FWIW, I did
> look at getting this out of SubclassOptionalData via SubclassData
> (spacious 16-bits),
> but that's apparently already used for other purposes. Also, I don't think
> we can just
> add a field to FPMathOperator because Operator is not intended to be
> instantiated.
> We'll defer movement of FMF to another day.
>
> We keep the 'fast' keyword. I thought about removing that, but seeing IR
> like this:
> %f.fast = fadd reassoc nnan ninf nsz arcp contract afn float %op1, %op2
> ...made me think we want to keep the shortcut synonym.
>
> Finally, this change is binary incompatible with existing IR as seen in the
> compatibility tests. This statement:
> "Newer releases can ignore features from older releases, but they cannot
> miscompile
> them. For example, if nsw is ever replaced with something else, dropping
> it would be
> a valid way to upgrade the IR."
> ( http://llvm.org/docs/DeveloperPolicy.html#ir-backwards-compatibility )
> ...provides the flexibility we want to make this change without requiring
> a new IR
> version. Ie, we're not loosening the FP strictness of existing IR. At
> worst, we will
> fail to optimize some previously 'fast' code because it's no longer
> recognized as
> 'fast'. This should get fixed as we audit/squash all of the uses of
> 'isFast()'.
>
> Note: an inter-dependent clang commit to use the new API name should
> closely follow
> commit.
>
> Differential Revision: https://reviews.llvm.org/D39304
>
>
> Modified:
>     llvm/trunk/docs/LangRef.rst
>     llvm/trunk/include/llvm/IR/Instruction.h
>     llvm/trunk/include/llvm/IR/Operator.h
>     llvm/trunk/include/llvm/Transforms/Utils/LoopUtils.h
>     llvm/trunk/lib/AsmParser/LLLexer.cpp
>     llvm/trunk/lib/AsmParser/LLParser.h
>     llvm/trunk/lib/AsmParser/LLToken.h
>     llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
>     llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
>     llvm/trunk/lib/CodeGen/ExpandReductions.cpp
>     llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
>     llvm/trunk/lib/IR/AsmWriter.cpp
>     llvm/trunk/lib/IR/Instruction.cpp
>     llvm/trunk/lib/Target/AMDGPU/AMDGPUCodeGenPrepare.cpp
>     llvm/trunk/lib/Target/AMDGPU/AMDGPULibCalls.cpp
>     llvm/trunk/lib/Transforms/InstCombine/InstCombineAddSub.cpp
>     llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp
>     llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
>     llvm/trunk/lib/Transforms/Scalar/Reassociate.cpp
>     llvm/trunk/lib/Transforms/Utils/LoopUtils.cpp
>     llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp
>     llvm/trunk/lib/Transforms/Vectorize/LoopVectorize.cpp
>     llvm/trunk/lib/Transforms/Vectorize/SLPVectorizer.cpp
>     llvm/trunk/test/Assembler/fast-math-flags.ll
>     llvm/trunk/test/Bitcode/compatibility-3.6.ll
>     llvm/trunk/test/Bitcode/compatibility-3.7.ll
>     llvm/trunk/test/Bitcode/compatibility-3.8.ll
>     llvm/trunk/test/Bitcode/compatibility-3.9.ll
>     llvm/trunk/test/Bitcode/compatibility-4.0.ll
>     llvm/trunk/test/Bitcode/compatibility-5.0.ll
>     llvm/trunk/test/Bitcode/compatibility.ll
>     llvm/trunk/unittests/IR/IRBuilderTest.cpp
>
> Modified: llvm/trunk/docs/LangRef.rst
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.rst?rev=317488&r1=317487&r2=317488&view=diff
>
> ==============================================================================
> --- llvm/trunk/docs/LangRef.rst (original)
> +++ llvm/trunk/docs/LangRef.rst Mon Nov  6 08:27:15 2017
> @@ -2272,11 +2272,11 @@ seq\_cst total orderings of other operat
>  Fast-Math Flags
>  ---------------
>
> -LLVM IR floating-point binary ops (:ref:`fadd <i_fadd>`,
> +LLVM IR floating-point operations (:ref:`fadd <i_fadd>`,
>  :ref:`fsub <i_fsub>`, :ref:`fmul <i_fmul>`, :ref:`fdiv <i_fdiv>`,
>  :ref:`frem <i_frem>`, :ref:`fcmp <i_fcmp>`) and :ref:`call <i_call>`
> -instructions have the following flags that can be set to enable
> -otherwise unsafe floating point transformations.
> +may use the following flags to enable otherwise unsafe
> +floating-point transformations.
>
>  ``nnan``
>     No NaNs - Allow optimizations to assume the arguments and result are
> not
> @@ -2300,10 +2300,17 @@ otherwise unsafe floating point transfor
>     Allow floating-point contraction (e.g. fusing a multiply followed by an
>     addition into a fused multiply-and-add).
>
> +``afn``
> +   Approximate functions - Allow substitution of approximate calculations
> for
> +   functions (sin, log, sqrt, etc). See floating-point intrinsic
> definitions
> +   for places where this can apply to LLVM's intrinsic math functions.
> +
> +``reassoc``
> +   Allow reassociation transformations for floating-point instructions.
> +   This may dramatically change results in floating point.
> +
>  ``fast``
> -   Fast - Allow algebraically equivalent transformations that may
> -   dramatically change results in floating point (e.g. reassociate). This
> -   flag implies all the others.
> +   This flag implies all of the others.
>
>  .. _uselistorder:
>
> @@ -10483,7 +10490,7 @@ Syntax:
>  """""""
>
>  This is an overloaded intrinsic. You can use ``llvm.sqrt`` on any
> -floating point or vector of floating point type. Not all targets support
> +floating-point or vector of floating-point type. Not all targets support
>  all types however.
>
>  ::
> @@ -10497,20 +10504,22 @@ all types however.
>  Overview:
>  """""""""
>
> -The '``llvm.sqrt``' intrinsics return the square root of the specified
> value,
> -returning the same value as the libm '``sqrt``' functions would, but
> without
> -trapping or setting ``errno``.
> +The '``llvm.sqrt``' intrinsics return the square root of the specified
> value.
>
>  Arguments:
>  """"""""""
>
> -The argument and return value are floating point numbers of the same type.
> +The argument and return value are floating-point numbers of the same type.
>
>  Semantics:
>  """"""""""
>
> -This function returns the square root of the operand if it is a
> nonnegative
> -floating point number.
> +Return the same value as a corresponding libm '``sqrt``' function but
> without
> +trapping or setting ``errno``. For types specified by IEEE-754, the result
> +matches a conforming libm implementation.
> +
> +When specified with the fast-math-flag 'afn', the result may be
> approximated
> +using a less accurate calculation.
>
>  '``llvm.powi.*``' Intrinsic
>  ^^^^^^^^^^^^^^^^^^^^^^^^^^^
> @@ -10557,7 +10566,7 @@ Syntax:
>  """""""
>
>  This is an overloaded intrinsic. You can use ``llvm.sin`` on any
> -floating point or vector of floating point type. Not all targets support
> +floating-point or vector of floating-point type. Not all targets support
>  all types however.
>
>  ::
> @@ -10576,14 +10585,16 @@ The '``llvm.sin.*``' intrinsics return t
>  Arguments:
>  """"""""""
>
> -The argument and return value are floating point numbers of the same type.
> +The argument and return value are floating-point numbers of the same type.
>
>  Semantics:
>  """"""""""
>
> -This function returns the sine of the specified operand, returning the
> -same values as the libm ``sin`` functions would, and handles error
> -conditions in the same way.
> +Return the same value as a corresponding libm '``sin``' function but
> without
> +trapping or setting ``errno``.
> +
> +When specified with the fast-math-flag 'afn', the result may be
> approximated
> +using a less accurate calculation.
>
>  '``llvm.cos.*``' Intrinsic
>  ^^^^^^^^^^^^^^^^^^^^^^^^^^
> @@ -10592,7 +10603,7 @@ Syntax:
>  """""""
>
>  This is an overloaded intrinsic. You can use ``llvm.cos`` on any
> -floating point or vector of floating point type. Not all targets support
> +floating-point or vector of floating-point type. Not all targets support
>  all types however.
>
>  ::
> @@ -10611,14 +10622,16 @@ The '``llvm.cos.*``' intrinsics return t
>  Arguments:
>  """"""""""
>
> -The argument and return value are floating point numbers of the same type.
> +The argument and return value are floating-point numbers of the same type.
>
>  Semantics:
>  """"""""""
>
> -This function returns the cosine of the specified operand, returning the
> -same values as the libm ``cos`` functions would, and handles error
> -conditions in the same way.
> +Return the same value as a corresponding libm '``cos``' function but
> without
> +trapping or setting ``errno``.
> +
> +When specified with the fast-math-flag 'afn', the result may be
> approximated
> +using a less accurate calculation.
>
>  '``llvm.pow.*``' Intrinsic
>  ^^^^^^^^^^^^^^^^^^^^^^^^^^
> @@ -10627,7 +10640,7 @@ Syntax:
>  """""""
>
>  This is an overloaded intrinsic. You can use ``llvm.pow`` on any
> -floating point or vector of floating point type. Not all targets support
> +floating-point or vector of floating-point type. Not all targets support
>  all types however.
>
>  ::
> @@ -10647,15 +10660,16 @@ specified (positive or negative) power.
>  Arguments:
>  """"""""""
>
> -The second argument is a floating point power, and the first is a value
> -to raise to that power.
> +The arguments and return value are floating-point numbers of the same
> type.
>
>  Semantics:
>  """"""""""
>
> -This function returns the first value raised to the second power,
> -returning the same values as the libm ``pow`` functions would, and
> -handles error conditions in the same way.
> +Return the same value as a corresponding libm '``pow``' function but
> without
> +trapping or setting ``errno``.
> +
> +When specified with the fast-math-flag 'afn', the result may be
> approximated
> +using a less accurate calculation.
>
>  '``llvm.exp.*``' Intrinsic
>  ^^^^^^^^^^^^^^^^^^^^^^^^^^
> @@ -10664,7 +10678,7 @@ Syntax:
>  """""""
>
>  This is an overloaded intrinsic. You can use ``llvm.exp`` on any
> -floating point or vector of floating point type. Not all targets support
> +floating-point or vector of floating-point type. Not all targets support
>  all types however.
>
>  ::
> @@ -10684,13 +10698,16 @@ value.
>  Arguments:
>  """"""""""
>
> -The argument and return value are floating point numbers of the same type.
> +The argument and return value are floating-point numbers of the same type.
>
>  Semantics:
>  """"""""""
>
> -This function returns the same values as the libm ``exp`` functions
> -would, and handles error conditions in the same way.
> +Return the same value as a corresponding libm '``exp``' function but
> without
> +trapping or setting ``errno``.
> +
> +When specified with the fast-math-flag 'afn', the result may be
> approximated
> +using a less accurate calculation.
>
>  '``llvm.exp2.*``' Intrinsic
>  ^^^^^^^^^^^^^^^^^^^^^^^^^^^
> @@ -10699,7 +10716,7 @@ Syntax:
>  """""""
>
>  This is an overloaded intrinsic. You can use ``llvm.exp2`` on any
> -floating point or vector of floating point type. Not all targets support
> +floating-point or vector of floating-point type. Not all targets support
>  all types however.
>
>  ::
> @@ -10719,13 +10736,16 @@ specified value.
>  Arguments:
>  """"""""""
>
> -The argument and return value are floating point numbers of the same type.
> +The argument and return value are floating-point numbers of the same type.
>
>  Semantics:
>  """"""""""
>
> -This function returns the same values as the libm ``exp2`` functions
> -would, and handles error conditions in the same way.
> +Return the same value as a corresponding libm '``exp2``' function but
> without
> +trapping or setting ``errno``.
> +
> +When specified with the fast-math-flag 'afn', the result may be
> approximated
> +using a less accurate calculation.
>
>  '``llvm.log.*``' Intrinsic
>  ^^^^^^^^^^^^^^^^^^^^^^^^^^
> @@ -10734,7 +10754,7 @@ Syntax:
>  """""""
>
>  This is an overloaded intrinsic. You can use ``llvm.log`` on any
> -floating point or vector of floating point type. Not all targets support
> +floating-point or vector of floating-point type. Not all targets support
>  all types however.
>
>  ::
> @@ -10754,13 +10774,16 @@ value.
>  Arguments:
>  """"""""""
>
> -The argument and return value are floating point numbers of the same type.
> +The argument and return value are floating-point numbers of the same type.
>
>  Semantics:
>  """"""""""
>
> -This function returns the same values as the libm ``log`` functions
> -would, and handles error conditions in the same way.
> +Return the same value as a corresponding libm '``log``' function but
> without
> +trapping or setting ``errno``.
> +
> +When specified with the fast-math-flag 'afn', the result may be
> approximated
> +using a less accurate calculation.
>
>  '``llvm.log10.*``' Intrinsic
>  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> @@ -10769,7 +10792,7 @@ Syntax:
>  """""""
>
>  This is an overloaded intrinsic. You can use ``llvm.log10`` on any
> -floating point or vector of floating point type. Not all targets support
> +floating-point or vector of floating-point type. Not all targets support
>  all types however.
>
>  ::
> @@ -10789,13 +10812,16 @@ specified value.
>  Arguments:
>  """"""""""
>
> -The argument and return value are floating point numbers of the same type.
> +The argument and return value are floating-point numbers of the same type.
>
>  Semantics:
>  """"""""""
>
> -This function returns the same values as the libm ``log10`` functions
> -would, and handles error conditions in the same way.
> +Return the same value as a corresponding libm '``log10``' function but
> without
> +trapping or setting ``errno``.
> +
> +When specified with the fast-math-flag 'afn', the result may be
> approximated
> +using a less accurate calculation.
>
>  '``llvm.log2.*``' Intrinsic
>  ^^^^^^^^^^^^^^^^^^^^^^^^^^^
> @@ -10804,7 +10830,7 @@ Syntax:
>  """""""
>
>  This is an overloaded intrinsic. You can use ``llvm.log2`` on any
> -floating point or vector of floating point type. Not all targets support
> +floating-point or vector of floating-point type. Not all targets support
>  all types however.
>
>  ::
> @@ -10824,13 +10850,16 @@ value.
>  Arguments:
>  """"""""""
>
> -The argument and return value are floating point numbers of the same type.
> +The argument and return value are floating-point numbers of the same type.
>
>  Semantics:
>  """"""""""
>
> -This function returns the same values as the libm ``log2`` functions
> -would, and handles error conditions in the same way.
> +Return the same value as a corresponding libm '``log2``' function but
> without
> +trapping or setting ``errno``.
> +
> +When specified with the fast-math-flag 'afn', the result may be
> approximated
> +using a less accurate calculation.
>
>  '``llvm.fma.*``' Intrinsic
>  ^^^^^^^^^^^^^^^^^^^^^^^^^^
> @@ -10839,7 +10868,7 @@ Syntax:
>  """""""
>
>  This is an overloaded intrinsic. You can use ``llvm.fma`` on any
> -floating point or vector of floating point type. Not all targets support
> +floating-point or vector of floating-point type. Not all targets support
>  all types however.
>
>  ::
> @@ -10853,20 +10882,21 @@ all types however.
>  Overview:
>  """""""""
>
> -The '``llvm.fma.*``' intrinsics perform the fused multiply-add
> -operation.
> +The '``llvm.fma.*``' intrinsics perform the fused multiply-add operation.
>
>  Arguments:
>  """"""""""
>
> -The argument and return value are floating point numbers of the same
> -type.
> +The arguments and return value are floating-point numbers of the same
> type.
>
>  Semantics:
>  """"""""""
>
> -This function returns the same values as the libm ``fma`` functions
> -would, and does not set errno.
> +Return the same value as a corresponding libm '``fma``' function but
> without
> +trapping or setting ``errno``.
> +
> +When specified with the fast-math-flag 'afn', the result may be
> approximated
> +using a less accurate calculation.
>
>  '``llvm.fabs.*``' Intrinsic
>  ^^^^^^^^^^^^^^^^^^^^^^^^^^^
>
> Modified: llvm/trunk/include/llvm/IR/Instruction.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Instruction.h?rev=317488&r1=317487&r2=317488&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/IR/Instruction.h (original)
> +++ llvm/trunk/include/llvm/IR/Instruction.h Mon Nov  6 08:27:15 2017
> @@ -308,10 +308,15 @@ public:
>    /// Determine whether the exact flag is set.
>    bool isExact() const;
>
> -  /// Set or clear the unsafe-algebra flag on this instruction, which
> must be an
> +  /// Set or clear all fast-math-flags on this instruction, which must be
> an
>    /// operator which supports this flag. See LangRef.html for the meaning
> of
>    /// this flag.
> -  void setHasUnsafeAlgebra(bool B);
> +  void setFast(bool B);
> +
> +  /// Set or clear the reassociation flag on this instruction, which must
> be
> +  /// an operator which supports this flag. See LangRef.html for the
> meaning of
> +  /// this flag.
> +  void setHasAllowReassoc(bool B);
>
>    /// Set or clear the no-nans flag on this instruction, which must be an
>    /// operator which supports this flag. See LangRef.html for the meaning
> of
> @@ -333,6 +338,11 @@ public:
>    /// this flag.
>    void setHasAllowReciprocal(bool B);
>
> +  /// Set or clear the approximate-math-functions flag on this
> instruction,
> +  /// which must be an operator which supports this flag. See
> LangRef.html for
> +  /// the meaning of this flag.
> +  void setHasApproxFunc(bool B);
> +
>    /// Convenience function for setting multiple fast-math flags on this
>    /// instruction, which must be an operator which supports these flags.
> See
>    /// LangRef.html for the meaning of these flags.
> @@ -343,8 +353,11 @@ public:
>    /// LangRef.html for the meaning of these flags.
>    void copyFastMathFlags(FastMathFlags FMF);
>
> -  /// Determine whether the unsafe-algebra flag is set.
> -  bool hasUnsafeAlgebra() const;
> +  /// Determine whether all fast-math-flags are set.
> +  bool isFast() const;
> +
> +  /// Determine whether the allow-reassociation flag is set.
> +  bool hasAllowReassoc() const;
>
>    /// Determine whether the no-NaNs flag is set.
>    bool hasNoNaNs() const;
> @@ -361,6 +374,9 @@ public:
>    /// Determine whether the allow-contract flag is set.
>    bool hasAllowContract() const;
>
> +  /// Determine whether the approximate-math-functions flag is set.
> +  bool hasApproxFunc() const;
> +
>    /// Convenience function for getting all the fast-math flags, which
> must be an
>    /// operator which supports these flags. See LangRef.html for the
> meaning of
>    /// these flags.
>
> Modified: llvm/trunk/include/llvm/IR/Operator.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Operator.h?rev=317488&r1=317487&r2=317488&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/IR/Operator.h (original)
> +++ llvm/trunk/include/llvm/IR/Operator.h Mon Nov  6 08:27:15 2017
> @@ -163,52 +163,61 @@ private:
>
>    unsigned Flags = 0;
>
> -  FastMathFlags(unsigned F) : Flags(F) { }
> +  FastMathFlags(unsigned F) {
> +    // If all 7 bits are set, turn this into -1. If the number of bits
> grows,
> +    // this must be updated. This is intended to provide some forward
> binary
> +    // compatibility insurance for the meaning of 'fast' in case bits are
> added.
> +    if (F == 0x7F) Flags = ~0U;
> +    else Flags = F;
> +  }
>
>  public:
> -  /// This is how the bits are used in Value::SubclassOptionalData so they
> -  /// should fit there too.
> +  // This is how the bits are used in Value::SubclassOptionalData so they
> +  // should fit there too.
> +  // WARNING: We're out of space. SubclassOptionalData only has 7 bits.
> New
> +  // functionality will require a change in how this information is
> stored.
>    enum {
> -    UnsafeAlgebra   = (1 << 0),
> +    AllowReassoc    = (1 << 0),
>      NoNaNs          = (1 << 1),
>      NoInfs          = (1 << 2),
>      NoSignedZeros   = (1 << 3),
>      AllowReciprocal = (1 << 4),
> -    AllowContract   = (1 << 5)
> +    AllowContract   = (1 << 5),
> +    ApproxFunc      = (1 << 6)
>    };
>
>    FastMathFlags() = default;
>
> -  /// Whether any flag is set
>    bool any() const { return Flags != 0; }
> +  bool none() const { return Flags == 0; }
> +  bool all() const { return Flags == ~0U; }
>
> -  /// Set all the flags to false
>    void clear() { Flags = 0; }
> +  void set()   { Flags = ~0U; }
>
>    /// Flag queries
> +  bool allowReassoc() const    { return 0 != (Flags & AllowReassoc); }
>    bool noNaNs() const          { return 0 != (Flags & NoNaNs); }
>    bool noInfs() const          { return 0 != (Flags & NoInfs); }
>    bool noSignedZeros() const   { return 0 != (Flags & NoSignedZeros); }
>    bool allowReciprocal() const { return 0 != (Flags & AllowReciprocal); }
> -  bool allowContract() const { return 0 != (Flags & AllowContract); }
> -  bool unsafeAlgebra() const   { return 0 != (Flags & UnsafeAlgebra); }
> +  bool allowContract() const   { return 0 != (Flags & AllowContract); }
> +  bool approxFunc() const      { return 0 != (Flags & ApproxFunc); }
> +  /// 'Fast' means all bits are set.
> +  bool isFast() const          { return all(); }
>
>    /// Flag setters
> +  void setAllowReassoc()    { Flags |= AllowReassoc; }
>    void setNoNaNs()          { Flags |= NoNaNs; }
>    void setNoInfs()          { Flags |= NoInfs; }
>    void setNoSignedZeros()   { Flags |= NoSignedZeros; }
>    void setAllowReciprocal() { Flags |= AllowReciprocal; }
> +  // TODO: Change the other set* functions to take a parameter?
>    void setAllowContract(bool B) {
>      Flags = (Flags & ~AllowContract) | B * AllowContract;
>    }
> -  void setUnsafeAlgebra() {
> -    Flags |= UnsafeAlgebra;
> -    setNoNaNs();
> -    setNoInfs();
> -    setNoSignedZeros();
> -    setAllowReciprocal();
> -    setAllowContract(true);
> -  }
> +  void setApproxFunc()      { Flags |= ApproxFunc; }
> +  void setFast()            { set(); }
>
>    void operator&=(const FastMathFlags &OtherFlags) {
>      Flags &= OtherFlags.Flags;
> @@ -221,18 +230,21 @@ class FPMathOperator : public Operator {
>  private:
>    friend class Instruction;
>
> -  void setHasUnsafeAlgebra(bool B) {
> -    SubclassOptionalData =
> -      (SubclassOptionalData & ~FastMathFlags::UnsafeAlgebra) |
> -      (B * FastMathFlags::UnsafeAlgebra);
> +  /// 'Fast' means all bits are set.
> +  void setFast(bool B) {
> +    setHasAllowReassoc(B);
> +    setHasNoNaNs(B);
> +    setHasNoInfs(B);
> +    setHasNoSignedZeros(B);
> +    setHasAllowReciprocal(B);
> +    setHasAllowContract(B);
> +    setHasApproxFunc(B);
> +  }
>
> -    // Unsafe algebra implies all the others
> -    if (B) {
> -      setHasNoNaNs(true);
> -      setHasNoInfs(true);
> -      setHasNoSignedZeros(true);
> -      setHasAllowReciprocal(true);
> -    }
> +  void setHasAllowReassoc(bool B) {
> +    SubclassOptionalData =
> +    (SubclassOptionalData & ~FastMathFlags::AllowReassoc) |
> +    (B * FastMathFlags::AllowReassoc);
>    }
>
>    void setHasNoNaNs(bool B) {
> @@ -265,6 +277,12 @@ private:
>          (B * FastMathFlags::AllowContract);
>    }
>
> +  void setHasApproxFunc(bool B) {
> +    SubclassOptionalData =
> +        (SubclassOptionalData & ~FastMathFlags::ApproxFunc) |
> +        (B * FastMathFlags::ApproxFunc);
> +  }
> +
>    /// Convenience function for setting multiple fast-math flags.
>    /// FMF is a mask of the bits to set.
>    void setFastMathFlags(FastMathFlags FMF) {
> @@ -278,42 +296,53 @@ private:
>    }
>
>  public:
> -  /// Test whether this operation is permitted to be
> -  /// algebraically transformed, aka the 'A' fast-math property.
> -  bool hasUnsafeAlgebra() const {
> -    return (SubclassOptionalData & FastMathFlags::UnsafeAlgebra) != 0;
> +  /// Test if this operation allows all non-strict floating-point
> transforms.
> +  bool isFast() const {
> +    return ((SubclassOptionalData & FastMathFlags::AllowReassoc) != 0 &&
> +            (SubclassOptionalData & FastMathFlags::NoNaNs) != 0 &&
> +            (SubclassOptionalData & FastMathFlags::NoInfs) != 0 &&
> +            (SubclassOptionalData & FastMathFlags::NoSignedZeros) != 0 &&
> +            (SubclassOptionalData & FastMathFlags::AllowReciprocal) != 0
> &&
> +            (SubclassOptionalData & FastMathFlags::AllowContract) != 0 &&
> +            (SubclassOptionalData & FastMathFlags::ApproxFunc) != 0);
> +  }
> +
> +  /// Test if this operation may be simplified with reassociative
> transforms.
> +  bool hasAllowReassoc() const {
> +    return (SubclassOptionalData & FastMathFlags::AllowReassoc) != 0;
>    }
>
> -  /// Test whether this operation's arguments and results are to be
> -  /// treated as non-NaN, aka the 'N' fast-math property.
> +  /// Test if this operation's arguments and results are assumed not-NaN.
>    bool hasNoNaNs() const {
>      return (SubclassOptionalData & FastMathFlags::NoNaNs) != 0;
>    }
>
> -  /// Test whether this operation's arguments and results are to be
> -  /// treated as NoN-Inf, aka the 'I' fast-math property.
> +  /// Test if this operation's arguments and results are assumed
> not-infinite.
>    bool hasNoInfs() const {
>      return (SubclassOptionalData & FastMathFlags::NoInfs) != 0;
>    }
>
> -  /// Test whether this operation can treat the sign of zero
> -  /// as insignificant, aka the 'S' fast-math property.
> +  /// Test if this operation can ignore the sign of zero.
>    bool hasNoSignedZeros() const {
>      return (SubclassOptionalData & FastMathFlags::NoSignedZeros) != 0;
>    }
>
> -  /// Test whether this operation is permitted to use
> -  /// reciprocal instead of division, aka the 'R' fast-math property.
> +  /// Test if this operation can use reciprocal multiply instead of
> division.
>    bool hasAllowReciprocal() const {
>      return (SubclassOptionalData & FastMathFlags::AllowReciprocal) != 0;
>    }
>
> -  /// Test whether this operation is permitted to
> -  /// be floating-point contracted.
> +  /// Test if this operation can be floating-point contracted (FMA).
>    bool hasAllowContract() const {
>      return (SubclassOptionalData & FastMathFlags::AllowContract) != 0;
>    }
>
> +  /// Test if this operation allows approximations of math library
> functions or
> +  /// intrinsics.
> +  bool hasApproxFunc() const {
> +    return (SubclassOptionalData & FastMathFlags::ApproxFunc) != 0;
> +  }
> +
>    /// Convenience function for getting all the fast-math flags
>    FastMathFlags getFastMathFlags() const {
>      return FastMathFlags(SubclassOptionalData);
>
> Modified: llvm/trunk/include/llvm/Transforms/Utils/LoopUtils.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/LoopUtils.h?rev=317488&r1=317487&r2=317488&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/Transforms/Utils/LoopUtils.h (original)
> +++ llvm/trunk/include/llvm/Transforms/Utils/LoopUtils.h Mon Nov  6
> 08:27:15 2017
> @@ -331,15 +331,13 @@ public:
>    /// not have the "fast-math" property. Such operation requires a
> relaxed FP
>    /// mode.
>    bool hasUnsafeAlgebra() {
> -    return InductionBinOp &&
> -      !cast<FPMathOperator>(InductionBinOp)->hasUnsafeAlgebra();
> +    return InductionBinOp &&
> !cast<FPMathOperator>(InductionBinOp)->isFast();
>    }
>
>    /// Returns induction operator that does not have "fast-math" property
>    /// and requires FP unsafe mode.
>    Instruction *getUnsafeAlgebraInst() {
> -    if (!InductionBinOp ||
> -        cast<FPMathOperator>(InductionBinOp)->hasUnsafeAlgebra())
> +    if (!InductionBinOp || cast<FPMathOperator>(InductionBinOp)->isFast())
>        return nullptr;
>      return InductionBinOp;
>    }
>
> Modified: llvm/trunk/lib/AsmParser/LLLexer.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLLexer.cpp?rev=317488&r1=317487&r2=317488&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/AsmParser/LLLexer.cpp (original)
> +++ llvm/trunk/lib/AsmParser/LLLexer.cpp Mon Nov  6 08:27:15 2017
> @@ -552,6 +552,8 @@ lltok::Kind LLLexer::LexIdentifier() {
>    KEYWORD(nsz);
>    KEYWORD(arcp);
>    KEYWORD(contract);
> +  KEYWORD(reassoc);
> +  KEYWORD(afn);
>    KEYWORD(fast);
>    KEYWORD(nuw);
>    KEYWORD(nsw);
>
> Modified: llvm/trunk/lib/AsmParser/LLParser.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.h?rev=317488&r1=317487&r2=317488&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/AsmParser/LLParser.h (original)
> +++ llvm/trunk/lib/AsmParser/LLParser.h Mon Nov  6 08:27:15 2017
> @@ -193,7 +193,7 @@ namespace llvm {
>        FastMathFlags FMF;
>        while (true)
>          switch (Lex.getKind()) {
> -        case lltok::kw_fast: FMF.setUnsafeAlgebra();   Lex.Lex();
> continue;
> +        case lltok::kw_fast: FMF.setFast();            Lex.Lex();
> continue;
>          case lltok::kw_nnan: FMF.setNoNaNs();          Lex.Lex();
> continue;
>          case lltok::kw_ninf: FMF.setNoInfs();          Lex.Lex();
> continue;
>          case lltok::kw_nsz:  FMF.setNoSignedZeros();   Lex.Lex();
> continue;
> @@ -202,6 +202,8 @@ namespace llvm {
>            FMF.setAllowContract(true);
>            Lex.Lex();
>            continue;
> +        case lltok::kw_reassoc: FMF.setAllowReassoc(); Lex.Lex();
> continue;
> +        case lltok::kw_afn:     FMF.setApproxFunc();   Lex.Lex();
> continue;
>          default: return FMF;
>          }
>        return FMF;
>
> Modified: llvm/trunk/lib/AsmParser/LLToken.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLToken.h?rev=317488&r1=317487&r2=317488&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/AsmParser/LLToken.h (original)
> +++ llvm/trunk/lib/AsmParser/LLToken.h Mon Nov  6 08:27:15 2017
> @@ -102,6 +102,8 @@ enum Kind {
>    kw_nsz,
>    kw_arcp,
>    kw_contract,
> +  kw_reassoc,
> +  kw_afn,
>    kw_fast,
>    kw_nuw,
>    kw_nsw,
>
> Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=317488&r1=317487&r2=317488&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original)
> +++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Mon Nov  6 08:27:15
> 2017
> @@ -1046,8 +1046,8 @@ static Comdat::SelectionKind getDecodedC
>
>  static FastMathFlags getDecodedFastMathFlags(unsigned Val) {
>    FastMathFlags FMF;
> -  if (0 != (Val & FastMathFlags::UnsafeAlgebra))
> -    FMF.setUnsafeAlgebra();
> +  if (0 != (Val & FastMathFlags::AllowReassoc))
> +    FMF.setAllowReassoc();
>    if (0 != (Val & FastMathFlags::NoNaNs))
>      FMF.setNoNaNs();
>    if (0 != (Val & FastMathFlags::NoInfs))
> @@ -1058,6 +1058,8 @@ static FastMathFlags getDecodedFastMathF
>      FMF.setAllowReciprocal();
>    if (0 != (Val & FastMathFlags::AllowContract))
>      FMF.setAllowContract(true);
> +  if (0 != (Val & FastMathFlags::ApproxFunc))
> +    FMF.setApproxFunc();
>    return FMF;
>  }
>
>
> Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=317488&r1=317487&r2=317488&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original)
> +++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Mon Nov  6 08:27:15
> 2017
> @@ -1321,8 +1321,8 @@ static uint64_t getOptimizationFlags(con
>      if (PEO->isExact())
>        Flags |= 1 << bitc::PEO_EXACT;
>    } else if (const auto *FPMO = dyn_cast<FPMathOperator>(V)) {
> -    if (FPMO->hasUnsafeAlgebra())
> -      Flags |= FastMathFlags::UnsafeAlgebra;
> +    if (FPMO->hasAllowReassoc())
> +      Flags |= FastMathFlags::AllowReassoc;
>      if (FPMO->hasNoNaNs())
>        Flags |= FastMathFlags::NoNaNs;
>      if (FPMO->hasNoInfs())
> @@ -1333,6 +1333,8 @@ static uint64_t getOptimizationFlags(con
>        Flags |= FastMathFlags::AllowReciprocal;
>      if (FPMO->hasAllowContract())
>        Flags |= FastMathFlags::AllowContract;
> +    if (FPMO->hasApproxFunc())
> +      Flags |= FastMathFlags::ApproxFunc;
>    }
>
>    return Flags;
>
> Modified: llvm/trunk/lib/CodeGen/ExpandReductions.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ExpandReductions.cpp?rev=317488&r1=317487&r2=317488&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/ExpandReductions.cpp (original)
> +++ llvm/trunk/lib/CodeGen/ExpandReductions.cpp Mon Nov  6 08:27:15 2017
> @@ -95,7 +95,7 @@ bool expandReductions(Function &F, const
>        // and it can't be handled by generating this shuffle sequence.
>        // TODO: Implement scalarization of ordered reductions here for
> targets
>        // without native support.
> -      if (!II->getFastMathFlags().unsafeAlgebra())
> +      if (!II->getFastMathFlags().isFast())
>          continue;
>        Vec = II->getArgOperand(1);
>        break;
>
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=317488&r1=317487&r2=317488&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Mon Nov  6
> 08:27:15 2017
> @@ -2585,7 +2585,7 @@ static bool isVectorReductionOp(const Us
>    case Instruction::FAdd:
>    case Instruction::FMul:
>      if (const FPMathOperator *FPOp = dyn_cast<const FPMathOperator>(Inst))
> -      if (FPOp->getFastMathFlags().unsafeAlgebra())
> +      if (FPOp->getFastMathFlags().isFast())
>          break;
>      LLVM_FALLTHROUGH;
>    default:
> @@ -2631,7 +2631,7 @@ static bool isVectorReductionOp(const Us
>
>        if (Inst->getOpcode() == OpCode || isa<PHINode>(U)) {
>          if (const FPMathOperator *FPOp = dyn_cast<const
> FPMathOperator>(Inst))
> -          if (!isa<PHINode>(FPOp) &&
> !FPOp->getFastMathFlags().unsafeAlgebra())
> +          if (!isa<PHINode>(FPOp) && !FPOp->getFastMathFlags().isFast())
>              return false;
>          UsersToVisit.push_back(U);
>        } else if (const ShuffleVectorInst *ShufInst =
> @@ -2725,7 +2725,7 @@ void SelectionDAGBuilder::visitBinary(co
>    Flags.setNoInfs(FMF.noInfs());
>    Flags.setNoNaNs(FMF.noNaNs());
>    Flags.setNoSignedZeros(FMF.noSignedZeros());
> -  Flags.setUnsafeAlgebra(FMF.unsafeAlgebra());
> +  Flags.setUnsafeAlgebra(FMF.isFast());
>
>    SDValue BinNodeValue = DAG.getNode(OpCode, getCurSDLoc(),
> Op1.getValueType(),
>                                       Op1, Op2, Flags);
> @@ -7959,13 +7959,13 @@ void SelectionDAGBuilder::visitVectorRed
>
>    switch (Intrinsic) {
>    case Intrinsic::experimental_vector_reduce_fadd:
> -    if (FMF.unsafeAlgebra())
> +    if (FMF.isFast())
>        Res = DAG.getNode(ISD::VECREDUCE_FADD, dl, VT, Op2);
>      else
>        Res = DAG.getNode(ISD::VECREDUCE_STRICT_FADD, dl, VT, Op1, Op2);
>      break;
>    case Intrinsic::experimental_vector_reduce_fmul:
> -    if (FMF.unsafeAlgebra())
> +    if (FMF.isFast())
>        Res = DAG.getNode(ISD::VECREDUCE_FMUL, dl, VT, Op2);
>      else
>        Res = DAG.getNode(ISD::VECREDUCE_STRICT_FMUL, dl, VT, Op1, Op2);
>
> Modified: llvm/trunk/lib/IR/AsmWriter.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/AsmWriter.cpp?rev=317488&r1=317487&r2=317488&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/IR/AsmWriter.cpp (original)
> +++ llvm/trunk/lib/IR/AsmWriter.cpp Mon Nov  6 08:27:15 2017
> @@ -1108,10 +1108,12 @@ static void writeAtomicRMWOperation(raw_
>
>  static void WriteOptimizationInfo(raw_ostream &Out, const User *U) {
>    if (const FPMathOperator *FPO = dyn_cast<const FPMathOperator>(U)) {
> -    // Unsafe algebra implies all the others, no need to write them all
> out
> -    if (FPO->hasUnsafeAlgebra())
> +    // 'Fast' is an abbreviation for all fast-math-flags.
> +    if (FPO->isFast())
>        Out << " fast";
>      else {
> +      if (FPO->hasAllowReassoc())
> +        Out << " reassoc";
>        if (FPO->hasNoNaNs())
>          Out << " nnan";
>        if (FPO->hasNoInfs())
> @@ -1122,6 +1124,8 @@ static void WriteOptimizationInfo(raw_os
>          Out << " arcp";
>        if (FPO->hasAllowContract())
>          Out << " contract";
> +      if (FPO->hasApproxFunc())
> +        Out << " afn";
>      }
>    }
>
>
> Modified: llvm/trunk/lib/IR/Instruction.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Instruction.cpp?rev=317488&r1=317487&r2=317488&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/IR/Instruction.cpp (original)
> +++ llvm/trunk/lib/IR/Instruction.cpp Mon Nov  6 08:27:15 2017
> @@ -146,9 +146,14 @@ bool Instruction::isExact() const {
>    return cast<PossiblyExactOperator>(this)->isExact();
>  }
>
> -void Instruction::setHasUnsafeAlgebra(bool B) {
> +void Instruction::setFast(bool B) {
>    assert(isa<FPMathOperator>(this) && "setting fast-math flag on invalid
> op");
> -  cast<FPMathOperator>(this)->setHasUnsafeAlgebra(B);
> +  cast<FPMathOperator>(this)->setFast(B);
> +}
> +
> +void Instruction::setHasAllowReassoc(bool B) {
> +  assert(isa<FPMathOperator>(this) && "setting fast-math flag on invalid
> op");
> +  cast<FPMathOperator>(this)->setHasAllowReassoc(B);
>  }
>
>  void Instruction::setHasNoNaNs(bool B) {
> @@ -171,6 +176,11 @@ void Instruction::setHasAllowReciprocal(
>    cast<FPMathOperator>(this)->setHasAllowReciprocal(B);
>  }
>
> +void Instruction::setHasApproxFunc(bool B) {
> +  assert(isa<FPMathOperator>(this) && "setting fast-math flag on invalid
> op");
> +  cast<FPMathOperator>(this)->setHasApproxFunc(B);
> +}
> +
>  void Instruction::setFastMathFlags(FastMathFlags FMF) {
>    assert(isa<FPMathOperator>(this) && "setting fast-math flag on invalid
> op");
>    cast<FPMathOperator>(this)->setFastMathFlags(FMF);
> @@ -181,9 +191,14 @@ void Instruction::copyFastMathFlags(Fast
>    cast<FPMathOperator>(this)->copyFastMathFlags(FMF);
>  }
>
> -bool Instruction::hasUnsafeAlgebra() const {
> +bool Instruction::isFast() const {
>    assert(isa<FPMathOperator>(this) && "getting fast-math flag on invalid
> op");
> -  return cast<FPMathOperator>(this)->hasUnsafeAlgebra();
> +  return cast<FPMathOperator>(this)->isFast();
> +}
> +
> +bool Instruction::hasAllowReassoc() const {
> +  assert(isa<FPMathOperator>(this) && "getting fast-math flag on invalid
> op");
> +  return cast<FPMathOperator>(this)->hasAllowReassoc();
>  }
>
>  bool Instruction::hasNoNaNs() const {
> @@ -211,6 +226,11 @@ bool Instruction::hasAllowContract() con
>    return cast<FPMathOperator>(this)->hasAllowContract();
>  }
>
> +bool Instruction::hasApproxFunc() const {
> +  assert(isa<FPMathOperator>(this) && "getting fast-math flag on invalid
> op");
> +  return cast<FPMathOperator>(this)->hasApproxFunc();
> +}
> +
>  FastMathFlags Instruction::getFastMathFlags() const {
>    assert(isa<FPMathOperator>(this) && "getting fast-math flag on invalid
> op");
>    return cast<FPMathOperator>(this)->getFastMathFlags();
> @@ -579,7 +599,7 @@ bool Instruction::isAssociative() const
>    switch (Opcode) {
>    case FMul:
>    case FAdd:
> -    return cast<FPMathOperator>(this)->hasUnsafeAlgebra();
> +    return cast<FPMathOperator>(this)->isFast();
>    default:
>      return false;
>    }
>
> Modified: llvm/trunk/lib/Target/AMDGPU/AMDGPUCodeGenPrepare.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/AMDGPUCodeGenPrepare.cpp?rev=317488&r1=317487&r2=317488&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/AMDGPU/AMDGPUCodeGenPrepare.cpp (original)
> +++ llvm/trunk/lib/Target/AMDGPU/AMDGPUCodeGenPrepare.cpp Mon Nov  6
> 08:27:15 2017
> @@ -400,7 +400,7 @@ bool AMDGPUCodeGenPrepare::visitFDiv(Bin
>      return false;
>
>    FastMathFlags FMF = FPOp->getFastMathFlags();
> -  bool UnsafeDiv = HasUnsafeFPMath || FMF.unsafeAlgebra() ||
> +  bool UnsafeDiv = HasUnsafeFPMath || FMF.isFast() ||
>                                        FMF.allowReciprocal();
>
>    // With UnsafeDiv node will be optimized to just rcp and mul.
>
> Modified: llvm/trunk/lib/Target/AMDGPU/AMDGPULibCalls.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/AMDGPULibCalls.cpp?rev=317488&r1=317487&r2=317488&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/AMDGPU/AMDGPULibCalls.cpp (original)
> +++ llvm/trunk/lib/Target/AMDGPU/AMDGPULibCalls.cpp Mon Nov  6 08:27:15
> 2017
> @@ -487,7 +487,7 @@ bool AMDGPULibCalls::parseFunctionName(c
>
>  bool AMDGPULibCalls::isUnsafeMath(const CallInst *CI) const {
>    if (auto Op = dyn_cast<FPMathOperator>(CI))
> -    if (Op->hasUnsafeAlgebra())
> +    if (Op->isFast())
>        return true;
>    const Function *F = CI->getParent()->getParent();
>    Attribute Attr = F->getFnAttribute("unsafe-fp-math");
>
> Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineAddSub.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineAddSub.cpp?rev=317488&r1=317487&r2=317488&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Transforms/InstCombine/InstCombineAddSub.cpp (original)
> +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineAddSub.cpp Mon Nov  6
> 08:27:15 2017
> @@ -482,7 +482,7 @@ Value *FAddCombine::performFactorization
>      return nullptr;
>
>    FastMathFlags Flags;
> -  Flags.setUnsafeAlgebra();
> +  Flags.setFast();
>    if (I0) Flags &= I->getFastMathFlags();
>    if (I1) Flags &= I->getFastMathFlags();
>
> @@ -511,7 +511,7 @@ Value *FAddCombine::performFactorization
>  }
>
>  Value *FAddCombine::simplify(Instruction *I) {
> -  assert(I->hasUnsafeAlgebra() && "Should be in unsafe mode");
> +  assert(I->isFast() && "Expected 'fast' instruction");
>
>    // Currently we are not able to handle vector type.
>    if (I->getType()->isVectorTy())
> @@ -1386,7 +1386,7 @@ Instruction *InstCombiner::visitFAdd(Bin
>    if (Value *V = SimplifySelectsFeedingBinaryOp(I, LHS, RHS))
>      return replaceInstUsesWith(I, V);
>
> -  if (I.hasUnsafeAlgebra()) {
> +  if (I.isFast()) {
>      if (Value *V = FAddCombine(Builder).simplify(&I))
>        return replaceInstUsesWith(I, V);
>    }
> @@ -1736,7 +1736,7 @@ Instruction *InstCombiner::visitFSub(Bin
>    if (Value *V = SimplifySelectsFeedingBinaryOp(I, Op0, Op1))
>      return replaceInstUsesWith(I, V);
>
> -  if (I.hasUnsafeAlgebra()) {
> +  if (I.isFast()) {
>      if (Value *V = FAddCombine(Builder).simplify(&I))
>        return replaceInstUsesWith(I, V);
>    }
>
> Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp?rev=317488&r1=317487&r2=317488&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp (original)
> +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp Mon Nov  6
> 08:27:15 2017
> @@ -2017,7 +2017,7 @@ Instruction *InstCombiner::visitCallInst
>    }
>    case Intrinsic::fmuladd: {
>      // Canonicalize fast fmuladd to the separate fmul + fadd.
> -    if (II->hasUnsafeAlgebra()) {
> +    if (II->isFast()) {
>        BuilderTy::FastMathFlagGuard Guard(Builder);
>        Builder.setFastMathFlags(II->getFastMathFlags());
>        Value *Mul = Builder.CreateFMul(II->getArgOperand(0),
>
> Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp?rev=317488&r1=317487&r2=317488&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
> (original)
> +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp Mon
> Nov  6 08:27:15 2017
> @@ -487,7 +487,7 @@ static void detectLog2OfHalf(Value *&Op,
>    IntrinsicInst *II = dyn_cast<IntrinsicInst>(Op);
>    if (!II)
>      return;
> -  if (II->getIntrinsicID() != Intrinsic::log2 || !II->hasUnsafeAlgebra())
> +  if (II->getIntrinsicID() != Intrinsic::log2 || !II->isFast())
>      return;
>    Log2 = II;
>
> @@ -498,7 +498,8 @@ static void detectLog2OfHalf(Value *&Op,
>    Instruction *I = dyn_cast<Instruction>(OpLog2Of);
>    if (!I)
>      return;
> -  if (I->getOpcode() != Instruction::FMul || !I->hasUnsafeAlgebra())
> +
> +  if (I->getOpcode() != Instruction::FMul || !I->isFast())
>      return;
>
>    if (match(I->getOperand(0), m_SpecificFP(0.5)))
> @@ -601,7 +602,7 @@ Value *InstCombiner::foldFMulConst(Instr
>    }
>
>    if (R) {
> -    R->setHasUnsafeAlgebra(true);
> +    R->setFast(true);
>      InsertNewInstWith(R, *InsertBefore);
>    }
>
> @@ -622,7 +623,7 @@ Instruction *InstCombiner::visitFMul(Bin
>                                    SQ.getWithInstruction(&I)))
>      return replaceInstUsesWith(I, V);
>
> -  bool AllowReassociate = I.hasUnsafeAlgebra();
> +  bool AllowReassociate = I.isFast();
>
>    // Simplify mul instructions with a constant RHS.
>    if (isa<Constant>(Op1)) {
> @@ -1341,7 +1342,7 @@ Instruction *InstCombiner::visitFDiv(Bin
>        if (Instruction *R = FoldOpIntoSelect(I, SI))
>          return R;
>
> -  bool AllowReassociate = I.hasUnsafeAlgebra();
> +  bool AllowReassociate = I.isFast();
>    bool AllowReciprocal = I.hasAllowReciprocal();
>
>    if (Constant *Op1C = dyn_cast<Constant>(Op1)) {
>
> Modified: llvm/trunk/lib/Transforms/Scalar/Reassociate.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/Reassociate.cpp?rev=317488&r1=317487&r2=317488&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Scalar/Reassociate.cpp (original)
> +++ llvm/trunk/lib/Transforms/Scalar/Reassociate.cpp Mon Nov  6 08:27:15
> 2017
> @@ -145,8 +145,7 @@ XorOpnd::XorOpnd(Value *V) {
>  static BinaryOperator *isReassociableOp(Value *V, unsigned Opcode) {
>    if (V->hasOneUse() && isa<Instruction>(V) &&
>        cast<Instruction>(V)->getOpcode() == Opcode &&
> -      (!isa<FPMathOperator>(V) ||
> -       cast<Instruction>(V)->hasUnsafeAlgebra()))
> +      (!isa<FPMathOperator>(V) || cast<Instruction>(V)->isFast()))
>      return cast<BinaryOperator>(V);
>    return nullptr;
>  }
> @@ -156,8 +155,7 @@ static BinaryOperator *isReassociableOp(
>    if (V->hasOneUse() && isa<Instruction>(V) &&
>        (cast<Instruction>(V)->getOpcode() == Opcode1 ||
>         cast<Instruction>(V)->getOpcode() == Opcode2) &&
> -      (!isa<FPMathOperator>(V) ||
> -       cast<Instruction>(V)->hasUnsafeAlgebra()))
> +      (!isa<FPMathOperator>(V) || cast<Instruction>(V)->isFast()))
>      return cast<BinaryOperator>(V);
>    return nullptr;
>  }
> @@ -565,7 +563,7 @@ static bool LinearizeExprTree(BinaryOper
>        assert((!isa<Instruction>(Op) ||
>                cast<Instruction>(Op)->getOpcode() != Opcode
>                || (isa<FPMathOperator>(Op) &&
> -                  !cast<Instruction>(Op)->hasUnsafeAlgebra())) &&
> +                  !cast<Instruction>(Op)->isFast())) &&
>               "Should have been handled above!");
>        assert(Op->hasOneUse() && "Has uses outside the expression tree!");
>
> @@ -2017,8 +2015,8 @@ void ReassociatePass::OptimizeInst(Instr
>    if (I->isCommutative())
>      canonicalizeOperands(I);
>
> -  // Don't optimize floating point instructions that don't have unsafe
> algebra.
> -  if (I->getType()->isFPOrFPVectorTy() && !I->hasUnsafeAlgebra())
> +  // Don't optimize floating-point instructions unless they are 'fast'.
> +  if (I->getType()->isFPOrFPVectorTy() && !I->isFast())
>      return;
>
>    // Do not reassociate boolean (i1) expressions.  We want to preserve the
>
> Modified: llvm/trunk/lib/Transforms/Utils/LoopUtils.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LoopUtils.cpp?rev=317488&r1=317487&r2=317488&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Utils/LoopUtils.cpp (original)
> +++ llvm/trunk/lib/Transforms/Utils/LoopUtils.cpp Mon Nov  6 08:27:15 2017
> @@ -432,7 +432,7 @@ RecurrenceDescriptor::isRecurrenceInstr(
>                                          InstDesc &Prev, bool
> HasFunNoNaNAttr) {
>    bool FP = I->getType()->isFloatingPointTy();
>    Instruction *UAI = Prev.getUnsafeAlgebraInst();
> -  if (!UAI && FP && !I->hasUnsafeAlgebra())
> +  if (!UAI && FP && !I->isFast())
>      UAI = I; // Found an unsafe (unvectorizable) algebra instruction.
>
>    switch (I->getOpcode()) {
> @@ -660,11 +660,11 @@ Value *RecurrenceDescriptor::createMinMa
>      break;
>    }
>
> -  // We only match FP sequences with unsafe algebra, so we can
> unconditionally
> +  // We only match FP sequences that are 'fast', so we can unconditionally
>    // set it on any generated instructions.
>    IRBuilder<>::FastMathFlagGuard FMFG(Builder);
>    FastMathFlags FMF;
> -  FMF.setUnsafeAlgebra();
> +  FMF.setFast();
>    Builder.setFastMathFlags(FMF);
>
>    Value *Cmp;
> @@ -768,7 +768,7 @@ Value *InductionDescriptor::transform(IR
>
>      // Floating point operations had to be 'fast' to enable the induction.
>      FastMathFlags Flags;
> -    Flags.setUnsafeAlgebra();
> +    Flags.setFast();
>
>      Value *MulExp = B.CreateFMul(StepValue, Index);
>      if (isa<Instruction>(MulExp))
> @@ -1338,7 +1338,7 @@ Optional<unsigned> llvm::getLoopEstimate
>  static Value *addFastMathFlag(Value *V) {
>    if (isa<FPMathOperator>(V)) {
>      FastMathFlags Flags;
> -    Flags.setUnsafeAlgebra();
> +    Flags.setFast();
>      cast<Instruction>(V)->setFastMathFlags(Flags);
>    }
>    return V;
> @@ -1401,7 +1401,7 @@ Value *llvm::createSimpleTargetReduction
>    RD::MinMaxRecurrenceKind MinMaxKind = RD::MRK_Invalid;
>    // TODO: Support creating ordered reductions.
>    FastMathFlags FMFUnsafe;
> -  FMFUnsafe.setUnsafeAlgebra();
> +  FMFUnsafe.setFast();
>
>    switch (Opcode) {
>    case Instruction::Add:
>
> Modified: llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp?rev=317488&r1=317487&r2=317488&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp (original)
> +++ llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp Mon Nov  6
> 08:27:15 2017
> @@ -1111,7 +1111,7 @@ Value *LibCallSimplifier::optimizePow(Ca
>    // Example: x = 1000, y = 0.001.
>    // pow(exp(x), y) = pow(inf, 0.001) = inf, whereas exp(x*y) = exp(1).
>    auto *OpC = dyn_cast<CallInst>(Op1);
> -  if (OpC && OpC->hasUnsafeAlgebra() && CI->hasUnsafeAlgebra()) {
> +  if (OpC && OpC->isFast() && CI->isFast()) {
>      LibFunc Func;
>      Function *OpCCallee = OpC->getCalledFunction();
>      if (OpCCallee && TLI->getLibFunc(OpCCallee->getName(), Func) &&
> @@ -1136,7 +1136,7 @@ Value *LibCallSimplifier::optimizePow(Ca
>                        LibFunc_sqrtl)) {
>      // If -ffast-math:
>      // pow(x, -0.5) -> 1.0 / sqrt(x)
> -    if (CI->hasUnsafeAlgebra()) {
> +    if (CI->isFast()) {
>        IRBuilder<>::FastMathFlagGuard Guard(B);
>        B.setFastMathFlags(CI->getFastMathFlags());
>
> @@ -1157,7 +1157,7 @@ Value *LibCallSimplifier::optimizePow(Ca
>                        LibFunc_sqrtl)) {
>
>      // In -ffast-math, pow(x, 0.5) -> sqrt(x).
> -    if (CI->hasUnsafeAlgebra()) {
> +    if (CI->isFast()) {
>        IRBuilder<>::FastMathFlagGuard Guard(B);
>        B.setFastMathFlags(CI->getFastMathFlags());
>
> @@ -1196,7 +1196,7 @@ Value *LibCallSimplifier::optimizePow(Ca
>      return B.CreateFDiv(ConstantFP::get(CI->getType(), 1.0), Op1,
> "powrecip");
>
>    // In -ffast-math, generate repeated fmul instead of generating pow(x,
> n).
> -  if (CI->hasUnsafeAlgebra()) {
> +  if (CI->isFast()) {
>      APFloat V = abs(Op2C->getValueAPF());
>      // We limit to a max of 7 fmul(s). Thus max exponent is 32.
>      // This transformation applies to integer exponents only.
> @@ -1284,9 +1284,9 @@ Value *LibCallSimplifier::optimizeFMinFM
>
>    IRBuilder<>::FastMathFlagGuard Guard(B);
>    FastMathFlags FMF;
> -  if (CI->hasUnsafeAlgebra()) {
> -    // Unsafe algebra sets all fast-math-flags to true.
> -    FMF.setUnsafeAlgebra();
> +  if (CI->isFast()) {
> +    // If the call is 'fast', then anything we create here will also be
> 'fast'.
> +    FMF.setFast();
>    } else {
>      // At a minimum, no-nans-fp-math must be true.
>      if (!CI->hasNoNaNs())
> @@ -1317,13 +1317,13 @@ Value *LibCallSimplifier::optimizeLog(Ca
>    if (UnsafeFPShrink && hasFloatVersion(Name))
>      Ret = optimizeUnaryDoubleFP(CI, B, true);
>
> -  if (!CI->hasUnsafeAlgebra())
> +  if (!CI->isFast())
>      return Ret;
>    Value *Op1 = CI->getArgOperand(0);
>    auto *OpC = dyn_cast<CallInst>(Op1);
>
> -  // The earlier call must also be unsafe in order to do these transforms.
> -  if (!OpC || !OpC->hasUnsafeAlgebra())
> +  // The earlier call must also be 'fast' in order to do these transforms.
> +  if (!OpC || !OpC->isFast())
>      return Ret;
>
>    // log(pow(x,y)) -> y*log(x)
> @@ -1333,7 +1333,7 @@ Value *LibCallSimplifier::optimizeLog(Ca
>
>    IRBuilder<>::FastMathFlagGuard Guard(B);
>    FastMathFlags FMF;
> -  FMF.setUnsafeAlgebra();
> +  FMF.setFast();
>    B.setFastMathFlags(FMF);
>
>    LibFunc Func;
> @@ -1365,11 +1365,11 @@ Value *LibCallSimplifier::optimizeSqrt(C
>                                    Callee->getIntrinsicID() ==
> Intrinsic::sqrt))
>      Ret = optimizeUnaryDoubleFP(CI, B, true);
>
> -  if (!CI->hasUnsafeAlgebra())
> +  if (!CI->isFast())
>      return Ret;
>
>    Instruction *I = dyn_cast<Instruction>(CI->getArgOperand(0));
> -  if (!I || I->getOpcode() != Instruction::FMul || !I->hasUnsafeAlgebra())
> +  if (!I || I->getOpcode() != Instruction::FMul || !I->isFast())
>      return Ret;
>
>    // We're looking for a repeated factor in a multiplication tree,
> @@ -1391,8 +1391,7 @@ Value *LibCallSimplifier::optimizeSqrt(C
>      Value *OtherMul0, *OtherMul1;
>      if (match(Op0, m_FMul(m_Value(OtherMul0), m_Value(OtherMul1)))) {
>        // Pattern: sqrt((x * y) * z)
> -      if (OtherMul0 == OtherMul1 &&
> -          cast<Instruction>(Op0)->hasUnsafeAlgebra()) {
> +      if (OtherMul0 == OtherMul1 && cast<Instruction>(Op0)->isFast()) {
>          // Matched: sqrt((x * x) * z)
>          RepeatOp = OtherMul0;
>          OtherOp = Op1;
> @@ -1437,8 +1436,8 @@ Value *LibCallSimplifier::optimizeTan(Ca
>    if (!OpC)
>      return Ret;
>
> -  // Both calls must allow unsafe optimizations in order to remove them.
> -  if (!CI->hasUnsafeAlgebra() || !OpC->hasUnsafeAlgebra())
> +  // Both calls must be 'fast' in order to remove them.
> +  if (!CI->isFast() || !OpC->isFast())
>      return Ret;
>
>    // tan(atan(x)) -> x
> @@ -2167,10 +2166,10 @@ Value *LibCallSimplifier::optimizeCall(C
>
>    // Command-line parameter overrides instruction attribute.
>    // This can't be moved to optimizeFloatingPointLibCall() because it may
> be
> -  // used by the intrinsic optimizations.
> +  // used by the intrinsic optimizations.
>    if (EnableUnsafeFPShrink.getNumOccurrences() > 0)
>      UnsafeFPShrink = EnableUnsafeFPShrink;
> -  else if (isa<FPMathOperator>(CI) && CI->hasUnsafeAlgebra())
> +  else if (isa<FPMathOperator>(CI) && CI->isFast())
>      UnsafeFPShrink = true;
>
>    // First, check for intrinsics.
>
> Modified: llvm/trunk/lib/Transforms/Vectorize/LoopVectorize.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Vectorize/LoopVectorize.cpp?rev=317488&r1=317487&r2=317488&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Vectorize/LoopVectorize.cpp (original)
> +++ llvm/trunk/lib/Transforms/Vectorize/LoopVectorize.cpp Mon Nov  6
> 08:27:15 2017
> @@ -385,7 +385,7 @@ static unsigned getReciprocalPredBlockPr
>  static Value *addFastMathFlag(Value *V) {
>    if (isa<FPMathOperator>(V)) {
>      FastMathFlags Flags;
> -    Flags.setUnsafeAlgebra();
> +    Flags.setFast();
>      cast<Instruction>(V)->setFastMathFlags(Flags);
>    }
>    return V;
> @@ -2720,7 +2720,7 @@ Value *InnerLoopVectorizer::getStepVecto
>
>    // Floating point operations had to be 'fast' to enable the induction.
>    FastMathFlags Flags;
> -  Flags.setUnsafeAlgebra();
> +  Flags.setFast();
>
>    Value *MulOp = Builder.CreateFMul(Cv, Step);
>    if (isa<Instruction>(MulOp))
> @@ -5396,7 +5396,7 @@ bool LoopVectorizationLegality::canVecto
>          // operations, shuffles, or casts, as they don't change precision
> or
>          // semantics.
>        } else if (I.getType()->isFloatingPointTy() && (CI ||
> I.isBinaryOp()) &&
> -                 !I.hasUnsafeAlgebra()) {
> +                 !I.isFast()) {
>          DEBUG(dbgs() << "LV: Found FP op with unsafe algebra.\n");
>          Hints->setPotentiallyUnsafe();
>        }
>
> Modified: llvm/trunk/lib/Transforms/Vectorize/SLPVectorizer.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Vectorize/SLPVectorizer.cpp?rev=317488&r1=317487&r2=317488&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Vectorize/SLPVectorizer.cpp (original)
> +++ llvm/trunk/lib/Transforms/Vectorize/SLPVectorizer.cpp Mon Nov  6
> 08:27:15 2017
> @@ -4880,7 +4880,7 @@ class HorizontalReduction {
>        case RK_Min:
>        case RK_Max:
>          return Opcode == Instruction::ICmp ||
> -               cast<Instruction>(I->getOperand(0))->hasUnsafeAlgebra();
> +               cast<Instruction>(I->getOperand(0))->isFast();
>        case RK_UMin:
>        case RK_UMax:
>          assert(Opcode == Instruction::ICmp &&
> @@ -5232,7 +5232,7 @@ public:
>      Value *VectorizedTree = nullptr;
>      IRBuilder<> Builder(ReductionRoot);
>      FastMathFlags Unsafe;
> -    Unsafe.setUnsafeAlgebra();
> +    Unsafe.setFast();
>      Builder.setFastMathFlags(Unsafe);
>      unsigned i = 0;
>
>
> Modified: llvm/trunk/test/Assembler/fast-math-flags.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/fast-math-flags.ll?rev=317488&r1=317487&r2=317488&view=diff
>
> ==============================================================================
> --- llvm/trunk/test/Assembler/fast-math-flags.ll (original)
> +++ llvm/trunk/test/Assembler/fast-math-flags.ll Mon Nov  6 08:27:15 2017
> @@ -7,6 +7,8 @@
>  @vec    = external global <3 x float>
>  @arr    = external global [3 x float]
>
> +declare float @foo(float)
> +
>  define float @none(float %x, float %y) {
>  entry:
>  ; CHECK:  %vec = load  <3 x float>,  <3 x float>* @vec
> @@ -86,6 +88,28 @@ entry:
>    ret float %c
>  }
>
> +; CHECK: @reassoc(
> +define float @reassoc(float %x, float %y) {
> +; CHECK: %a = fsub reassoc float %x, %y
> +  %a = fsub reassoc float %x, %y
> +; CHECK: %b = fmul reassoc float %x, %y
> +  %b = fmul reassoc float %x, %y
> +; CHECK: %c = call reassoc float @foo(float %b)
> +  %c = call reassoc float @foo(float %b)
> +  ret float %c
> +}
> +
> +; CHECK: @afn(
> +define float @afn(float %x, float %y) {
> +; CHECK: %a = fdiv afn float %x, %y
> +  %a = fdiv afn float %x, %y
> +; CHECK: %b = frem afn float %x, %y
> +  %b = frem afn float %x, %y
> +; CHECK: %c = call afn float @foo(float %b)
> +  %c = call afn float @foo(float %b)
> +  ret float %c
> +}
> +
>  ; CHECK: no_nan_inf
>  define float @no_nan_inf(float %x, float %y) {
>  entry:
> @@ -130,10 +154,10 @@ entry:
>  ; CHECK:  %arr    = load [3 x float], [3 x float]* @arr
>    %arr    = load [3 x float], [3 x float]* @arr
>
> -; CHECK:  %a = fadd nnan ninf float %x, %y
> -  %a = fadd ninf nnan float %x, %y
> -; CHECK:  %a_vec = fadd nnan <3 x float> %vec, %vec
> -  %a_vec = fadd nnan <3 x float> %vec, %vec
> +; CHECK:  %a = fadd nnan ninf afn float %x, %y
> +  %a = fadd ninf nnan afn float %x, %y
> +; CHECK:  %a_vec = fadd reassoc nnan <3 x float> %vec, %vec
> +  %a_vec = fadd reassoc nnan <3 x float> %vec, %vec
>  ; CHECK:  %b = fsub fast float %x, %y
>    %b = fsub nnan nsz fast float %x, %y
>  ; CHECK:  %b_vec = fsub nnan <3 x float> %vec, %vec
>
> Modified: llvm/trunk/test/Bitcode/compatibility-3.6.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bitcode/compatibility-3.6.ll?rev=317488&r1=317487&r2=317488&view=diff
>
> ==============================================================================
> --- llvm/trunk/test/Bitcode/compatibility-3.6.ll (original)
> +++ llvm/trunk/test/Bitcode/compatibility-3.6.ll Mon Nov  6 08:27:15 2017
> @@ -612,7 +612,9 @@ define void @fastmathflags(float %op1, f
>    %f.arcp = fadd arcp float %op1, %op2
>    ; CHECK: %f.arcp = fadd arcp float %op1, %op2
>    %f.fast = fadd fast float %op1, %op2
> -  ; CHECK: %f.fast = fadd fast float %op1, %op2
> +  ; 'fast' used to be its own bit, but this changed in Oct 2017.
> +  ; The binary test file does not have the newer 'contract' and 'afn'
> bits set, so this is not fully 'fast'.
> +  ; CHECK: %f.fast = fadd reassoc nnan ninf nsz arcp float %op1, %op2
>    ret void
>  }
>
>
> Modified: llvm/trunk/test/Bitcode/compatibility-3.7.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bitcode/compatibility-3.7.ll?rev=317488&r1=317487&r2=317488&view=diff
>
> ==============================================================================
> --- llvm/trunk/test/Bitcode/compatibility-3.7.ll (original)
> +++ llvm/trunk/test/Bitcode/compatibility-3.7.ll Mon Nov  6 08:27:15 2017
> @@ -656,7 +656,9 @@ define void @fastmathflags(float %op1, f
>    %f.arcp = fadd arcp float %op1, %op2
>    ; CHECK: %f.arcp = fadd arcp float %op1, %op2
>    %f.fast = fadd fast float %op1, %op2
> -  ; CHECK: %f.fast = fadd fast float %op1, %op2
> +  ; 'fast' used to be its own bit, but this changed in Oct 2017.
> +  ; The binary test file does not have the newer 'contract' and 'afn'
> bits set, so this is not fully 'fast'.
> +  ; CHECK: %f.fast = fadd reassoc nnan ninf nsz arcp float %op1, %op2
>    ret void
>  }
>
>
> Modified: llvm/trunk/test/Bitcode/compatibility-3.8.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bitcode/compatibility-3.8.ll?rev=317488&r1=317487&r2=317488&view=diff
>
> ==============================================================================
> --- llvm/trunk/test/Bitcode/compatibility-3.8.ll (original)
> +++ llvm/trunk/test/Bitcode/compatibility-3.8.ll Mon Nov  6 08:27:15 2017
> @@ -687,7 +687,9 @@ define void @fastmathflags(float %op1, f
>    %f.arcp = fadd arcp float %op1, %op2
>    ; CHECK: %f.arcp = fadd arcp float %op1, %op2
>    %f.fast = fadd fast float %op1, %op2
> -  ; CHECK: %f.fast = fadd fast float %op1, %op2
> +  ; 'fast' used to be its own bit, but this changed in Oct 2017.
> +  ; The binary test file does not have the newer 'contract' and 'afn'
> bits set, so this is not fully 'fast'.
> +  ; CHECK: %f.fast = fadd reassoc nnan ninf nsz arcp float %op1, %op2
>    ret void
>  }
>
> @@ -700,7 +702,9 @@ declare <4 x double> @fmf3()
>  ; CHECK-LABEL: fastMathFlagsForCalls(
>  define void @fastMathFlagsForCalls(float %f, double %d1, <4 x double>
> %d2) {
>    %call.fast = call fast float @fmf1()
> -  ; CHECK: %call.fast = call fast float @fmf1()
> +  ; 'fast' used to be its own bit, but this changed in Oct 2017.
> +  ; The binary test file does not have the newer 'contract' and 'aml'
> bits set, so this is not fully 'fast'.
> +  ; CHECK: %call.fast = call reassoc nnan ninf nsz arcp float @fmf1()
>
>    ; Throw in some other attributes to make sure those stay in the right
> places.
>
>
> Modified: llvm/trunk/test/Bitcode/compatibility-3.9.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bitcode/compatibility-3.9.ll?rev=317488&r1=317487&r2=317488&view=diff
>
> ==============================================================================
> --- llvm/trunk/test/Bitcode/compatibility-3.9.ll (original)
> +++ llvm/trunk/test/Bitcode/compatibility-3.9.ll Mon Nov  6 08:27:15 2017
> @@ -758,7 +758,9 @@ define void @fastmathflags(float %op1, f
>    %f.arcp = fadd arcp float %op1, %op2
>    ; CHECK: %f.arcp = fadd arcp float %op1, %op2
>    %f.fast = fadd fast float %op1, %op2
> -  ; CHECK: %f.fast = fadd fast float %op1, %op2
> +  ; 'fast' used to be its own bit, but this changed in Oct 2017.
> +  ; The binary test file does not have the newer 'contract' and 'afn'
> bits set, so this is not fully 'fast'.
> +  ; CHECK: %f.fast = fadd reassoc nnan ninf nsz arcp float %op1, %op2
>    ret void
>  }
>
> @@ -771,7 +773,9 @@ declare <4 x double> @fmf3()
>  ; CHECK-LABEL: fastMathFlagsForCalls(
>  define void @fastMathFlagsForCalls(float %f, double %d1, <4 x double>
> %d2) {
>    %call.fast = call fast float @fmf1()
> -  ; CHECK: %call.fast = call fast float @fmf1()
> +  ; 'fast' used to be its own bit, but this changed in Oct 2017.
> +  ; The binary test file does not have the newer 'contract' and 'afn'
> bits set, so this is not fully 'fast'.
> +  ; CHECK: %call.fast = call reassoc nnan ninf nsz arcp float @fmf1()
>
>    ; Throw in some other attributes to make sure those stay in the right
> places.
>
>
> Modified: llvm/trunk/test/Bitcode/compatibility-4.0.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bitcode/compatibility-4.0.ll?rev=317488&r1=317487&r2=317488&view=diff
>
> ==============================================================================
> --- llvm/trunk/test/Bitcode/compatibility-4.0.ll (original)
> +++ llvm/trunk/test/Bitcode/compatibility-4.0.ll Mon Nov  6 08:27:15 2017
> @@ -757,8 +757,10 @@ define void @fastmathflags(float %op1, f
>    ; CHECK: %f.nsz = fadd nsz float %op1, %op2
>    %f.arcp = fadd arcp float %op1, %op2
>    ; CHECK: %f.arcp = fadd arcp float %op1, %op2
> +  ; 'fast' used to be its own bit, but this changed in Oct 2017.
> +  ; The binary test file does not have the newer 'contract' and 'afn'
> bits set, so this is not fully 'fast'.
>    %f.fast = fadd fast float %op1, %op2
> -  ; CHECK: %f.fast = fadd fast float %op1, %op2
> +  ; CHECK: %f.fast = fadd reassoc nnan ninf nsz arcp float %op1, %op2
>    ret void
>  }
>
> @@ -771,7 +773,9 @@ declare <4 x double> @fmf3()
>  ; CHECK-LABEL: fastMathFlagsForCalls(
>  define void @fastMathFlagsForCalls(float %f, double %d1, <4 x double>
> %d2) {
>    %call.fast = call fast float @fmf1()
> -  ; CHECK: %call.fast = call fast float @fmf1()
> +  ; 'fast' used to be its own bit, but this changed in Oct 2017.
> +  ; The binary test file does not have the newer 'contract' and 'afn'
> bits set, so this is not fully 'fast'.
> +  ; CHECK: %call.fast = call reassoc nnan ninf nsz arcp float @fmf1()
>
>    ; Throw in some other attributes to make sure those stay in the right
> places.
>
>
> Modified: llvm/trunk/test/Bitcode/compatibility-5.0.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bitcode/compatibility-5.0.ll?rev=317488&r1=317487&r2=317488&view=diff
>
> ==============================================================================
> --- llvm/trunk/test/Bitcode/compatibility-5.0.ll (original)
> +++ llvm/trunk/test/Bitcode/compatibility-5.0.ll Mon Nov  6 08:27:15 2017
> @@ -765,7 +765,9 @@ define void @fastmathflags(float %op1, f
>    %f.contract = fadd contract float %op1, %op2
>    ; CHECK: %f.contract = fadd contract float %op1, %op2
>    %f.fast = fadd fast float %op1, %op2
> -  ; CHECK: %f.fast = fadd fast float %op1, %op2
> +  ; 'fast' used to be its own bit, but this changed in Oct 2017.
> +  ; The binary test file does not have the newer 'afn' bit set, so this
> is not fully 'fast'.
> +  ; CHECK: %f.fast = fadd reassoc nnan ninf nsz arcp contract float %op1,
> %op2
>    ret void
>  }
>
> @@ -778,7 +780,9 @@ declare <4 x double> @fmf3()
>  ; CHECK-LABEL: fastMathFlagsForCalls(
>  define void @fastMathFlagsForCalls(float %f, double %d1, <4 x double>
> %d2) {
>    %call.fast = call fast float @fmf1()
> -  ; CHECK: %call.fast = call fast float @fmf1()
> +  ; 'fast' used to be its own bit, but this changed in Oct 2017.
> +  ; The binary test file does not have the newer 'afn' bit set, so this
> is not fully 'fast'.
> +  ; CHECK: %call.fast = call reassoc nnan ninf nsz arcp contract float
> @fmf1()
>
>    ; Throw in some other attributes to make sure those stay in the right
> places.
>
>
> Modified: llvm/trunk/test/Bitcode/compatibility.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bitcode/compatibility.ll?rev=317488&r1=317487&r2=317488&view=diff
>
> ==============================================================================
> --- llvm/trunk/test/Bitcode/compatibility.ll (original)
> +++ llvm/trunk/test/Bitcode/compatibility.ll Mon Nov  6 08:27:15 2017
> @@ -775,6 +775,10 @@ define void @fastmathflags(float %op1, f
>    ; CHECK: %f.arcp = fadd arcp float %op1, %op2
>    %f.contract = fadd contract float %op1, %op2
>    ; CHECK: %f.contract = fadd contract float %op1, %op2
> +  %f.afn = fadd afn float %op1, %op2
> +  ; CHECK: %f.afn = fadd afn float %op1, %op2
> +  %f.reassoc = fadd reassoc float %op1, %op2
> +  ; CHECK: %f.reassoc = fadd reassoc float %op1, %op2
>    %f.fast = fadd fast float %op1, %op2
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20171106/102c09c5/attachment-0001.html>


More information about the llvm-commits mailing list