<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>