source:
_Bool bar2(void)
{
_Bool foo[2] = {1, 2};
return foo[1]; // Crashed sdcc.
}
Result assembler (no-peep, i-code-in-asm):
; Stack space usage: 2 bytes.
_bar2::
ld a, #3
rst 0x08
add sp, #-2
;gen/ucgbz80/bug2942247/bug2942247.c:19: _Bool foo[2] = {1, 2};
;ic:4: arrayInit iTemp1 [k4 lr3:3 so:0]{ ia0 a2p0 re0 rm0 nos0 ru0 dp0}{_Bool near* fixed}
; genArrayInit
;fetchPairLong
ld e, a
ld d, a
call __initrleblock
.db #2
.db #0x01, #0x01
.db #0
Here DE is loaded from A register which has gabarge.
Fo me that tests does not fail reliably (though I've seen teh failure before). The attached test should be a reliable reproducer.
This problem happens in an optimization, as can be seen from --dump-i-code:
The dumplood code still looks correct, but the dumplospre one doesn't.
However, it is not lospre that is at fault here, as --nolospre is not a workround for this bug.
That leaves the four minor optimizations done just before lospre:
optimizeOpWidth, optimizeCastCast, iCodeLabelOptimize, shortenLiveRanges.
Apparently the problem is related to offsetFoldGet. If I comment out the call to offsetFoldGet in eBBlockFromiCode, the bug disappears.
P.S.: Looks like this is due to offsetFoldGet is getting wrong information from an earlier analysis, as at offsetFoldGet OP_USES for the ADDRESS_OF does not include the ARRAYINIT iCode.
Last edit: Philipp Klaus Krause 2020-11-03
I'm not familiar with the parts of SDCC that set OP_USES, so I hope someone else can have a look at this issue in the arrayinit branch.
Last edit: Philipp Klaus Krause 2020-11-03
Apart from the bug, using an __initrleblock support call to initialize an array of total size 16 bits also seems quite inefficient.
agree. there are much of improvements to this part of code, but I have not sufficient experience to do it.
i think that __initrleblock simply can be switched for objects bigger than 4 bytes.
In [r11936], I made the use of RLE depend on array size and array element size.
isn't that function optimized to
ld e, #1when __initrleblock is disabled?Fixed by reverting compressed array initalization support in trunk.
Bug is not fixed. It just hidden, because bug in another place not in AI. AI support just activates it.
As far as I know, the bug is specific to the ARRAYINIT iCode. The ARRAYINIT iCode is used only if compressed array initalization is enabled. So disabling the compressed array initalization in trunk fixes the bug (as no trunk user would be exposed to it).
I set the state to pending-fixed, since the bug is fixed (by disabling compressed array initialization) in trunk, but we can still use the bug report to track the bug in the arrayinit branch.
that RLE initializer correctly inits arrays when using {0}, while current one initializes only the first element.