This tries to optimize the pattern "(a + b) + 1" and "(a - b) - 1".
In the case of genMinus we get the extra "-1" for free in many
cases by flipping the carry bit.
In the case of genPlus it requires switching the first add to
already use addc instead of just add and adding the SETC operation.
Since "SETB C" is a single byte while "ADD A, #1" is two bytes,
this is still a win (except when the register tracker has found an
existing #1 immediate so that "ADD A, Rn" can be used, then it
is a draw).
In the best case (multi-byte addition) we'll save several the
extra addition would have generated.
Further optimization would be supporting "(a + b) + bitvar" and
"(a - b) - bitvar", as well as supporting iCode variants like
"a + (b + 1)" or "1 + (a + b)".
A bit more reference on what I was trying to do:
generates
at first I tried modifying rtrack.c to keep track of value equality, and in genPlusIncr for a 16bit addition to use "rtrackRegEq(...)" to prefer "inc dptr/mov/mov" over "inc/cjne/inc", but this doesn't work because register tracking runs before peephole optimizations and any jumps clear the tracker, so it has its state cleared just before the genPlusIncr.
But then there already is special handling for (*(ptr++)), so we can write:
but this generates a seperate 16bit subtraction for the "- 1":
with the proposed change this becomes the more optimized:
I should try if this can be handled by a peephole rule instead, speaking of which it would be nice if the temporary to dptr and dptr to temporary copies could be hoisted out of the loop...
And yes, both can with --peep-file containing:
the generated code becomes:
Last edit: Tobias Diedrich 2026-03-03
On the note of peephole rules, I think rule 131 is unsafe?
AFAICS these are only identical if carry is unset at the beginning, and differ when carry is set.
Maybe this was intended to be:
Do you have a C code sample that can reproduce incorrect optimizations with this rule?
No, I just randomly noticed this while looking for existing add/sub-related peephole rules. I had a quick look how old this rule is and it's been there for over 20 years, so its probably safe. Possibly the compiler will just never generate instructions that would trigger the false-positive case.
[edit]Rule 131 goes back all the way to https://sourceforge.net/p/sdcc/code/3/[/edit]
Last edit: Tobias Diedrich 5 days ago
Looking through mcs51/gen.c I don't think this pattern is generated anymore.
Grep through the regression test results I don't see a single hit on "Peephole 131" either, so this is probably an unused rule nowadays...
Optimized strlen peephole rules:
generates:
Last edit: Tobias Diedrich 2026-03-03
Which of these rules are general enough to apply to code other than your own strlen variant? Did you try them on the regression tests?
Grepping over the regression test:
[edit]Some regressions found compared to unmodified baseline, need to check where the
mov , dplcorruption is coming from...Unfortunately
notSame(%1, '')is not accepted, so for now I fixed it by duplicating the rule, so the degenerate case is consumed first by the earlier more specific rule:[/edit]
Last edit: Tobias Diedrich 5 days ago
That said, sampling the hits it is often only a change with no further effect (no change in size or speed).
But it has some successes, for example in
support/regression/gen/mcs51-medium/rotate2/rotate2_size_16_andCase_1_xorLiteral_1_rotateLeft_0_structVar_0.asm:Last edit: Tobias Diedrich 5 days ago
So 468 bytes saved over all testcases?
Last edit: Tobias Diedrich 5 days ago
Not yet, will try to do that on the weekend. Any tips? Presumably all I need to run them is
make -C support/regression test-mcs51? How long is the run expected to take on a gen2 ryzen?Of course there were some bugs, but the regression test is passing now.
76397798-76397020 => 778 bytes saved across (duplicated per model) test code.
Hits for "folding post-decrement":
Hits for "folding post-increment":
Additionally the "increment by 0" optimization path triggers in some array access cases even without folding.
I also have a patch for the "need pointerCode" assert, as attached.