Merge pull request #2938 from kugelfuhr/kugelfuhr/fix-2811

Fix an invalid transformation by the optimizer
This commit is contained in:
Bob Andrews
2026-03-05 19:51:51 +01:00
committed by GitHub
2 changed files with 37 additions and 7 deletions

View File

@@ -1213,21 +1213,24 @@ unsigned OptTosPushPop (CodeSeg* S)
/* Get the next entry */
const CodeEntry* E = CS_GetEntry (S, I);
/* Check for decspn, incspn, subysp or addysp */
/* Check for pushax/popax */
if (CE_IsCallTo (E, "pushax") &&
(N = CS_GetNextEntry (S, I)) != 0 &&
(CE_IsCallTo (N, "popax") || CE_IsJumpTo (N, "popax")) &&
!CE_HasLabel (N)) {
/* Insert an rts if jmp popax */
if (N->OPC == OP65_JMP) {
CodeEntry* X = NewCodeEntry (OP65_RTS, AM65_IMP, 0, 0, E->LI);
CS_InsertEntry (S, X, I);
/* If we jumped to popax instead of calling it as a subroutine,
** add an RTS before removing the sequence.
*/
CodeEntry* X = NewCodeEntry (OP65_RTS, AM65_IMP, 0, 0, E->LI);
CS_InsertEntry (S, X, I);
CS_DelEntries (S, I+1, 2);
} else {
/* Otherwise just remove the sequence */
CS_DelEntries (S, I, 2);
}
/* Delete the old code */
CS_DelEntries (S, I+1, 2);
/* Remember we had changes */
++Changes;

27
test/val/bug2811.c Normal file
View File

@@ -0,0 +1,27 @@
/* Note: This test is rather fragile since it depends on how the compiler
** handles certain sequences and return codes. It checks for exactly one
** optimizer problem introduced in #2811. If it fails in some future version,
** do not hesitate to remove it.
*/
#include <stdio.h>
static unsigned char test(unsigned v)
{
(void)v;
asm("jsr popax");
asm("lda #0");
return __A__;
}
int main(void)
{
if (test(1)) {
printf("Test failed\n");
return 1;
} else {
printf("Test ok\n");
return 0;
}
}