From efb23003f7c5c151646809f2a10c6fa9a703c1b8 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Wed, 19 Oct 2016 18:49:37 -0500 Subject: [PATCH] Don't do an optimization that would move a store to a DP location above an indirect load using that DP location. This generated invalid code in instances like the following. The code generated for "s = s->u.next" would update the most significant word of s first, then use an indirect load with the half-updated pointer value to update the least significant word of s. This would generally corrupt the result if the new and old pointers had different bank bytes. #pragma optimize 79 #include struct S { int i; union { struct S * next; } u; } s1 = {0, 0}; int main (void) { struct S * s = &s1; s = s->u.next; if (s != 0) puts("compiler bug detected\n"); /* May not always be triggered, depending on memory contents. */ } --- Native.pas | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Native.pas b/Native.pas index 1e639f7..a87b134 100644 --- a/Native.pas +++ b/Native.pas @@ -1674,11 +1674,14 @@ var else if npeep[ns+1].opcode = m_dey then if npeep[ns+2].opcode = m_dey then if npeep[ns+3].opcode = m_lda_indly then - if npeep[ns+4].opcode = m_stx_dir then begin - npeep[ns] := npeep[ns+4]; - opcode := m_sta_dir; - Remove(ns+4); - end; {if} + if npeep[ns+4].opcode = m_stx_dir then + if (npeep[ns+4].operand - npeep[ns+3].operand < -1) + or (npeep[ns+4].operand - npeep[ns+3].operand > 2) + then begin + npeep[ns] := npeep[ns+4]; + opcode := m_sta_dir; + Remove(ns+4); + end; {if} m_tya: if npeep[ns+1].opcode = m_sta_dir then begin