-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[LangRef] Clarify the semantics of fast-math flags #89442
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This change clarifies the semantics of the fast-math flags when a transformation enabled by fast-math flags involves more than one instruction. This was discussed at https://discourse.llvm.org/t/rfc-fast-math-optimizations-with-mixed-fast-math-flags/78320
@llvm/pr-subscribers-llvm-ir Author: Andy Kaylor (andykaylor) ChangesThis change clarifies the semantics of the fast-math flags when a This was discussed at https://discourse.llvm.org/t/rfc-fast-math-optimizations-with-mixed-fast-math-flags/78320 Full diff: https://github.com/llvm/llvm-project/pull/89442.diff 1 Files Affected:
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 9592929d79feb4..dcb21330fa8156 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -3656,6 +3656,45 @@ floating-point transformations.
``fast``
This flag implies all of the others.
+When performing a transformation that involves more that one instruction, the
+flags required to enable the transformation must be set on all instructions
+involved in the transformation, and any new instructions created by the
+transformation should have only those flags set which were set on all the
+original instructions that are being transformed.
+
+For example
+
+::
+
+%mul1 = fmul float %x, %y
+%mul2 = fmul fast float %mul1, %z
+
+cannot be transformed to
+
+::
+
+%mul1 = fmul float %x, %z
+%mul2 = fmul fast float %mul1, %y
+
+because the %mul1 instruction does not have the 'reassoc' flag set.
+
+Similarly, if applying reassociation to
+
+::
+
+%mul1 = fmul reassoc float %x, %y
+%mul2 = fmul fast float %mul1, %z
+
+the result must be
+
+::
+
+%mul1 = fmul reassoc float %x, %z
+%mul2 = fmul reassoc float %mul1, %y
+
+because only the reassoc flag is set on both original instructions.
+
+
.. _uselistorder:
Use-list Order Directives
|
transformation should have only those flags set which were set on all the | ||
original instructions that are being transformed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't universally true. In some cases, you can or in the flags. In others you can infer new nnan/ninf. It should be true for reassoc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I suppose you're right that the semantics we've defined for nnan
and ninf
make that true in many cases. This leads to an increasing sense I have that those two flags are fundamentally different from the other fast-math flags. Those two flags provide clear, consistent, and rather strict semantics, whereas the other flags all have a sort of "you're allowed to do something here that you normally couldn't" character.
This also significantly complicates the reasoning involved. For instance
%mul1 = fmul reassoc float %x, %y
%mul2 = fmul fast float %mul1, %z
becomes
%mul1.1 = fmul reassoc nnan float %x, %z
%mul2.1 = fmul reassoc nnan float %mul1, %y
which is already tricky because the possibility of %x=INF, %y=0 prevents me from setting ninf
on %mul2.1 and %x=0. %y=INF prevents me from setting ninf
on %mul1.1
but also
%mul1 = fmul fast float %x, %y
%mul2 = fmul reassoc float %mul1, %z
becomes
%mul1.1 = fmul reassoc float %x, %z
%mul2.1 = fmul reassoc float %mul1, %y
because we don't have enough information to set ninf
or nnan
on either transformed instruction.
In practice, I think this would be difficult to implement any way other than to apply the rule I stated and rely on a later pass to infer nnan
and ninf
where it can. Of course, for the purposes of describing the semantics, it may be best to say something like
any new instructions created by the transformation should have only those flags set which were set on all the original instructions that are being transformed unless additional flags can be strictly deduced from the original IR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you want to add more of a guideline, maybe could say something about how you can infer that. e.g. since nnan/ninf imply something about the inputs in one instruction, it implies something about the value in the other use
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've been putting together an RFC on FMF semantics, but one of the things I note is that there's a definite dichotomy between nnan
/ninf
/nsz
(which have clear value-based semantics) and reassoc
/afn
/arcp
/contract
(which probably have to be rewrite-based semantics). For the rewrite-based semantics flags, it's necessary that the flags be present on all operations in the expression.
I don't have great wording to suggest at the moment (not unless you want a page of text), but maybe it would be better to delineate the flags for which the all-instructions-must-have-the-flags-to-be-rewritten property is true?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have great wording to suggest at the moment (not unless you want a page of text), but maybe it would be better to delineate the flags for which the all-instructions-must-have-the-flags-to-be-rewritten property is true?
I think for the purposes of this change, explicitly listing the flags for which this guidance applies would indeed be best.
This change clarifies the semantics of the fast-math flags when a
transformation enabled by fast-math flags involves more than one
instruction.
This was discussed at https://discourse.llvm.org/t/rfc-fast-math-optimizations-with-mixed-fast-math-flags/78320