Previously we considered this field to be either N-bit unsigned or
N+1-bit signed, depending on the instruction. I think it's conceptually
simpler to say that the field is always N+1-bit signed, but some
instructions do not allow negative values.
Details
- Reviewers
matejam piotr scott.linder - Group Reviewers
Restricted Project - Commits
- rGf460c6658107: [AMDGPU] Simplify getNumFlatOffsetBits. NFC.
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
llvm/lib/Target/AMDGPU/SIInstrInfo.cpp | ||
---|---|---|
7968 | Is this actually an improvement? Wouldn't it be conceptually simpler to pass FlatVariant and get the actual width and, if needed, signedness? |
Is this actually an improvement?
I think so (of course!) because it simplifies getNumFlatOffsetBits without making its callers more complicated.
Wouldn't it be conceptually simpler to pass FlatVariant and get the actual width and, if needed, signedness?
Not sure what you mean by "actual width" here. I would not want to revert to getNumFlatOffsetBits returning different values for different flat variants on the same subtarget. But I suppose an additional patch to make getNumFlatOffsetBits return the "AllowNegative" flag as well as the field width might be an improvement.
By actual width I mean what can be passed to isIntN()/isUInt() without adjustments. The AllowNegative thing feels a bit alien to the ISA, effectively adding an extra concept while not eliminating the need for adjustments. Signedness, in contrast, looks rather natural and familiar, and if (Signed ? isIntN(...) : isUIntN(...)) is probably easier to understand than if (!isIntN(...) || (!AllowNegative && Op.getImm() < 0)).
The AllowNegative thing feels a bit alien to the ISA, effectively adding an extra concept while not eliminating the need for adjustments.
Then I think we simply disagree about which one is conceptually simpler.
llvm/lib/Target/AMDGPU/SIInstrInfo.cpp | ||
---|---|---|
7942 | I don't think "ignored" is right. In at least some cases (like hasNegativeScratchOffsetBug) it is definitely not ignored but leads to wrong behaviour. |
I agree that it is a bit simpler to conceptualize it as a signed field with a common size, especially as we already have to think about the "negative scratch offset bug" for some "signed" versions of the field. At that point, might as well just say it is always a signed field, and negative values are sometimes illegal.
Wouldn't it be conceptually simpler to pass FlatVariant and get the actual width and, if needed, signedness?
Not sure what you mean by "actual width" here. I would not want to revert to getNumFlatOffsetBits returning different values for different flat variants on the same subtarget. But I suppose an additional patch to make getNumFlatOffsetBits return the "AllowNegative" flag as well as the field width might be an improvement.
+1 to returning AllowNegative from getNumFlatOffsetBits, especially with structured bindings making it less awkward:
auto [OffsetSize, AllowNegative] = AMDGPU::getNumFlatOffsetBits(getSTI(), TSFlags);
llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp | ||
---|---|---|
4119 | ||
4120–4121 | If the MSB is not always ignored, this comment should be updated/deleted |
I agree that it is a bit simpler to conceptualize it as a signed field with a common size, especially as we already have to think about the "negative scratch offset bug" for some "signed" versions of the field. At that point, might as well just say it is always a signed field, and negative values are sometimes illegal.
The advantage of the original code is that it encapsulates (apart from the signedness and bug-handling bits, sadly) these specifics in a single place, getNumFlatOffsetBits(), whereas the proposed version effectively lets them leak to the surrounding logic. So on generating the error particularly the new code translates the signed non-negatives back to the precision-and-signedness representation.
So on generating the error particularly the new code translates the signed non-negatives back to the precision-and-signedness representation.
I only did that to make the patch NFC including the text of error messages. Really I'd prefer to reword the error message too, to something like "expected an N-bit signed offset" or "expected a non-negative N-bit signed offset".
llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp | ||
---|---|---|
4120–4121 | In the absence of hardware bugs this might be true; I really don't know. I will see if I can find some good documentation. OTOH it is not a very useful comment for us, since the compiler never needs to rely on the bit being "ignored and forced to zero". |
"expected a non-negative N-bit signed offset"
Might be worth ruminating on whether that would be an improvement as well before moving forward with this patch, on which, apart from noting that silicon-level bugs are probably not the best reasoning for user-exposed conceptual models, I've decided to have no opinion. :)
Things to take into consideration: that the offset bug will retire at some point and the chance for the hardware to support other offset representations in the future.
I'm not sure I follow the argument here, as the only thing being encapsulated is the field size as a function of the signedness, but you immediately say the signedness is sadly not encapsulated. What is being encapsulated more completely in the old version?
I think this is the most compelling argument for leaving things as they are, along with the fact that anything we change here adds a small gap between the compiler writer/user's model and the model that the hardware specs document.
Also, just to clarify, even in light of the arguments against it I still vote for the change being made.
LGTM
I'm open to renaming things, but I think AllowNegative is at least as clear as anything I can think of.