Kaylor, Andrew via llvm-dev
2019-Nov-14 19:39 UTC
[llvm-dev] RFC: token arguments and operand bundles
Hello everyone,
I've just uploaded a patch (https://reviews.llvm.org/D70261) to introduce a
could of new token types to be used with constrained floating point intrinsics
and, optionally, vector predicated intrinsics. These intrinsics may not be of
interest to many of you, but I have a more general question.
I would like some general feedback on the way I am proposing to use token
arguments and operand bundles. I have an incomplete understanding of how these
are intended to be used, and I want to make sure what I have in mind is
consistent with the philosophy behind them.
Currently, the constrained floating point intrinsics require string metadata
arguments to describe the rounding mode and exception semantics. These
"arguments" are really providing information to the optimizer about
what it can and cannot assume when acting on these intrinsics. The rounding mode
argument potentially overrides the default optimizer assumption that the
"to nearest" rounding mode is in use, and the exception behavior
argument overrides the default optimizer assumption that floating point
operations have no side effects. I've never liked the use of strings here,
and the fact that these arguments are not actually inputs to the operation
represented by the intrinsic seems vaguely wrong.
A typical call to a current intrinsic looks like this:
%sum = call double @llvm.experimental.constrained.fadd(double %x,
double %y,
Metadata
"fpround.dynamic",
Metadata
"fpexcept.strict")
The idea I am pursuing in my patch is to replace these metadata arguments with
optional operand bundles, "fpround" and "fpexcept". If the
operand bundles are present, they would mean what the arguments currently mean.
If not, the default assumption is allowed. A typical call to a constrained
intrinsic would look like this:
%sum = call double @llvm.experimental2.constrained.fadd(double %x,
double %y) [
"fpround"(token rmDynamic),
"fpexcept"(token ebStrict) ]
Does that seem like a valid use of tokens and operand bundles? Does it seem
better than the current approach?
Thanks,
Andy
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20191114/9b9910cf/attachment.html>
Jameson Nash via llvm-dev
2019-Nov-14 20:26 UTC
[llvm-dev] RFC: token arguments and operand bundles
>From a front-end perspective, I think it'd be preferable if these eithergot encoded in the function name or were normal enum value arguments. It's a bit awkward to expose things to the user that must be constant or of a special type or in a special metadata slot, since we now need more special support for it. If the optimization passes couldn't identify a constant value for one of the arguments, these seem like they can fallback to assuming the most conservative semantics (of round.dynamic and fpexcept.strict--e.g. don't optimize) without loss of precision or generality. -Jameson On Thu, Nov 14, 2019 at 2:40 PM Kaylor, Andrew via llvm-dev < llvm-dev at lists.llvm.org> wrote:> Hello everyone, > > > > I’ve just uploaded a patch (https://reviews.llvm.org/D70261) to introduce > a could of new token types to be used with constrained floating point > intrinsics and, optionally, vector predicated intrinsics. These intrinsics > may not be of interest to many of you, but I have a more general question. > > > > I would like some general feedback on the way I am proposing to use token > arguments and operand bundles. I have an incomplete understanding of how > these are intended to be used, and I want to make sure what I have in mind > is consistent with the philosophy behind them. > > > > Currently, the constrained floating point intrinsics require string > metadata arguments to describe the rounding mode and exception semantics. > These “arguments” are really providing information to the optimizer about > what it can and cannot assume when acting on these intrinsics. The rounding > mode argument potentially overrides the default optimizer assumption that > the “to nearest” rounding mode is in use, and the exception behavior > argument overrides the default optimizer assumption that floating point > operations have no side effects. I’ve never liked the use of strings here, > and the fact that these arguments are not actually inputs to the operation > represented by the intrinsic seems vaguely wrong. > > > > A typical call to a current intrinsic looks like this: > > > > *%sum = call double @llvm*.experimental.constrained.fadd(double %x, > > double %y, > > Metadata > “fpround.dynamic”, > > Metadata > “fpexcept.strict”) > > > > The idea I am pursuing in my patch is to replace these metadata arguments > with optional operand bundles, “fpround” and “fpexcept”. If the operand > bundles are present, they would mean what the arguments currently mean. If > not, the default assumption is allowed. A typical call to a constrained > intrinsic would look like this: > > > > *%sum = call double @llvm*.experimental2.constrained.fadd(double %x, > > double %y) [ > “fpround”(token rmDynamic), > > > “fpexcept”(token ebStrict) ] > > > > Does that seem like a valid use of tokens and operand bundles? Does it > seem better than the current approach? > > > > Thanks, > > Andy > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20191114/0074ca8b/attachment.html>
Kaylor, Andrew via llvm-dev
2019-Nov-14 20:58 UTC
[llvm-dev] RFC: token arguments and operand bundles
Let me clarify. These aren’t intended to be exposed to the user. The user code
that leads to the generation of these intrinsics will be normal floating point
operations combined with either pragmas (such as “STDC FENV_ACCESS ON”) or
command line options (such as the recently introduced “-fp-model=strict”).
The reason I’ve been avoiding normal constant values is that it provides no
information when you’re reading the IR. For example:
%sum = call double @llvm.experimental.constrained.fadd(double %x, double %y, i32
1, i32 2)
What does that mean? You’d need to consult an external reference to have any
idea.
-Andy
From: Jameson Nash <vtjnash at gmail.com>
Sent: Thursday, November 14, 2019 12:27 PM
To: Kaylor, Andrew <andrew.kaylor at intel.com>
Cc: LLVM Developers Mailing List <llvm-dev at lists.llvm.org>
Subject: Re: [llvm-dev] RFC: token arguments and operand bundles
From a front-end perspective, I think it'd be preferable if these either got
encoded in the function name or were normal enum value arguments. It's a bit
awkward to expose things to the user that must be constant or of a special type
or in a special metadata slot, since we now need more special support for it. If
the optimization passes couldn't identify a constant value for one of the
arguments, these seem like they can fallback to assuming the most conservative
semantics (of round.dynamic and fpexcept.strict--e.g. don't optimize)
without loss of precision or generality.
-Jameson
On Thu, Nov 14, 2019 at 2:40 PM Kaylor, Andrew via llvm-dev <llvm-dev at
lists.llvm.org<mailto:llvm-dev at lists.llvm.org>> wrote:
Hello everyone,
I’ve just uploaded a patch (https://reviews.llvm.org/D70261) to introduce a
could of new token types to be used with constrained floating point intrinsics
and, optionally, vector predicated intrinsics. These intrinsics may not be of
interest to many of you, but I have a more general question.
I would like some general feedback on the way I am proposing to use token
arguments and operand bundles. I have an incomplete understanding of how these
are intended to be used, and I want to make sure what I have in mind is
consistent with the philosophy behind them.
Currently, the constrained floating point intrinsics require string metadata
arguments to describe the rounding mode and exception semantics. These
“arguments” are really providing information to the optimizer about what it can
and cannot assume when acting on these intrinsics. The rounding mode argument
potentially overrides the default optimizer assumption that the “to nearest”
rounding mode is in use, and the exception behavior argument overrides the
default optimizer assumption that floating point operations have no side
effects. I’ve never liked the use of strings here, and the fact that these
arguments are not actually inputs to the operation represented by the intrinsic
seems vaguely wrong.
A typical call to a current intrinsic looks like this:
%sum = call double @llvm.experimental.constrained.fadd(double %x,
double %y,
Metadata
“fpround.dynamic”,
Metadata
“fpexcept.strict”)
The idea I am pursuing in my patch is to replace these metadata arguments with
optional operand bundles, “fpround” and “fpexcept”. If the operand bundles are
present, they would mean what the arguments currently mean. If not, the default
assumption is allowed. A typical call to a constrained intrinsic would look like
this:
%sum = call double @llvm.experimental2.constrained.fadd(double %x,
double %y) [
“fpround”(token rmDynamic),
“fpexcept”(token ebStrict) ]
Does that seem like a valid use of tokens and operand bundles? Does it seem
better than the current approach?
Thanks,
Andy
_______________________________________________
LLVM Developers mailing list
llvm-dev at lists.llvm.org<mailto:llvm-dev at lists.llvm.org>
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20191114/39ce6517/attachment-0001.html>
Joseph Tremoulet via llvm-dev
2019-Nov-15 21:06 UTC
[llvm-dev] RFC: token arguments and operand bundles
As I recall, tokens were added largely as a mechanism to constrain particular
users to particular single-entry regions of the CFG, and to do so in a way that
guaranteed that later phases would be able to determine to which region any
given use was tied. That sounds pretty different to me than the use here of
wanting something that's less string-y than metadata but prints as something
less obtuse than an integer constant. I think it would functionally work to do
what you're proposing, but it strikes me as mixing unrelated concepts (one
of which is already fairly esoteric) in a way that I for one would caution
against. Your issue here strikes me as similar to what 'immArg'
addresses, and I'd imagine that having a way to constrain particular
'immArg' arguments to particular known enumerations of values in a way
that prints legibly is something that could have other uses as well and involve
less conceptual gymnastics. I'll also note that with the CFG-centric view
of tokens, it makes sense that the only constant token is 'None' - you
only need one way to indicate "not tied to any region".
Bundles strike me as a better fit. What strikes me as a bit odd there is that
bundles tend (or at least originally tended) to be used to communicate things
orthogonal to the semantics of the call itself (or the operation represented by
the call) - the ambient state of the virtual machine, the GC values that happen
to be live across the call, the EH region that happens to contain the call. In
this new case, the bundle is communicating something relevant to the semantics
of the operation that the call represents... but it's also true that, like
the other examples, it's communicating something about the context or
ambient state at the point of the call, and that it (IIUC) would be applied
consistently across the different fp operations... so that one passes my sniff
test, for whatever that's worth.
I'm also wondering if "named metadata" could help with the
readability issue.
-Joseph
From: llvm-dev <llvm-dev-bounces at lists.llvm.org> On Behalf Of Kaylor,
Andrew via llvm-dev
Sent: Thursday, November 14, 2019 2:40 PM
To: LLVM Developers Mailing List <llvm-dev at lists.llvm.org>
Subject: [llvm-dev] RFC: token arguments and operand bundles
Hello everyone,
I've just uploaded a patch
(https://reviews.llvm.org/D70261<https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Freviews.llvm.org%2FD70261&data=02%7C01%7Cjotrem%40microsoft.com%7C681ef688e2804e28dbf308d7693a70f6%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637093572046751978&sdata=BB2AZOZrm2BhlMQg20f88CYkXLTMdwxwP1I9NO3lLZw%3D&reserved=0>)
to introduce a could of new token types to be used with constrained floating
point intrinsics and, optionally, vector predicated intrinsics. These intrinsics
may not be of interest to many of you, but I have a more general question.
I would like some general feedback on the way I am proposing to use token
arguments and operand bundles. I have an incomplete understanding of how these
are intended to be used, and I want to make sure what I have in mind is
consistent with the philosophy behind them.
Currently, the constrained floating point intrinsics require string metadata
arguments to describe the rounding mode and exception semantics. These
"arguments" are really providing information to the optimizer about
what it can and cannot assume when acting on these intrinsics. The rounding mode
argument potentially overrides the default optimizer assumption that the
"to nearest" rounding mode is in use, and the exception behavior
argument overrides the default optimizer assumption that floating point
operations have no side effects. I've never liked the use of strings here,
and the fact that these arguments are not actually inputs to the operation
represented by the intrinsic seems vaguely wrong.
A typical call to a current intrinsic looks like this:
%sum = call double @llvm.experimental.constrained.fadd(double %x,
double %y,
Metadata
"fpround.dynamic",
Metadata
"fpexcept.strict")
The idea I am pursuing in my patch is to replace these metadata arguments with
optional operand bundles, "fpround" and "fpexcept". If the
operand bundles are present, they would mean what the arguments currently mean.
If not, the default assumption is allowed. A typical call to a constrained
intrinsic would look like this:
%sum = call double @llvm.experimental2.constrained.fadd(double %x,
double %y) [
"fpround"(token rmDynamic),
"fpexcept"(token ebStrict) ]
Does that seem like a valid use of tokens and operand bundles? Does it seem
better than the current approach?
Thanks,
Andy
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20191115/64eda889/attachment-0001.html>
Kaylor, Andrew via llvm-dev
2019-Nov-15 22:30 UTC
[llvm-dev] RFC: token arguments and operand bundles
Hi Joseph,
Thanks for the feedback. Ulrich Weigand raised the same concern about tokens in
my Phabricator review. As I said there, I see the point. I'm definitely
proposing a new use for the token type. For my use to be valid, I'd need to
redefine token something like this: "a compiler-generated pseudo-value that
is not intended to be represented in memory or register during program execution
and can only be used by compiler-specific intrinsics and instructions." I
think that covers the existing uses correctly. It is a new definition, but not
one that would require any changes to implement.
The other characteristics of tokens, such as not being allowed in PHI or select
instructions, are exactly what I'm after. I want a type of value that means
what the optimizer says it means and nothing else. However, I will admit that
what I want is more like an immediate operand that can only have one of the
small set of existing values. Unlike the tokens used by Windows exception
handling and coroutine intrinsics, I don't want these values to be part of a
use-def chain, though perhaps Jameson does want that.
Anyway, I agree with your assessment that the operand bundle part of my proposal
is on more solid ground than the token part.
Thanks,
Andy
From: Joseph Tremoulet <jotrem at microsoft.com>
Sent: Friday, November 15, 2019 1:07 PM
To: Kaylor, Andrew <andrew.kaylor at intel.com>
Cc: llvm-dev <llvm-dev at lists.llvm.org>
Subject: RE: RFC: token arguments and operand bundles
As I recall, tokens were added largely as a mechanism to constrain particular
users to particular single-entry regions of the CFG, and to do so in a way that
guaranteed that later phases would be able to determine to which region any
given use was tied. That sounds pretty different to me than the use here of
wanting something that's less string-y than metadata but prints as something
less obtuse than an integer constant. I think it would functionally work to do
what you're proposing, but it strikes me as mixing unrelated concepts (one
of which is already fairly esoteric) in a way that I for one would caution
against. Your issue here strikes me as similar to what 'immArg'
addresses, and I'd imagine that having a way to constrain particular
'immArg' arguments to particular known enumerations of values in a way
that prints legibly is something that could have other uses as well and involve
less conceptual gymnastics. I'll also note that with the CFG-centric view
of tokens, it makes sense that the only constant token is 'None' - you
only need one way to indicate "not tied to any region".
Bundles strike me as a better fit. What strikes me as a bit odd there is that
bundles tend (or at least originally tended) to be used to communicate things
orthogonal to the semantics of the call itself (or the operation represented by
the call) - the ambient state of the virtual machine, the GC values that happen
to be live across the call, the EH region that happens to contain the call. In
this new case, the bundle is communicating something relevant to the semantics
of the operation that the call represents... but it's also true that, like
the other examples, it's communicating something about the context or
ambient state at the point of the call, and that it (IIUC) would be applied
consistently across the different fp operations... so that one passes my sniff
test, for whatever that's worth.
I'm also wondering if "named metadata" could help with the
readability issue.
-Joseph
From: llvm-dev <llvm-dev-bounces at lists.llvm.org<mailto:llvm-dev-bounces
at lists.llvm.org>> On Behalf Of Kaylor, Andrew via llvm-dev
Sent: Thursday, November 14, 2019 2:40 PM
To: LLVM Developers Mailing List <llvm-dev at
lists.llvm.org<mailto:llvm-dev at lists.llvm.org>>
Subject: [llvm-dev] RFC: token arguments and operand bundles
Hello everyone,
I've just uploaded a patch
(https://reviews.llvm.org/D70261<https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Freviews.llvm.org%2FD70261&data=02%7C01%7Cjotrem%40microsoft.com%7C681ef688e2804e28dbf308d7693a70f6%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637093572046751978&sdata=BB2AZOZrm2BhlMQg20f88CYkXLTMdwxwP1I9NO3lLZw%3D&reserved=0>)
to introduce a could of new token types to be used with constrained floating
point intrinsics and, optionally, vector predicated intrinsics. These intrinsics
may not be of interest to many of you, but I have a more general question.
I would like some general feedback on the way I am proposing to use token
arguments and operand bundles. I have an incomplete understanding of how these
are intended to be used, and I want to make sure what I have in mind is
consistent with the philosophy behind them.
Currently, the constrained floating point intrinsics require string metadata
arguments to describe the rounding mode and exception semantics. These
"arguments" are really providing information to the optimizer about
what it can and cannot assume when acting on these intrinsics. The rounding mode
argument potentially overrides the default optimizer assumption that the
"to nearest" rounding mode is in use, and the exception behavior
argument overrides the default optimizer assumption that floating point
operations have no side effects. I've never liked the use of strings here,
and the fact that these arguments are not actually inputs to the operation
represented by the intrinsic seems vaguely wrong.
A typical call to a current intrinsic looks like this:
%sum = call double @llvm.experimental.constrained.fadd(double %x,
double %y,
Metadata
"fpround.dynamic",
Metadata
"fpexcept.strict")
The idea I am pursuing in my patch is to replace these metadata arguments with
optional operand bundles, "fpround" and "fpexcept". If the
operand bundles are present, they would mean what the arguments currently mean.
If not, the default assumption is allowed. A typical call to a constrained
intrinsic would look like this:
%sum = call double @llvm.experimental2.constrained.fadd(double %x,
double %y) [
"fpround"(token rmDynamic),
"fpexcept"(token ebStrict) ]
Does that seem like a valid use of tokens and operand bundles? Does it seem
better than the current approach?
Thanks,
Andy
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20191115/ba80c3f5/attachment-0001.html>
Philip Reames via llvm-dev
2019-Nov-18 21:52 UTC
[llvm-dev] RFC: token arguments and operand bundles
I'm going to mostly stay out of the floating point specifics, but I want to point out a few alternative approaches which have been used elsewhere in the past. We have the ability to require a intrinsic function argument to be a constant. We have support for annotations printed during IR serialization. Putting those together, we could use an argument encoding + annotation printer to field something like: %sum = call double @llvm.experimental.constrained.fadd(double %x, double %y, int 0, int 1) ;; fpround.dynamic + fpexcept.strict If we didn't want to have token types involved, we could use operand bundles and a custom annotator. We'd get something like: %sum = call double @llvm.experimental2.constrained.fadd(double %x, double %y) [ “fenv”(i32 0, i32 1)] ;; fpround.dynamic + fpexcept.strict </end alternatives> Personally, I'd try to avoid token types here. Token types are relatively ill defined, and most of the cases we've used them have been a proxy for multiple variable return. In retrospect, I wish we'd done multiple variable return e.g. statepoints. Philip On 11/14/19 11:39 AM, Kaylor, Andrew via llvm-dev wrote:> > Hello everyone, > > I’ve just uploaded a patch (https://reviews.llvm.org/D70261) to > introduce a could of new token types to be used with constrained > floating point intrinsics and, optionally, vector predicated > intrinsics. These intrinsics may not be of interest to many of you, > but I have a more general question. > > I would like some general feedback on the way I am proposing to use > token arguments and operand bundles. I have an incomplete > understanding of how these are intended to be used, and I want to make > sure what I have in mind is consistent with the philosophy behind them. > > Currently, the constrained floating point intrinsics require string > metadata arguments to describe the rounding mode and exception > semantics. These “arguments” are really providing information to the > optimizer about what it can and cannot assume when acting on these > intrinsics. The rounding mode argument potentially overrides the > default optimizer assumption that the “to nearest” rounding mode is in > use, and the exception behavior argument overrides the default > optimizer assumption that floating point operations have no side > effects. I’ve never liked the use of strings here, and the fact that > these arguments are not actually inputs to the operation represented > by the intrinsic seems vaguely wrong. > > A typical call to a current intrinsic looks like this: > > *%sum = call double @llvm*.experimental.constrained.fadd(double %x, > > double %y, > > Metadata “fpround.dynamic”, > > Metadata “fpexcept.strict”) > > The idea I am pursuing in my patch is to replace these metadata > arguments with optional operand bundles, “fpround” and “fpexcept”. If > the operand bundles are present, they would mean what the arguments > currently mean. If not, the default assumption is allowed. A typical > call to a constrained intrinsic would look like this: > > *%sum = call double @llvm*.experimental2.constrained.fadd(double %x, > > double %y) [ “fpround”(token rmDynamic), > > “fpexcept”(token ebStrict) ] > > Does that seem like a valid use of tokens and operand bundles? Does it > seem better than the current approach? > > Thanks, > > Andy > > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20191118/fd85f93d/attachment.html>
Reid Kleckner via llvm-dev
2019-Nov-19 17:57 UTC
[llvm-dev] RFC: token arguments and operand bundles
Based on what I've read in this thread, it doesn't seem like tokens are a good fit here. If in the future we want to establish different regions of FP safety (i.e. inlining functions with different FP safety settings), then it might make sense to start using tokens. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20191119/0e9409f8/attachment.html>
Kaylor, Andrew via llvm-dev
2019-Nov-19 18:24 UTC
[llvm-dev] RFC: token arguments and operand bundles
I think we do want to support different regions of FP safety through inlining and other means, but I otherwise agree with your conclusion that tokens as I was using them are not a good fit. We should be able to handle different regions by using different constraint arguments (in whatever form). From: Reid Kleckner <rnk at google.com> Sent: Tuesday, November 19, 2019 9:58 AM To: Kaylor, Andrew <andrew.kaylor at intel.com> Cc: LLVM Developers Mailing List <llvm-dev at lists.llvm.org> Subject: Re: [llvm-dev] RFC: token arguments and operand bundles Based on what I've read in this thread, it doesn't seem like tokens are a good fit here. If in the future we want to establish different regions of FP safety (i.e. inlining functions with different FP safety settings), then it might make sense to start using tokens. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20191119/4069fc5e/attachment.html>