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 <stdio.h>

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. */
}
This commit is contained in:
Stephen Heumann 2016-10-19 18:49:37 -05:00
parent 45cc0a0721
commit efb23003f7

View File

@ -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