-
Notifications
You must be signed in to change notification settings - Fork 13.7k
[CIR] Upstream support for promoted types with unary plus/minus #133829
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
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
So I'm having a touch of trouble understanding this, so can you clarify:
We're casting the f16 to float (f32) because we expect the hardware doesn't support f16 operations, right? So we cast it, do the math, then bring it back.
I find myself wondering why CIR doesn't need/shouldn't model this instead, and this shouldn't happen in CIR->LLVM-IR lowering?
Uh oh!
There was an error while loading. Please reload this page.
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.
Yep, it does make sense, we do similar with other operations. If we go about this I suggest we land the direct version first and introduce a more higher level CIR in a follow up (and add that to incu too).
Some background: so far the approach has been not to raise too early unless we (a) have use case for those new ops, or (b) we feel it's a natural improvement and have time to work on it. Otherwise we start very similar to LLVM (as the safe known path) until an opportunity to raise appears. Depending on how hard it might be (e.g. when dealing with vtables, itanium logic, etc) we usually ask folks to do the most similar to LLVM first and in a subsquent PR work on a more higher level approach, this allows us to get functionality before potential design problems (and PRs not moving along because too many design iterations).
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.
@erichkeane This is an excellent question, and I'm glad you raised it this early in the process. As I've been working on upstreaming these operations, I found myself somewhat confused by the difference between type promotion that is happening because the C/C++ semantics require it (such as short-to-int promotion during increment/decrement) and promotion that's happening because the compile options want us to perform calculations with excess precision (such as the fp16-to-float promotion seen here). There's also going to be some type promotion associated with complex division, which is yet a third thing. The terminology in the code doesn't really distinguish between these.
I believe the C/C++ standard promotions are represented directly in the AST, and so we don't need any special handling for them. I think you're right that we probably do not want to encode the other type promotions directly into CIR in the long run, but I'm not sure how the lowering would determine if this sort of promotion needs to happen. And if we lower to other intermediate dialects, do those dialects need to know about the promotion? I think if they don't, it's not going to happen, but it also seems like they might want to know what the real data type in the source was, especially if they're going to be making decisions about vectorizing or offloading to different hardware.
@bcardosolopes When you say, "land the direct version first," do you mean proceed with this PR as is? That seems reasonable to me. I just wanted to make sure we're all in agreement.
Long term, I think we have at least two options: (1) generate CIR that operates directly on the FP16/BF16 types with no indication that promotion might be required and insert the promotion during lowering if it is needed, or (2) generate CIR that explicitly represents the fact that we're promoting the type to perform calculations with excess precision. It sounds like maybe you want to consider the second approach? Or am I misunderstanding?
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, that is correct, any language required conversions are done as a part of AST creation via casts.
That is my take from what he said. My summary of Bruno's post is: "When designing CIR we stayed as low-level to LLVM-IR as possible, except when we saw explicit benefit of making CIR a 'higher level' language. So merge it as-is now, and if we see benefit to figuring this out later, do it then".
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!
Uh oh!
There was an error while loading. Please reload this page.
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.
Both (1) and (2) have different design tradeoffs and my experience has been that it varies depending on the use case in question. For this specific case, I'd say that if the promotions aren't crucial for analysis on top of CIR (right now), I'd defer the details to LLVM, staying with (1) - note that here the operation itself wraps the semantic, because it contains enough info for you to lower things properly later on. In case you can see the explicit promotions being helpful for other things (random speculative example: callconv lowering) then it might be worth doing (2). Either way, implementation experience will tell if you should move from one to the other approach over time - in CIR so far we've come back n forth with similar design choices as part of evolving things over time.