-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[CodeGen][MachineVerifier] Use TypeSize instead of unsigned for getRe… #70881
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 4 commits
8c0577a
7d1aace
166017c
0f0e8ab
10d2840
624c945
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 |
---|---|---|
|
@@ -1937,29 +1937,34 @@ void MachineVerifier::visitMachineInstrBefore(const MachineInstr *MI) { | |
|
||
// If we have only one valid type, this is likely a copy between a virtual | ||
// and physical register. | ||
unsigned SrcSize = 0; | ||
unsigned DstSize = 0; | ||
TypeSize SrcSize = TRI->getRegSizeInBits(SrcReg, *MRI); | ||
TypeSize DstSize = TRI->getRegSizeInBits(DstReg, *MRI); | ||
if (SrcReg.isPhysical() && DstTy.isValid()) { | ||
const TargetRegisterClass *SrcRC = | ||
TRI->getMinimalPhysRegClassLLT(SrcReg, DstTy); | ||
if (SrcRC) | ||
SrcSize = TRI->getRegSizeInBits(*SrcRC); | ||
} | ||
|
||
if (SrcSize == 0) | ||
SrcSize = TRI->getRegSizeInBits(SrcReg, *MRI); | ||
|
||
if (DstReg.isPhysical() && SrcTy.isValid()) { | ||
const TargetRegisterClass *DstRC = | ||
TRI->getMinimalPhysRegClassLLT(DstReg, SrcTy); | ||
if (DstRC) | ||
DstSize = TRI->getRegSizeInBits(*DstRC); | ||
} | ||
|
||
if (DstSize == 0) | ||
DstSize = TRI->getRegSizeInBits(DstReg, *MRI); | ||
// If the Dst is scalable and the Src is fixed, then the Dst can only hold | ||
// the Src if the minimum size Dst can hold is at least as big as Src. | ||
if (DstSize.isScalable() && !SrcSize.isScalable() && | ||
DstSize.getKnownMinValue() <= SrcSize.getFixedValue()) | ||
break; | ||
// If the Src is scalable and the Dst is fixed, then Dest can only hold | ||
// the Src is known to fit in Dest | ||
if (SrcSize.isScalable() && !DstSize.isScalable() && | ||
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. @arsenm I think I should remove this case. I'm not testing for it and I'm pretty sure its impossible for isKnownLE to ever be true here. WDYT? 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. Copy is only supposed to allow equal sized operands, but that starts getting fuzzy with physical registers. Is it really supposed to allow these mixed cases for scalable vectors? 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 agree that copys should be of the same size. As far as I understand the scalable vector registers have never been marked as "Scalable" though, only being given a size equal to the KnownMinValue. The patch at davemgreen@07e9bdd was enough to make the test case there work for a simple add. It went the route of marking the vector registers as scalable. I don't think that is necessary to make things work though, in that I can remove the Scalable defs from RegisterClasses and so long as it gets past the verifier it works for that small example still. SDAG never needed the registers to be scalable. The sizes of some of the SVE scalable register types is a bit odd in places though, I was expecting them to all be vscale*128bit, and Im not sure how RISCV scalable vectors are defined. 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. We do need some ability to copy physical registers into virtual registers and vice versa. The way we accomplish this, I am not sure, and I am interested in having a discussion on it. I have updated the code here to allow copy from physical -> virtual when we know the min size is at least as big. However, I am not confident that this is the correct approach. The first reason I am not sure this is the correct approach is because this dual for return values will not work:
The problem here is that The second reason I am not sure this is the correct approach is because it isn't clear to me what happens to elements in the scalable vector that are past the size of the physical register. For example, v8 in the test case below reports a size of 64 bits, but %0 reports a size of vscale x 8. If vscale is bigger than 8, then I'm not sure what goes into the rest of the elements. Does anyone have any opinion on a better approach? @davemgreen, does marking the physical registers as scalable solve this problem? IIUC marking v8 here as scalable would mean that it has size 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. @davemgreen do you plan to PR davemgreen@07e9bdd? I am pretty sure at least some of the 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. Hello - I don't have any immediate plans to push that forward, it would take some cleanup to get it into a good state. Feel free to take/reuse any part that is useful to you. As for the verifier check, as far as I understand that we have it at the moment, the "Size" of the physical register class should be the fixed size without being marked as scalable, and all the types added to it should be the same size or smaller ignoring the scalability. 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 believe what is implemented here essentially does this, without marking the physical register as scalable. Here, we check that the MinKnownValue is less than or equal to the fixed value. This is the same as checking that the "size of the physical register should be the fixed size without being marked as scalable". I think this patch here is less invasive than marking physical registers as scalable and I propose that we take this patch and can discuss making physical registers scalable in the future. WDYT? 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. Yeah that sounds OK to me, with the way scalable vector currently work. We can adjust it later if it becomes an issue. |
||
TypeSize::isKnownLE(DstSize, SrcSize)) | ||
break; | ||
|
||
if (SrcSize != 0 && DstSize != 0 && SrcSize != DstSize) { | ||
if (SrcSize.isNonZero() && DstSize.isNonZero() && SrcSize != DstSize) { | ||
if (!DstOp.getSubReg() && !SrcOp.getSubReg()) { | ||
report("Copy Instruction is illegal with mismatching sizes", MI); | ||
errs() << "Def Size = " << DstSize << ", Src Size = " << SrcSize | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 3 | ||
# RUN: llc -mtriple=riscv64 -o - -global-isel -run-pass=none -verify-machineinstrs %s | FileCheck %s | ||
# REQUIRES: riscv64-registered-target | ||
|
||
--- | ||
name: test_copy_fixed_to_scalable | ||
legalized: true | ||
regBankSelected: false | ||
selected: false | ||
tracksRegLiveness: true | ||
registers: | ||
- { id: 0, class: _, preferred-register: '' } | ||
liveins: | ||
body: | | ||
bb.0: | ||
liveins: $v8 | ||
|
||
; CHECK-LABEL: name: test_copy_fixed_to_scalable | ||
; CHECK: liveins: $v8 | ||
; CHECK-NEXT: {{ $}} | ||
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<vscale x 1 x s8>) = COPY $v8 | ||
%0:_(<vscale x 1 x s8>) = COPY $v8 | ||
... |
Uh oh!
There was an error while loading. Please reload this page.