From 5670a7543cb170889fee2f3e8e65ccfd96c0b18e Mon Sep 17 00:00:00 2001 From: florian Date: Sun, 16 Oct 2022 22:51:50 +0200 Subject: [PATCH] * properly reset nf_write/nf_modify flags for min/max inline nodes, needed by dead store optimization, resolves #39958 * factored out nutils.node_reset_pass1_write --- compiler/nflw.pas | 1 + compiler/ninl.pas | 17 ++--------------- compiler/nutils.pas | 25 +++++++++++++++++++++++++ tests/webtbs/tw39958.pp | 17 +++++++++++++++++ 4 files changed, 45 insertions(+), 15 deletions(-) create mode 100644 tests/webtbs/tw39958.pp diff --git a/compiler/nflw.pas b/compiler/nflw.pas index 4a481696af..1ee8a8c0d5 100644 --- a/compiler/nflw.pas +++ b/compiler/nflw.pas @@ -1707,6 +1707,7 @@ implementation cinlinenode.create(in_nr,false,ccallparanode.create(tassignmentnode(elsestmnt).right.getcopy, ccallparanode.create(tassignmentnode(thenstmnt).right.getcopy,nil))) ); + node_reset_pass1_write(Result); end; {$endif defined(i386) or defined(x86_64) or defined(xtensa) or defined(aarch64)} {$endif llvm} diff --git a/compiler/ninl.pas b/compiler/ninl.pas index 8be3c590f6..cd47ee2d74 100644 --- a/compiler/ninl.pas +++ b/compiler/ninl.pas @@ -4558,6 +4558,7 @@ implementation temp_pnode^ := nil; end; + function tinlinenode.first_abs_long : tnode; begin expectloc:=LOC_REGISTER; @@ -4565,20 +4566,6 @@ implementation end; - function node_reset_pass1_write(var n: tnode; arg: pointer): foreachnoderesult; - begin - Result := fen_false; - n.flags := n.flags - [nf_pass1_done,nf_write,nf_modify]; - if n.nodetype = assignn then - begin - { Force re-evaluation of assignments so nf_modify and nf_write - flags are correctly set. } - n.resultdef := nil; - Result := fen_true; - end; - end; - - function tinlinenode.getaddsub_for_incdec : tnode; var hp,hpp,resultnode : tnode; @@ -4680,7 +4667,7 @@ implementation { force pass 1, so copied trees get first pass'ed as well and flags like nf_call_unique get set right } - foreachnodestatic(hpp,@node_reset_pass1_write,nil); + node_reset_pass1_write(hpp); do_typecheckpass(hpp); addstatement(newstatement,cassignmentnode.create(resultnode,hpp)); diff --git a/compiler/nutils.pas b/compiler/nutils.pas index d7c27db24a..ba69b3c390 100644 --- a/compiler/nutils.pas +++ b/compiler/nutils.pas @@ -201,6 +201,10 @@ interface } function MatchAndTransformNodesCommutative(n1,n2,n3,n4 : tnode;matchproc : TMatchProc4;transformproc : TTransformProc4;var res : tnode) : Boolean; + { + resets all flags so that nf_write/nf_modify information is regenerated + } + procedure node_reset_pass1_write(n: tnode); implementation @@ -1693,4 +1697,25 @@ implementation result:=false; end; + + function _node_reset_pass1_write(var n: tnode; arg: pointer): foreachnoderesult; + begin + Result := fen_false; + n.flags := n.flags - [nf_pass1_done,nf_write,nf_modify]; + if n.nodetype = assignn then + begin + { Force re-evaluation of assignments so nf_modify and nf_write + flags are correctly set. } + n.resultdef := nil; + Result := fen_true; + end; + end; + + + procedure node_reset_pass1_write(n: tnode); + begin + foreachnodestatic(n,@_node_reset_pass1_write,nil); + end; + + end. diff --git a/tests/webtbs/tw39958.pp b/tests/webtbs/tw39958.pp new file mode 100644 index 0000000000..22273698a1 --- /dev/null +++ b/tests/webtbs/tw39958.pp @@ -0,0 +1,17 @@ +{ %opt=-O4 -Oodeadstore} +var + data: array[0 .. 1] of single = (8, 7); + minData, maxData: single; + +begin + minData := data[0]; + maxData := data[0]; + if data[1] < minData then minData := data[1]; + if data[1] > maxData then maxData := data[1]; + writeln('min = ', minData:0:2, ' (must be 7), max = ', maxData:0:2, ' (must be 8).'); + if minData<>7 then + halt(1); + if maxData<>8 then + halt(1); + writeln('ok'); +end.