-
Notifications
You must be signed in to change notification settings - Fork 14.5k
[AVR] Fix incorrect selection of post indexed addresses #145040
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
Conversation
@benshi001 Please review |
@@ -1114,6 +1120,10 @@ bool AVRTargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op, | |||
if (AVR::isProgramMemoryAccess(LD)) | |||
return false; | |||
|
|||
// Fixes https://github.com/llvm/llvm-project/issues/143247 |
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.
For the above lines,
// FIXME: We temporarily disable post increment load from program memory,
// due to bug https://github.com/llvm/llvm-project/issues/59914.
It is also a walkaround committed by me, it revealed the root cause, though did not fix the root cause.
I hope your walk around solution can also be like that.
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.
.
@Benshi Thanks for the review. What do you mean with "the generated .ll files have slight difference"? Which files are you comparing? Changing |
fwiw - one sec, I'm taking a look as well 🔍 |
✅ With the latest revision this PR passed the C/C++ code formatter. |
Ok, got it - I think we're hitting the same condition RISC-V and aarch64 are already guarded against:
So I thiiiink the proper fix would be to: diff --git a/llvm/lib/Target/AVR/AVRISelLowering.cpp b/llvm/lib/Target/AVR/AVRISelLowering.cpp
index d65ef8986c98..c319499ecc05 100644
--- a/llvm/lib/Target/AVR/AVRISelLowering.cpp
+++ b/llvm/lib/Target/AVR/AVRISelLowering.cpp
@@ -1120,12 +1120,22 @@ bool AVRTargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op,
if (AVR::isProgramMemoryAccess(LD))
return false;
- // Fixes https://github.com/llvm/llvm-project/issues/143247
- if (Op->getOperand(0)->hasOneUse())
+ SDValue Ptr;
+ if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {
+ Ptr = LD->getBasePtr();
+ } else if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
+ Ptr = ST->getBasePtr();
+ } else
return false;
Base = Op->getOperand(0);
Offset = DAG.getConstant(RHSC, DL, MVT::i8);
+
+ // Post-indexing updates the base, so it's not a valid transform
+ // if that's not the same as the load's pointer.
+ if (Ptr != Base)
+ return false;
+
AM = ISD::POST_INC;
return true; |
@Patryk27 Great! Committed your suggestion, the CI test should pick it up. Should the same be applied to pre-indexing? |
Doesn't seem so, it's just a post-indexing thingie. |
Ok, I think you should take ownership of the fix commit. Not sure what the easiest way to do that is. This PR could just be the new CI test? Anyway, nice find. I looked briefly at the arm32 sources, but that did not result in anything usefull. :/ |
Yea, if you dropped the three commits here and added a new commit just with the test, I could take it from here and create a new pull request with the test and fix 🙂 |
I was comparing your test program #define PA 0x1 // Bad
//#define PA 0x2 // Good
volatile char *const PORT = (char *const) PA;
extern void nil(short);
void bug()
{
short s= 0;
while (1) {
s++;
*PORT = *PORT | 0x80;
nil((s & 0xF) + 1);
}
} |
We need not two commits (test+fix) for a bug fix, you can directly create a new PR with both of the test and fix. |
@Patryk27 Ok, as suggested by @benshi001 can you create a new PR with the fix and edited test? I will close this PR. Thanks! |
@Patryk27 added a cleaned up test to this PR for your convenience. |
|
Cut out of llvm#145040; thanks to @tomtor for preparing the test. Basically, we're hitting the same edge case as RISC-V and aarch64: - https://github.com/llvm/llvm-project/blob/2ed089fb18b92ad668509076b9830f55d96d27fe/llvm/lib/Target/RISCV/RISCVISelLowering.cpp#L2354 - https://github.com/llvm/llvm-project/blob/2ed089fb18b92ad668509076b9830f55d96d27fe/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp#L27144 Closes llvm#143247.
Cut out of llvm#145040; thanks to @tomtor for preparing the test. Basically, we're hitting the same edge case as RISC-V and aarch64: - https://github.com/llvm/llvm-project/blob/2ed089fb18b92ad668509076b9830f55d96d27fe/llvm/lib/Target/RISCV/RISCVISelLowering.cpp#L23545 - https://github.com/llvm/llvm-project/blob/2ed089fb18b92ad668509076b9830f55d96d27fe/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp#L27144 Closes llvm#143247.
Cut out of llvm#145040; thanks to @tomtor for preparing the test. Basically, we're hitting the same edge case as RISC-V and aarch64: - https://github.com/llvm/llvm-project/blob/2ed089fb18b92ad668509076b9830f55d96d27fe/llvm/lib/Target/RISCV/RISCVISelLowering.cpp#L23545 - https://github.com/llvm/llvm-project/blob/2ed089fb18b92ad668509076b9830f55d96d27fe/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp#L27144 Closes llvm#143247.
Cut out of llvm#145040; thanks to @tomtor for preparing the test. Basically, we're hitting the same edge case as RISC-V and aarch64: - https://github.com/llvm/llvm-project/blob/2ed089fb18b92ad668509076b9830f55d96d27fe/llvm/lib/Target/RISCV/RISCVISelLowering.cpp#L23545 - https://github.com/llvm/llvm-project/blob/2ed089fb18b92ad668509076b9830f55d96d27fe/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp#L27144 Closes llvm#143247.
Fixes #143247
For testing this PR I used the following code:
It contains the code which triggers the original bug and two demo functions which still emit post/pre-index code triggered by
getPostIndexedAddressParts
.When comparing the generated assembly the only difference is in the generated code for
bug()
For future reference, I examined tests from the gcc torture collection, and determined that only the few following tests (from 1930 tests) generate pre/post index code:
The commented out test crashes clang, as do many others.
So for some reason, the AVR pre/post index only is generated in a few cases, less then I would expect, but that is not related to this PR.
The reason why this PR is effective for the specific
bug()
code generation is not clear to me.The fix can be suboptimal, but it only removes a certain case of optimization which is incorrect for the
bug()
code, so there is minimal danger of a regression. I would really appreciate any feedback from experienced LLVM contributors about the root cause or alternative ways to handle the issue.