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