-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[ADT] Fix specialization of ValueIsPresent for PointerUnion #121847
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
Changes from 3 commits
107a35d
f833dff
13a9098
8abd5cd
294c617
62157bf
0546ba3
f0140f8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -134,10 +134,10 @@ const TargetRegisterClass *RegisterBankInfo::constrainGenericRegister( | |
|
|
||
| // If the register already has a class, fallback to MRI::constrainRegClass. | ||
| auto &RegClassOrBank = MRI.getRegClassOrRegBank(Reg); | ||
| if (isa<const TargetRegisterClass *>(RegClassOrBank)) | ||
| if (isa_and_present<const TargetRegisterClass *>(RegClassOrBank)) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think either of these 2 instances should ever encounter a register without a set class or bank, this is papering over a different bug?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Input gMIR to instruction selector shouldn't contain registers without class/bank. This is what
I don't know if this should be considered a bug. If it should, I can try to address it separately (probably in #121270). (Unrelated to this PR). Note that the type of the temporary register is
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
As I mentioned in the other PR this is broken. In no context should an incomplete virtual register be used by an instruction
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It appears there is another context when class/bank may not be set: 7e1f66d
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. After regbankselect / in the selection pass, there must be a class or bank set. The null/null case is only valid before that, when a generic vreg must have a type |
||
| return MRI.constrainRegClass(Reg, &RC); | ||
|
|
||
| const RegisterBank *RB = cast<const RegisterBank *>(RegClassOrBank); | ||
| const auto *RB = dyn_cast_if_present<const RegisterBank *>(RegClassOrBank); | ||
| // Otherwise, all we can do is ensure the bank covers the class, and set it. | ||
| if (RB && !RB->covers(RC)) | ||
| return nullptr; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -208,6 +208,11 @@ TEST_F(PointerUnionTest, NewCastInfra) { | |
| EXPECT_FALSE(isa<float *>(d4null)); | ||
| EXPECT_FALSE(isa<long long *>(d4null)); | ||
|
|
||
| EXPECT_FALSE(isa_and_present<int *>(i4null)); | ||
| EXPECT_FALSE(isa_and_present<float *>(f4null)); | ||
| EXPECT_FALSE(isa_and_present<long long *>(l4null)); | ||
| EXPECT_FALSE(isa_and_present<double *>(d4null)); | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Previously, only the first |
||
|
|
||
| // test cast<> | ||
| EXPECT_EQ(cast<float *>(a), &f); | ||
| EXPECT_EQ(cast<int *>(b), &i); | ||
|
|
||
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.
Is this enable_if needed? Isn't PointerUnion always nullable because it satisfies
std::is_constructible_v<PointerUnion<PTs...>, std::nullptr_t>?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.
I agree that this looks suspicious, but this is the only way I could get it compiled without errors.
I would appreciate it if someone could explain to me why this is necessary and how it can be simplified.
https://godbolt.org/z/x6dKhr5x1
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 think the underlying issue is that without this, the main partial specialization from here would be as good of a match as this one:
llvm-project/llvm/include/llvm/Support/Casting.h
Line 622 in 2a4992e
voidat the end both L622 and here. In the godbolt link,enable_if<true>doesn't work because it appears in non-deduced context.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.
Another way to handle this would be to change the main
ValueIsPresentfor nullable types to cast to bool instead, or introduce some traits for nullable types that would tell you how to check for null values that you can specialize for PointerUnion.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 tried
which always evaluates to
voidand introduces(?) deduced context, but the error persists. Shouldn't this work?The existing implementation implicitly assumes that if a type is constructible from
nullptr_t, thenoperator==exists and works the way that's expected in this particular use case. Apparently, this doesn't work for PointerUnion.Casting to bool works for PointerUnion, but may in theory not work for other types. I'll make this change because it is simpler, but I think the best solution would be to stop making implicit assumptions about existence / behavior of
operator==/operator bool()and require the clients to explicitly provide specializations if the behavior should diverge from the default.