-
Notifications
You must be signed in to change notification settings - Fork 124
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
[CIR][CIRGen] Support for C++20 three-way comparison #485
Conversation
Are the check errors related? If so they need to be fixed. |
After some investigation I found the root cause of the problem. Well, technically this is not a problem of the code, just that the test checks are not general enough. The problem looks a bit strange at first. For the test input: auto three_way_strong(int x, int y) {
return x <=> y;
} clangir emits different CIR on Linux/Windows and macOS. On Linux or Windows, clangir emits: %3 = cir.load %0 : cir.ptr <!s32i>, !s32i loc(#loc8)
%4 = cir.load %1 : cir.ptr <!s32i>, !s32i loc(#loc9)
%5 = cir.const(#cir.int<1> : !s8i) : !s8i loc(#loc28)
%6 = cir.const(#cir.int<-1> : !s8i) : !s8i loc(#loc28)
%7 = cir.cmp(lt, %3, %4) : !s32i, !cir.bool loc(#loc28) On macOS, clangir emits: %3 = cir.load %0 : cir.ptr <!s32i>, !s32i loc(#loc8)
%4 = cir.load %1 : cir.ptr <!s32i>, !s32i loc(#loc9)
%5 = cir.cmp(lt, %3, %4) : !s32i, !cir.bool loc(#loc28)
%6 = cir.const(#cir.int<-1> : !s8i) : !s8i loc(#loc28)
%7 = cir.const(#cir.int<1> : !s8i) : !s8i loc(#loc28) Note the order of the last three operations gets reversed on macOS. The test checks only covers the operation sequence on Linux so on macOS the test fails. But the macOS code is still correct and CIRGen code has no problems. The relevant CIRGen code is the following one-liner at https://github.com/llvm/clangir/pull/485/files#diff-eed2632a5f5feb5d46423a602c86f0b5f5327ef95f2cb43e50bd2c628537461fR1127: auto SelectOne = EmitSelect(EmitCmp(CK_Less), EmitCmpRes(CmpInfo.getLess()),
EmitCmpRes(CmpInfo.getGreater())); The problem here is that the order of generated CIR operations depends on the evaluation order of the three arguments to the So the solution should be updating the test checks so they accept both of the two operation sequence. |
Unfortunately I could not find a way to make FileCheck accept both output... So I updated the code to make sure that the output CIR operation sequence is consistent across all platforms. |
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 is awesome, thanks for working on this! Since this is a bit more simple and close to traditional LLVM codegen, I'd prefer if this PR can already raise the three-way cmp functionality:
- Add a higher level op for the three way cmp and CIRGen that. Should probably be its own Op (as opposed to incorporated into
cir.cmp
, given we'll need some category information). - Emit the code in this PR via LoweringPrepare.
Yes this is the longer direction. Since this should be straight-forward enough I'll implement it directly into this PR. So I'm now turning this PR into draft state and will convert it back once this is done. |
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.
Great, comments inline!
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.
LGTM
|
||
#include "Inputs/std-compare.h" | ||
|
||
// BEFORE: #cmp3way_info_partial_ltn1eq0gt1unn127_ = #cir.cmp3way_info<partial, lt = -1, eq = 0, gt = 1, unordered = -127> |
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.
Mixed feelings because it's nice to have all that info, but maybe it's too big? Should we get a bit more terse in the alias? I was thinking #cmp3HASH
at most. Anyways it's something to be addressed in another PR, this is good for now.
Some conflicts need to be address before merge |
This patch adds CIRGen support for the C++20 three-way comparison operator `<=>`. The binary operator is directly lowered to existing CIR operations.
361d62c
to
a47de98
Compare
Squashed and rebased onto the latest |
As a side note for potential future improvements: LLVM now has an RFC that adds 3-way comparison intrinsic. LLVM folks believe this new intrinsic can generate better code for various targets. This project will be done in GSoC2024 and when it's done we can consider lowering |
This patch adds CIRGen support for the C++20 three-way comparison operator `<=>`. The binary operator is directly lowered to existing CIR operations. Most of the changes are tests.
This patch adds CIRGen support for the C++20 three-way comparison operator `<=>`. The binary operator is directly lowered to existing CIR operations. Most of the changes are tests.
This patch adds CIRGen support for the C++20 three-way comparison operator `<=>`. The binary operator is directly lowered to existing CIR operations. Most of the changes are tests.
This patch adds CIRGen support for the C++20 three-way comparison operator `<=>`. The binary operator is directly lowered to existing CIR operations. Most of the changes are tests.
This patch adds CIRGen support for the C++20 three-way comparison operator `<=>`. The binary operator is directly lowered to existing CIR operations. Most of the changes are tests.
This patch adds CIRGen support for the C++20 three-way comparison operator `<=>`. The binary operator is directly lowered to existing CIR operations. Most of the changes are tests.
This patch adds CIRGen support for the C++20 three-way comparison operator `<=>`. The binary operator is directly lowered to existing CIR operations. Most of the changes are tests.
This patch adds CIRGen support for the C++20 three-way comparison operator `<=>`. The binary operator is directly lowered to existing CIR operations. Most of the changes are tests.
This patch adds CIRGen support for the C++20 three-way comparison operator `<=>`. The binary operator is directly lowered to existing CIR operations. Most of the changes are tests.
This patch adds CIRGen support for the C++20 three-way comparison operator `<=>`. The binary operator is directly lowered to existing CIR operations. Most of the changes are tests.
This patch adds CIRGen support for the C++20 three-way comparison operator
<=>
. The binary operator is directly lowered to existing CIR operations.Most of the changes are tests.