-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[RISCV][GISEL] Fix legalization for G_MERGE/UNMERGE_VALUES #75619
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
[RISCV][GISEL] Fix legalization for G_MERGE/UNMERGE_VALUES #75619
Conversation
@llvm/pr-subscribers-llvm-globalisel @llvm/pr-subscribers-backend-risc-v Author: Michael Maitland (michaelmaitland) ChangesThere are two bugs fixed by this patch:
The existing test was passing because (2) covered up (1). Full diff: https://github.com/llvm/llvm-project/pull/75619.diff 1 Files Affected:
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
index 8f03a7ac41d37b..b46269fb9565fb 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
@@ -85,14 +85,16 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
// Merge/Unmerge
for (unsigned Op : {G_MERGE_VALUES, G_UNMERGE_VALUES}) {
- unsigned BigTyIdx = Op == G_MERGE_VALUES ? 0 : 1;
- unsigned LitTyIdx = Op == G_MERGE_VALUES ? 1 : 0;
auto &MergeUnmergeActions = getActionDefinitionsBuilder(Op);
if (XLen == 32 && ST.hasStdExtD()) {
- LLT IdxZeroTy = G_MERGE_VALUES ? s64 : s32;
- LLT IdxOneTy = G_MERGE_VALUES ? s32 : s64;
- MergeUnmergeActions.legalFor({IdxZeroTy, IdxOneTy});
+ // Only need to legalize on IdxZeroTy since there is no way to construct
+ // a valid MERGE/UNMERGE where the types don't combine/decompose as
+ // expected.
+ LLT IdxZeroTy = Op == G_MERGE_VALUES ? s64 : s32;
+ MergeUnmergeActions.legalFor({IdxZeroTy});
}
+ unsigned BigTyIdx = Op == G_MERGE_VALUES ? 0 : 1;
+ unsigned LitTyIdx = Op == G_MERGE_VALUES ? 1 : 0;
MergeUnmergeActions.widenScalarToNextPow2(LitTyIdx, XLen)
.widenScalarToNextPow2(BigTyIdx, XLen)
.clampScalar(LitTyIdx, sXLen, sXLen)
|
// a valid MERGE/UNMERGE where the types don't combine/decompose as | ||
// expected. | ||
LLT IdxZeroTy = Op == G_MERGE_VALUES ? s64 : s32; | ||
MergeUnmergeActions.legalFor({IdxZeroTy}); |
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.
Don't you need to list 2 types here?
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.
Do we need to?
// Only need to legalize on IdxZeroTy since there is no way to construct
// a valid MERGE/UNMERGE where the types don't combine/decompose as
// expected.
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'm surprised there isn't a check that the correct number of type indices is provided to .legalFor.
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 there can only be two type indices for these opcodes. A small type or a large type. You cannot construct a MERGE/UNMERGE with >2 types.
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'm surprised that we don't have to pass a 2 element initializer_list to legalFor
for an opcode that is defined with 2 type indices. It doesn't make sense to me that you can just omit a type for type index 1.
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 have updated the code to do this, but I suppose there could be a case where you want to mark a type index as legal, regardless of what the other type index is.
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 have updated the code to do this, but I suppose there could be a case where you want to mark a type index as legal, regardless of what the other type index is.
You couldn't make type index 1 legal and ignore type index 0 though. So it would be inconsistent if that was the intent.
MergeUnmergeActions.legalFor({IdxZeroTy, IdxOneTy}); | ||
LLT IdxZeroTy = Op == G_MERGE_VALUES ? s64 : s32; | ||
LLT IdxOneTy = Op == G_MERGE_VALUES ? s32 : s64; | ||
MergeUnmergeActions.legalFor({{IdxZeroTy}, {IdxOneTy}}); |
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.
Can we write
MergeUnmergeActions.legalFor(all(typeIs(BigTyIdx, s64), typeIs(LitTyIdx, s32)))`
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
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 - thanks @michaelmaitland
This needs to be rebased now |
The legalFor check did not work as expected. Use legalIf instead. Also do some simplification by removing IdxZeroTy and IdxOneTy.
70dc7d7
to
011f4d6
Compare
There are two bugs fixed by this patch:
The existing test was passing because (2) covered up (1).