When pairing loads, we should check if in between the two loads the
base register has been modified. If that is the case then avoid pairing
them because the second load actually loads from a different address.
Details
Diff Detail
Event Timeline
Is it possible to add a MIR test for the issue? Also, it looks like the formatting is off a bit. Could you run clang-format-diff on the change?
Thanks! Regarding the MIR test: similar to the test file in the other patch https://reviews.llvm.org/D86906, the MIR test file for this patch is very lengthy (over 1000 lines). I'm wondering if it looks fine if I use that test file, or I could spend time trying to prune it, although I'm not optimistic how much it can be reduced.
Thanks for the comment, now fixed the code style and provided a test case which has already been reduced using creduce and llvm-reduce.
llvm/test/CodeGen/AArch64/aarch64-ldst-modified-baseReg.mir | ||
---|---|---|
18 | It might be good to have test cases with stores & non-load instructions modifying the base? |
llvm/test/CodeGen/AArch64/aarch64-ldst-modified-baseReg.mir | ||
---|---|---|
18 | Thanks for this comment, now added test cases where the base register or base address is modified with non-load instructions. ldr x9 [x10] ldr x10 [x8] ldr x10 [x10, 8]. For other instructions that modify the base register or base address with non-load instructions, the existing pass works correctly. The case that the base register is modified with non-load instructions is handled in lines 1626-1627 of the original AArch64 Load Store Optimization pass: if (!ModifiedRegUnits.available(BaseReg)) return E; Only when the pattern shown above occurs, this pass fails to handle it because it would hit a continue in the for-loop and would not reach lines 1626-1627. Still, I added these test cases where the base register or base address is modified with non-load instructions, but please note that these test cases already work correctly without the patch since the original AArch64 Load Store Optimization pass handles them well. I did not find similar tests in other test files that's why I added them, but maybe not adding them also makes sense. I'll appreciate it if you could let me know your thoughts. |
llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp | ||
---|---|---|
1580 | then *we* cannot do the optimization? | |
1586 | can we hoist the check outside of the containing if, i.e. to around line 1562? I think we should be able to bail out once the base reg is modified, because it won't get 'un-modified' so that should not rule out any valid pairs. Also, it is safer to do it earlier, otherwise we would need the check for each code path that returns a valid found pair (for example, we would probably also need it around line 1611) | |
llvm/test/CodeGen/AArch64/aarch64-ldst-modified-baseReg.mir | ||
4 | nit: spurious to, should that be tries to convert load instructions? | |
5 | a ldp instruction? | |
6 | convertion -> conversion? | |
18 | Thanks for adding those tests! Even though it is already handled correctly, adding a few additional tests here for completeness makes sense to me. |
LGTM, thanks!
llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp | ||
---|---|---|
1564 | nit: capitalize For. |
Thanks for all the comments, now addressed all of them @fhahn
llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp | ||
---|---|---|
1580 | Thanks, updated accordingly. | |
1586 | Now hoisted the check outside of the containing if. | |
llvm/test/CodeGen/AArch64/aarch64-ldst-modified-baseReg.mir | ||
6 | Thanks for the comments, revised accordingly. |
nit: capitalize For.