Fix optimizer bug that could limit certain address calculations to a 32k or 64k range even when using the large memory model.

This optimization could apply when indexing into an array whose elements are a power-of-2 size using a 16-bit index value. It is now only used when addressing arrays on the stack (which are necessarily smaller than 64k).

The following program demonstrates the problem:

#pragma optimize 1
#pragma memorymodel 1

long c[40000];

int main(void) {
    int i = 30000;
    c[30000] = 3;
    return c[i]; /* should return 3 */
}
This commit is contained in:
Stephen Heumann 2017-11-01 22:56:40 -05:00
parent e780043007
commit 730544a6ce

35
DAG.pas
View File

@ -806,23 +806,24 @@ case op^.opcode of {check for optimizations of this node}
if op^.right^.left^.opcode = pc_cnv then begin if op^.right^.left^.opcode = pc_cnv then begin
fromtype.i := (op^.right^.left^.q & $00F0) >> 4; fromtype.i := (op^.right^.left^.q & $00F0) >> 4;
if fromType.optype in [cgByte,cgUByte,cgWord,cgUWord] then if fromType.optype in [cgByte,cgUByte,cgWord,cgUWord] then
begin if op^.left^.opcode = pc_lda then
if fromType.optype = cgByte then begin
op^.right^.left^.q := $02 if fromType.optype = cgByte then
else if fromType.optype = cgUByte then op^.right^.left^.q := $02
op^.right^.left^.q := $13 else if fromType.optype = cgUByte then
else op^.right^.left^.q := $13
op^.right^.left := op^.right^.left^.left; else
with op^.right^.right^ do begin op^.right^.left := op^.right^.left^.left;
lq := lval; with op^.right^.right^ do begin
lval := 0; lq := lval;
q := long(lq).lsw; lval := 0;
optype := cgUWord; q := long(lq).lsw;
end; {with} optype := cgUWord;
op^.right^.opcode := pc_shl; end; {with}
op^.opcode := pc_ixa; op^.right^.opcode := pc_shl;
PeepHoleOptimization(opv); op^.opcode := pc_ixa;
end; {if} PeepHoleOptimization(opv);
end; {if}
end; {if} end; {if}
end {if} end {if}
else if op^.right^.opcode = pc_cnv then begin else if op^.right^.opcode = pc_cnv then begin