From 83537fd3c744dcf6af73475cc273a698ab5e2af9 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Sun, 17 Mar 2024 21:31:18 -0500 Subject: [PATCH] Disable a peephole optimization that can produce bad code. The optimization applies to code sequences like: dec abs lda abs beq ... where the dec and lda were supposed to refer to the same location. There were two problems with this optimization as written: -It considered the dec and lda to refer to the same location even if they were actually references to different elements of the same array. -It did not work in the case where the A register value was needed in subsequent code. The first of these was already an issue in previous ORCA/C releases, as in the following example: #pragma optimize -1 int x[2] = {0,0}; int main(void) { --x[0]; if (x[1] != 0) return 123; return 0; /* should return 0 */ } I do not believe the second problem was triggered by any code sequences generated in previous releases of ORCA/C, but it can be triggered after commit 4c402fc88, e.g. by the following example: #pragma optimize -1 int x = 1; int main(void) { int y = 123; --x; return x == 0; /* should return 1 */ } Since the circumstances where this peephole optimization was triggered validly are pretty obscure, just disabling it should have a minimal impact on the generated code. --- Native.pas | 7 ++++--- cc.notes | 2 ++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Native.pas b/Native.pas index 6dba273..faf3543 100644 --- a/Native.pas +++ b/Native.pas @@ -1720,11 +1720,12 @@ var Remove(ns+3); end; {if} - m_dec_abs: + {disabled - can generate bad code} + {m_dec_abs: if npeep[ns+1].opcode = m_lda_abs then if name^ = npeep[ns+1].name^ then if npeep[ns+2].opcode = m_beq then - Remove(ns+1); + Remove(ns+1);} m_lda_abs: if npeep[ns+1].opcode = m_clc then begin @@ -2657,7 +2658,7 @@ yRegister.condition := regUnknown; lastRegOpcode := 0; {BRK} nnextspot := 1; nleadOpcodes := [m_asl_a,m_bcc,m_bcs,m_beq,m_bmi,m_bne,m_bpl,m_brl,{m_bvs,} - m_dec_abs,m_lda_abs,m_lda_dir,m_lda_imm,m_ldx_imm,m_sta_abs,m_sta_dir, + {m_dec_abs,}m_lda_abs,m_lda_dir,m_lda_imm,m_ldx_imm,m_sta_abs,m_sta_dir, m_pha,m_plb,{m_plx,}m_tax,m_tya,m_tyx,m_phy,m_pei_dir,m_ldy_imm,m_rep, m_ora_dir,m_ora_abs,m_and_imm,m_pea,m_tcd]; nstopOpcodes := [d_end,d_pin]; diff --git a/cc.notes b/cc.notes index c5a9d35..b8b7c6c 100644 --- a/cc.notes +++ b/cc.notes @@ -1618,6 +1618,8 @@ If you use #pragma debug 0x0010 to enable stack check debug code, the compiler w 14. If a struct, union, or enum type name appeared within the third expression in a for loop statement (e.g. in a cast or as the argument to sizeof), ORCA/C could behave incorrectly. It could report a spurious error if a semicolon occurred within the type name as part of a structure or union member declaration. Also, any tags or enumeration constants declared by such a type name should be in scope within the loop body, but they were not. +15. Native code peephole optimization might produce invalid code in some obscure circumstances where one element of a global or static array was decremented and then another element of the same array was accessed immediately thereafter. + -- Bugs from C 2.1.1 B3 that have been fixed in C 2.2.0 --------------------- 1. There were various bugs that could cause incorrect code to be generated in certain cases. Some of these were specific to certain optimization passes, alone or in combination.