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
Arm64 doesn't have
modulooperator, so we convert the operation todiv/mul/subformat. 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 thatdivisorwas invariant otherwise we can hoist some extra checks likedivisor == 0anddivisor == -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.category:cq
theme:div-mod-rem
skill-level:expert
cost:medium
impact:medium