Uh oh!
There was an error while loading. Please reload this page.
JIT: "Scaled" addressing mode on ARM - #60808
Conversation
ghost
commented
Oct 24, 2021
Tagging subscribers to this area: @JulieLeeMSFT Issue DetailsAddressing modes on ARM are tricky, it only supports: while on x64 we can do things like Codegen improvement example: voidGetSet(int*data,inti,intj)=>data[i]=data[j];diff: ; Method Prog:GetSet(long,int,int):this
G_M13801_IG01:
stp fp, lr, [sp,#-16]!
mov fp, sp
G_M13801_IG02:
sxtw x0, w3
- lsl x0, x0, #2- ldr w0, [x1, x0]+ ldr w0, [x1, x0, LSL #2]
sxtw x2, w2
- lsl x2, x2, #2- str w0, [x1, x2]+ str w0, [x1, x2, LSL #2]
G_M13801_IG03:
ldp fp, lr, [sp],#16
ret lr
; Total bytes of code: 40Also, I removed coreclr_tests.pmi.Linux.arm64.checked.mch:Detail diffslibraries.crossgen2.Linux.arm64.checked.mch:Detail diffslibraries.pmi.Linux.arm64.checked.mch:Detail diffslibraries_tests.pmi.Linux.arm64.checked.mch:Detail diffsI have a more complicated improvement with bigger diffs but it's not ready yet.
|
It doesn't handle "array access via index" yet, e.g.: inta=array[i];// int[] array, int icurrently emits: mov w1, w1lsl x1, x1, #2add x1, x1, #16ldr w0,[x0, x1]while could be: add x8, x0, w1, uxtw #2ldr w0,[x8, #16] |
EgorBo
commented
Oct 24, 2021
/azp run runtime-coreclr jitstressregs, runtime-coreclr outerloop, runtime-coreclr jitstress2-jitstressregs, runtime-coreclr gcstress0x3-gcstress0xc |
|
Azure Pipelines successfully started running 4 pipeline(s). |
EgorBo
commented
Oct 25, 2021
PTAL @dotnet/jit-contrib |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
| assert(op1 != op1Save); | ||
| assert(op2 != nullptr); | ||
| #if defined(TARGET_XARCH) |
There was a problem hiding this comment.
Can you add a comment here explaining why arm64 doesn't/shouldn't do this walk?
| #ifdef TARGET_ARMARCH | ||
| if ((scale > 0) && (genTypeSize(targetType) != scale)) | ||
| { | ||
| return false; |
There was a problem hiding this comment.
Are there cases now where we look for and find a scale, but it is not the appropriate number, and so we bail out on creating an addressing mode that we would previously find?
There was a problem hiding this comment.
Example: https://godbolt.org/z/xG4TsYYTG - in case of Test2 we bail out
There was a problem hiding this comment.
Ok, but in that case we would also bail out in the baseline as well as with this change, right?
There was a problem hiding this comment.
From my understanding genCreateAddrMode is called from two places (gtSetEvalOrder and in Lower) and these checks are needed in both otherwise it leads to asserts.
EgorBo
commented
Oct 28, 2021
@BruceForstall could you please take a look one more time? |
BruceForstall
left a comment
There was a problem hiding this comment.
LGTM
Long-term, I'm worried about one comment you added:
"For now we only handle MUL and LSH because
arm doesn't support both scale and offset at the same. Offset is handled
at the emitter as a peephole optimization."
There's been controversy over the years about what GenTreeAddrMode should represent; it is a fully general x86 addressing mode, as the comments seem to indicate? Or is it "target-specific" as the comments also say? Should it be extended to include the arm64 "sxt/uxt" shifters, for arm? It seems like handling "offset as a peephole optimization" is the wrong place for that; the full address mode should be properly represented in the GenTree.
BruceForstall
commented
Oct 28, 2021
Also, can you verify there are no spmi asm diffs on x86/x64? |
EgorBo
commented
Oct 29, 2021
Just checked, no diffs.
I agree, I want to try to refactor it as it looks like a proper fix here will have ~200kb diffs on arm64 (for many indirect loads we emit up to 4 instructions where we could do it in 1 or 2), this PR was just a low-hanging fruit. |
krwq
commented
Nov 2, 2021
@EgorBo I think this has regressed rolling builds. See i.e.: essentially every rolling build since then is consistently failing with that assert. If fix is unclear please consider temporarily reverting. Note: I'm not 100% sure this PR is responsible but looking at the list of commits: https://dev.azure.com/dnceng/public/_traceability/runview/changes?currentRunId=1446655 this looks most probable. |
improvements in linux-arm64 dotnet/perf-autofiling-issues#2148 and dotnet/perf-autofiling-issues#2141 and dotnet/perf-autofiling-issues#2253 |
Addressing modes on ARM are tricky, it only supports:
while on x64 we can do things like
[reg1 + 8 * reg2 + icon]Codegen improvement example:
diff:
Also, I removed
SCALED_ADDR_MODES- it's always defined for all targets and I don't think it simplifies porting to new platforms as before this PR this flag was set but scaled addr modes were disabled anyway.coreclr_tests.pmi.Linux.arm64.checked.mch:
Detail diffs
libraries.crossgen2.Linux.arm64.checked.mch:
Detail diffs
libraries.pmi.Linux.arm64.checked.mch:
Detail diffs
libraries_tests.pmi.Linux.arm64.checked.mch:
Detail diffs
I have a more complicated improvement with bigger diffs but it's not ready yet (see #60813 (comment))