Open easyaspi314 opened 1 year ago
@llvm/issue-subscribers-backend-arm
This also happens with 64-bit arithmetic which is ridiculous, because there is only __aeabi_[u]ldivmod
and it is 100% redundant since either way you get a modulo
divmod64:
push {r4, r5, r6, r7, r11, lr}
mov r4, r3
mov r5, r2
mov r6, r1
mov r7, r0
bl __aeabi_uldivmod
umull r2, r3, r0, r5
mla r3, r0, r4, r3
ldr r4, [sp, #24]
subs r2, r7, r2
mla r3, r1, r5, r3
sbc r3, r6, r3
stm r4, {r0, r1, r2, r3}
pop {r4, r5, r6, r7, r11, pc}
Vs.
divmod64:
push {r4, lr}
bl __aeabi_uldivmod
ldr r4, [sp, #8]
stm r4, {r0, r1, r2, r3}
pop {r4, pc}
LLVM will always decompose
div
+rem
on ARM todiv
+mul
+sub
when optimizations are enabled.This makes sense on targets with division, but on targets without division it breaks the conversion to
__aeabi_[u]idivmod
:With
--target=armv5te-none-eabi -O0 -fomit-frame-pointer
:With
--target=armv5te-none-eabi -O3
:This is because llvm will "decompose" the div+rem into this:
If this optimization didn't occur it would emit something much cleaner, without spilling r0 and r1.
Additionally,
udiv+urem
without optimizations already generatesudiv+mls
on targets with idiv, so this optimization pass is detrimental either way unless it can be turned into shift+add (?)