Skip to content

Arm64: In mod operation happening inside the loop, if divisor is an invariant, hoist the divisor checks #64795

Description

@kunalspathak

Arm64 doesn't have modulo operator, so we convert the operation to div/mul/sub format. However, we don't do much to the tree node until codegen where we generate code for it. During codegen, it is too late to know that divisor was invariant otherwise we can hoist some extra checks like divisor == 0 and divisor == -1.

In below example, when both dividend (x) and divisor (y) are invariant, we hoist the checks properly, but when dividend is not invariant (result) but divisor is invariant (y), we can hoist the checks out of the loop.

publicstaticintissue2(intx,inty,intz){intresult=0;for(inti=0;i<z;i++){//result = x % y; <-- this hoist things properly because both dividend and divisor are invariant.result=result%y;}returnresult;}
...G_M61875_IG03:cmp w0, #0 ; Check# 1 divisor == 0, can be hoisted  beq G_M61875_IG08 cmn w0, #1 ; Check# 2 divisor == -1, can be hoisted  bne G_M61875_IG04 adds wzr, w1, w1 bne G_M61875_IG04 bvs G_M61875_IG07 ;; bbWeight=4 PerfScore 22.00G_M61875_IG04: sdiv w4, w1, w0mul w4, w4, w0sub w1, w1, w4add w3, w3, #1cmp w3, w2 blt G_M61875_IG03 ;; bbWeight=4 PerfScore 62.00G_M61875_IG05:mov w0, w1 ;; bbWeight=1 PerfScore 0.50G_M61875_IG06: ldp fp, lr,[sp],#16ret lr ;; bbWeight=1 PerfScore 2.00G_M61875_IG07:bl CORINFO_HELP_OVERFLOW ;; bbWeight=0 PerfScore 0.00G_M61875_IG08:bl CORINFO_HELP_THROWDIVZERO brk_windows #0

category:cq
theme:div-mod-rem
skill-level:expert
cost:medium
impact:medium

Metadata

Metadata

Assignees

Labels

Priority:3Work that is nice to havearch-arm64area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMIin-prThere is an active PR which will close this issue when it is merged

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions