seems like modulo optimization (on powers of two) regression starting somewhere after 3.6.3 #9771
observed behavior:
simple modulo patterns using constant base-2 divisor are using modsint? internal routines
expected behavior:
modulo patterns using a constant base-2 divisor should be using the optimized AND-bitmask pattern
examples:
previous version of sdcc (3.6.3 #9771):
; src/main.c:382: if ((count % 4) == 0) {
mov a,_count
anl a,#0x03
jnz 00107$
newer version of sdcc (sdcc 3.8.1, #10620):
; src/main.c:382: if ((count % 4) == 0) {
mov r5,_count
mov r6,#0x00
mov __modsint_PARM_2,#0x04
; 1-genFromRTrack replaced mov (__modsint_PARM_2 + 1),#0x00
mov (__modsint_PARM_2 + 1),r6
mov dpl,r5
mov dph,r6
push ar7
lcall __modsint
mov a,dpl
mov b,dph
pop ar7
orl a,b
jnz 00107$
forgot to include here, "count" var is uint8_t. (Not sure if the optimization previously had a 16 bit variant or not)
and the same for stm8
Version 3.8.1 #10625 (MINGW32)
--opt-code-speed --max-allocs-per-node 100000
but the next "hint" helps compiler taking right decision:
Last edit: Nikolay 2018-10-20
Thanks Nikolay. The casting the constant trick is a good workaround.
This is not mcs51-specific. Interestingly.
still gets optimized, while
Doesn't.
Philipp
P.S.: Not that interesting after all. / gets optimized even for signed operands, and the optimized version is indeed the one for signed operands.
P.P.S.: The best solution would be to implement generalized constant propagation, so that such optimizations can be done depending on actual possible values, not types.
Last edit: Philipp Klaus Krause 2018-10-24
Partially fixed by Philipp in [r10643] and fully unregressed by my update in [r11622].