From 66e015f48cb09a72c21ac28a3b88eedf7a830c7a Mon Sep 17 00:00:00 2001 From: florian Date: Mon, 28 Jul 2008 15:51:58 +0000 Subject: [PATCH] * avoid shifter constant overflow on arm when optimizing two shifter operations into one git-svn-id: trunk@11474 - --- .gitattributes | 1 + compiler/arm/aoptcpu.pas | 20 ++++++++++++++++++++ tests/test/opt/tarmshift.pp | 12 ++++++++++++ 3 files changed, 33 insertions(+) create mode 100644 tests/test/opt/tarmshift.pp diff --git a/.gitattributes b/.gitattributes index 61eb6c2777..dca95ac956 100644 --- a/.gitattributes +++ b/.gitattributes @@ -7446,6 +7446,7 @@ tests/test/cg/variants/tvarol96.pp svneol=native#text/plain tests/test/dumpclass.pp svneol=native#text/plain tests/test/dumpmethods.pp svneol=native#text/plain tests/test/opt/README -text +tests/test/opt/tarmshift.pp svneol=native#text/plain tests/test/opt/tcaseopt1.pp svneol=native#text/plain tests/test/opt/tcmov.pp svneol=native#text/plain tests/test/opt/tcse1.pp svneol=native#text/plain diff --git a/compiler/arm/aoptcpu.pas b/compiler/arm/aoptcpu.pas index 42894fe21f..58ca12d154 100644 --- a/compiler/arm/aoptcpu.pas +++ b/compiler/arm/aoptcpu.pas @@ -40,6 +40,7 @@ Type Implementation uses + verbose, aasmbase,aasmcpu; function CanBeCond(p : tai) : boolean; @@ -51,6 +52,7 @@ Implementation function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean; var next1: tai; + hp1: tai; begin result := false; case p.typ of @@ -82,6 +84,24 @@ Implementation (taicpu(p).oper[2]^.shifterop^.shiftmode=taicpu(next1).oper[2]^.shifterop^.shiftmode) then begin inc(taicpu(p).oper[2]^.shifterop^.shiftimm,taicpu(next1).oper[2]^.shifterop^.shiftimm); + { avoid overflows } + if taicpu(p).oper[2]^.shifterop^.shiftimm>31 then + case taicpu(p).oper[2]^.shifterop^.shiftmode of + SM_ROR: + taicpu(p).oper[2]^.shifterop^.shiftimm:=taicpu(p).oper[2]^.shifterop^.shiftimm and 31; + SM_ASR: + taicpu(p).oper[2]^.shifterop^.shiftimm:=31; + SM_LSR, + SM_LSL: + begin + hp1:=taicpu.op_reg_const(A_MOV,taicpu(p).oper[0]^.reg,0); + InsertLLItem(p.previous, p.next, hp1); + p.free; + p:=hp1; + end; + else + internalerror(2008072803); + end; asml.remove(next1); next1.free; result := true; diff --git a/tests/test/opt/tarmshift.pp b/tests/test/opt/tarmshift.pp new file mode 100644 index 0000000000..2dec2b7a5f --- /dev/null +++ b/tests/test/opt/tarmshift.pp @@ -0,0 +1,12 @@ +{ %norun } +{ %opt=-O2 } +var + i : longint; + +begin + i:=1234; + i:=i shl 23; + i:=i shl 23; + if i<>0 then + halt(1); +end.