Loads with pre-decrement and post-decrement indexing modes are lowered as pre-increment and post-increment loads on AArch64.
The decrement-semantics are ignored, which results in incorrect addressing.
Details
- Reviewers
efriedma
Diff Detail
Unit Tests
Time | Test | |
---|---|---|
60,060 ms | x64 debian > MLIR.Examples/standalone::test.toy |
Event Timeline
Here's a bit more context:
I have a sample, which, unfortunately, I am not able to disclose. In one basicblock, the following transformation is made in SelectionDAG:
What's essentially happening here is that the following expression:
t54 = t53 - 8 load(t54)
is transformed to:
load<pre-dec>(t53, 8). Due to the pre-dec indexing mode it seems like a valid transformation.
However, during instruction selection, the load is transformed like this:
LDRXpre(t53, 8) is selected which is then lowered to ldr x24, [x2, #8]!.
Essentially transforming the offset -8 into a +8. Which is simply wrong.
The reason is, as stated above, that dec indexing modes are not respected during instruction selection on AArch64.
Usually, patterns like this don't occur. The expression t54 = t53 - 8 is usually transformed to t54 = t53 + (-8) in prior optimization/transformation steps.
This can then be represented using increment indexing.
For unknown reasons, this is not the case with my sample.
Here is a drastically reduced version of the initial sample (which is still pretty big 🙁), that shows the issue: https://godbolt.org/z/sn5n9r96v One can see ldr x24, [x2, #8]! in line 65, which should instead be a -8.
However, the sample is highly sensitive to changes. The slightest adaptation will not trigger the bug anymore. Which is why I was not able to reduce it any further.
It is to note that switching to llc (trunk) yields the correct result. The reason for that is that the subtraction is previously transformed into an addtion, which is not represented as a decrement load anymore. Again, that is because the slightest change won't trigger the bug anymore.
This makes it extremely difficult to design a test case.
I tried reducing my initial sample as much as possible, however, the semantics in that godbolt snippet are meaningless and it is still way too big, which does not make for a good test, in my opinion.
Ontop of that, in my specific case, the issue does not occur anymore with the latest version of llc.
However, I still feel like the initial issue should be fixed, hence this commit.
I think with fb7c3807, we shouldn't use PRE_DEC/POST_DEC modes anymore. So IsDec will always be false, and this patch does nothing.
Ah man, ngl, that hurts. 3 days of straight debugging just to see this pattern cannot occur anymore. I guess it do be like that sometimes 😂 Still thank you though.