Explorar o código

* factored out the conditions under which add nodes need to perform
overflow checks
o in particular ensure that cpu-specific overrides don't perform overflow
checks when nf_internal is set

git-svn-id: trunk@42573 -

Jonas Maebe %!s(int64=6) %!d(string=hai) anos
pai
achega
ce598c15ec

+ 1 - 0
.gitattributes

@@ -12926,6 +12926,7 @@ tests/tbs/tb0654.pp svneol=native#text/plain
 tests/tbs/tb0655.pp svneol=native#text/pascal
 tests/tbs/tb0655.pp svneol=native#text/pascal
 tests/tbs/tb0656.pp svneol=native#text/pascal
 tests/tbs/tb0656.pp svneol=native#text/pascal
 tests/tbs/tb0657.pp svneol=native#text/pascal
 tests/tbs/tb0657.pp svneol=native#text/pascal
+tests/tbs/tb0658.pp svneol=native#text/plain
 tests/tbs/tb205.pp svneol=native#text/plain
 tests/tbs/tb205.pp svneol=native#text/plain
 tests/tbs/tb610.pp svneol=native#text/pascal
 tests/tbs/tb610.pp svneol=native#text/pascal
 tests/tbs/tb613.pp svneol=native#text/plain
 tests/tbs/tb613.pp svneol=native#text/plain

+ 1 - 1
compiler/arm/narmadd.pas

@@ -728,7 +728,7 @@ interface
       begin
       begin
         result:=GenerateThumbCode or
         result:=GenerateThumbCode or
           not(CPUARM_HAS_UMULL in cpu_capabilities[current_settings.cputype]) or
           not(CPUARM_HAS_UMULL in cpu_capabilities[current_settings.cputype]) or
-          (cs_check_overflow in current_settings.localswitches);
+          needoverflowcheck;
       end;
       end;
 
 
 begin
 begin

+ 4 - 4
compiler/i386/n386add.pas

@@ -64,7 +64,7 @@ interface
 
 
     function ti386addnode.use_generic_mul64bit: boolean;
     function ti386addnode.use_generic_mul64bit: boolean;
     begin
     begin
-      result:=(cs_check_overflow in current_settings.localswitches) or
+      result:=needoverflowcheck or
         (cs_opt_size in current_settings.optimizerswitches);
         (cs_opt_size in current_settings.optimizerswitches);
     end;
     end;
 
 
@@ -78,7 +78,7 @@ interface
                 not(is_signed(right.resultdef));
                 not(is_signed(right.resultdef));
       { use IMUL instead of MUL in case overflow checking is off and we're
       { use IMUL instead of MUL in case overflow checking is off and we're
         doing a 32->32-bit multiplication }
         doing a 32->32-bit multiplication }
-      if not (cs_check_overflow in current_settings.localswitches) and
+      if not needoverflowcheck and
          not is_64bit(resultdef) then
          not is_64bit(resultdef) then
         unsigned:=false;
         unsigned:=false;
       if (nodetype=muln) and (unsigned or is_64bit(resultdef)) then
       if (nodetype=muln) and (unsigned or is_64bit(resultdef)) then
@@ -213,7 +213,7 @@ interface
         { is in unsigned VAR!!                              }
         { is in unsigned VAR!!                              }
         if mboverflow then
         if mboverflow then
          begin
          begin
-           if cs_check_overflow in current_settings.localswitches  then
+           if needoverflowcheck then
             begin
             begin
               current_asmdata.getjumplabel(hl4);
               current_asmdata.getjumplabel(hl4);
               if unsigned then
               if unsigned then
@@ -487,7 +487,7 @@ interface
         emit_ref(asmops[unsigned],S_L,ref)
         emit_ref(asmops[unsigned],S_L,ref)
       else
       else
         emit_reg(asmops[unsigned],S_L,reg);
         emit_reg(asmops[unsigned],S_L,reg);
-      if (cs_check_overflow in current_settings.localswitches) and
+      if needoverflowcheck and
         { 32->64 bit cannot overflow }
         { 32->64 bit cannot overflow }
         (not is_64bit(resultdef)) then
         (not is_64bit(resultdef)) then
         begin
         begin

+ 6 - 3
compiler/i8086/n8086add.pas

@@ -315,7 +315,7 @@ interface
         { is in unsigned VAR!!                              }
         { is in unsigned VAR!!                              }
         if mboverflow then
         if mboverflow then
          begin
          begin
-           if cs_check_overflow in current_settings.localswitches  then
+           if needoverflowcheck then
             begin
             begin
               current_asmdata.getjumplabel(hl4);
               current_asmdata.getjumplabel(hl4);
               if unsigned then
               if unsigned then
@@ -1002,6 +1002,7 @@ interface
         ref:Treference;
         ref:Treference;
         use_ref:boolean;
         use_ref:boolean;
         hl4 : tasmlabel;
         hl4 : tasmlabel;
+        overflowcheck: boolean;
 
 
     const
     const
       asmops: array[boolean] of tasmop = (A_IMUL, A_MUL);
       asmops: array[boolean] of tasmop = (A_IMUL, A_MUL);
@@ -1012,10 +1013,12 @@ interface
 
 
       pass_left_right;
       pass_left_right;
 
 
+      overflowcheck:=needoverflowcheck;
+
       { MUL is faster than IMUL on the 8086 & 8088 (and equal in speed on 286+),
       { MUL is faster than IMUL on the 8086 & 8088 (and equal in speed on 286+),
         but it's only safe to use in place of IMUL when overflow checking is off
         but it's only safe to use in place of IMUL when overflow checking is off
         and we're doing a 16-bit>16-bit multiplication }
         and we're doing a 16-bit>16-bit multiplication }
-      if not (cs_check_overflow in current_settings.localswitches) and
+      if not overflowcheck and
         (not is_32bitint(resultdef)) then
         (not is_32bitint(resultdef)) then
         unsigned:=true;
         unsigned:=true;
 
 
@@ -1048,7 +1051,7 @@ interface
         emit_ref(asmops[unsigned],S_W,ref)
         emit_ref(asmops[unsigned],S_W,ref)
       else
       else
         emit_reg(asmops[unsigned],S_W,reg);
         emit_reg(asmops[unsigned],S_W,reg);
-      if (cs_check_overflow in current_settings.localswitches) and
+      if overflowcheck and
         { 16->32 bit cannot overflow }
         { 16->32 bit cannot overflow }
         (not is_32bitint(resultdef)) then
         (not is_32bitint(resultdef)) then
         begin
         begin

+ 2 - 4
compiler/m68k/n68kadd.pas

@@ -399,9 +399,7 @@ implementation
       begin
       begin
         { if we need to handle overflow checking, fall back to the generic cg }
         { if we need to handle overflow checking, fall back to the generic cg }
         if (nodetype in [addn,subn,muln]) and
         if (nodetype in [addn,subn,muln]) and
-           (left.resultdef.typ<>pointerdef) and
-           (right.resultdef.typ<>pointerdef) and
-           (cs_check_overflow in current_settings.localswitches) then
+           needoverflowcheck then
           begin
           begin
             inherited;
             inherited;
             exit;
             exit;
@@ -609,7 +607,7 @@ implementation
 
 
     function t68kaddnode.use_generic_mul64bit: boolean;
     function t68kaddnode.use_generic_mul64bit: boolean;
     begin
     begin
-      result:=(cs_check_overflow in current_settings.localswitches) or
+      result:=needoverflowcheck  or
         (cs_opt_size in current_settings.optimizerswitches) or
         (cs_opt_size in current_settings.optimizerswitches) or
         not (CPUM68K_HAS_64BITMUL in cpu_capabilities[current_settings.cputype]);
         not (CPUM68K_HAS_64BITMUL in cpu_capabilities[current_settings.cputype]);
     end;
     end;

+ 1 - 1
compiler/mips/ncpuadd.pas

@@ -426,7 +426,7 @@ end;
 
 
 function tmipsaddnode.use_generic_mul64bit: boolean;
 function tmipsaddnode.use_generic_mul64bit: boolean;
 begin
 begin
-  result:=(cs_check_overflow in current_settings.localswitches) or
+  result:=needoverflowcheck or
     (not (CPUMIPS_HAS_ISA32R2 in cpu_capabilities[current_settings.cputype]));
     (not (CPUMIPS_HAS_ISA32R2 in cpu_capabilities[current_settings.cputype]));
 end;
 end;
 
 

+ 12 - 3
compiler/ncgadd.pas

@@ -66,6 +66,8 @@ interface
           procedure second_cmpsmallset;virtual;abstract;
           procedure second_cmpsmallset;virtual;abstract;
           procedure second_cmp64bit;virtual;abstract;
           procedure second_cmp64bit;virtual;abstract;
           procedure second_cmpordinal;virtual;abstract;
           procedure second_cmpordinal;virtual;abstract;
+
+          function needoverflowcheck: boolean;
        end;
        end;
 
 
   implementation
   implementation
@@ -518,9 +520,7 @@ interface
 
 
         checkoverflow:=
         checkoverflow:=
           checkoverflow and
           checkoverflow and
-          (left.resultdef.typ<>pointerdef) and
-          (right.resultdef.typ<>pointerdef) and
-          (cs_check_overflow in current_settings.localswitches) and not(nf_internal in flags);
+          needoverflowcheck;
 
 
 {$if defined(cpu64bitalu) or defined(cpuhighleveltarget)}
 {$if defined(cpu64bitalu) or defined(cpuhighleveltarget)}
         case nodetype of
         case nodetype of
@@ -763,6 +763,15 @@ interface
         second_cmpordinal;
         second_cmpordinal;
       end;
       end;
 
 
+    function tcgaddnode.needoverflowcheck: boolean;
+      begin
+        result:=
+          (cs_check_overflow in current_settings.localswitches) and
+          (left.resultdef.typ<>pointerdef) and
+          (right.resultdef.typ<>pointerdef) and
+          not(nf_internal in flags);
+      end;
+
 
 
 {*****************************************************************************
 {*****************************************************************************
                                 pass_generate_code;
                                 pass_generate_code;

+ 4 - 7
compiler/powerpc/nppcadd.pas

@@ -325,11 +325,10 @@ interface
             current_asmdata.getjumplabel(falselabel);
             current_asmdata.getjumplabel(falselabel);
           end;
           end;
 
 
-        load_left_right(cmpop,((cs_check_overflow in current_settings.localswitches) and
-            (nodetype in [addn,subn])) or (nodetype = muln));
+        load_left_right(cmpop,needoverflowcheck or (nodetype = muln));
 
 
-        if (nodetype <> muln) and
-           (not(cs_check_overflow in current_settings.localswitches) or
+        if (nodetype<>muln) and
+           (not needoverflowcheck or
             not(nodetype in [addn,subn])) then
             not(nodetype in [addn,subn])) then
           begin
           begin
             case nodetype of
             case nodetype of
@@ -657,9 +656,7 @@ interface
 
 
          checkoverflow:=
          checkoverflow:=
            (nodetype in [addn,subn,muln]) and
            (nodetype in [addn,subn,muln]) and
-           (cs_check_overflow in current_settings.localswitches) and
-           (left.resultdef.typ<>pointerdef) and
-           (right.resultdef.typ<>pointerdef);
+           needoverflowcheck;
 
 
          load_left_right(cmpop, checkoverflow);
          load_left_right(cmpop, checkoverflow);
 
 

+ 1 - 5
compiler/powerpc64/nppcadd.pas

@@ -219,11 +219,7 @@ begin
   else
   else
     location_reset(location, LOC_FLAGS, OS_NO);
     location_reset(location, LOC_FLAGS, OS_NO);
 
 
-  checkoverflow:=
-    (nodetype in [addn,subn,muln]) and
-    (cs_check_overflow in current_settings.localswitches) and
-    (left.resultdef.typ<>pointerdef) and
-    (right.resultdef.typ<>pointerdef);
+  checkoverflow:=needoverflowcheck;
 
 
   load_left_right(cmpop, checkoverflow);
   load_left_right(cmpop, checkoverflow);
 
 

+ 1 - 1
compiler/sparcgen/ncpuadd.pas

@@ -505,7 +505,7 @@ interface
     function tsparcaddnode.use_generic_mul64bit: boolean;
     function tsparcaddnode.use_generic_mul64bit: boolean;
       begin
       begin
 {$ifdef SPARC64}
 {$ifdef SPARC64}
-        result:=(cs_check_overflow in current_settings.localswitches);
+        result:=needoverflowcheck;
 {$else SPARC64}
 {$else SPARC64}
         result:=inherited;
         result:=inherited;
 {$endif SPARC64}
 {$endif SPARC64}

+ 8 - 8
compiler/x86/nx86add.pas

@@ -93,7 +93,9 @@ unit nx86add;
         hl4   : tasmlabel;
         hl4   : tasmlabel;
         r     : Tregister;
         r     : Tregister;
         href  : treference;
         href  : treference;
+        overflowcheck: boolean;
       begin
       begin
+        overflowcheck:=needoverflowcheck;
         { at this point, left.location.loc should be LOC_REGISTER }
         { at this point, left.location.loc should be LOC_REGISTER }
         if right.location.loc=LOC_REGISTER then
         if right.location.loc=LOC_REGISTER then
          begin
          begin
@@ -152,7 +154,7 @@ unit nx86add;
                  if (op=A_ADD) and
                  if (op=A_ADD) and
                     (right.location.loc=LOC_CONSTANT) and
                     (right.location.loc=LOC_CONSTANT) and
                     (right.location.value=1) and
                     (right.location.value=1) and
-                    not(cs_check_overflow in current_settings.localswitches) and
+                    not overflowcheck and
                     UseIncDec then
                     UseIncDec then
                   begin
                   begin
                     emit_reg(A_INC,TCGSize2Opsize[opsize],left.location.register);
                     emit_reg(A_INC,TCGSize2Opsize[opsize],left.location.register);
@@ -161,7 +163,7 @@ unit nx86add;
                  if (op=A_SUB) and
                  if (op=A_SUB) and
                     (right.location.loc=LOC_CONSTANT) and
                     (right.location.loc=LOC_CONSTANT) and
                     (right.location.value=1) and
                     (right.location.value=1) and
-                    not(cs_check_overflow in current_settings.localswitches) and
+                    overflowcheck and
                     UseIncDec then
                     UseIncDec then
                   begin
                   begin
                     emit_reg(A_DEC,TCGSize2Opsize[opsize],left.location.register);
                     emit_reg(A_DEC,TCGSize2Opsize[opsize],left.location.register);
@@ -170,7 +172,7 @@ unit nx86add;
                  if (op=A_IMUL) and
                  if (op=A_IMUL) and
                     (right.location.loc=LOC_CONSTANT) and
                     (right.location.loc=LOC_CONSTANT) and
                     (ispowerof2(int64(right.location.value),power)) and
                     (ispowerof2(int64(right.location.value),power)) and
-                    not(cs_check_overflow in current_settings.localswitches) then
+                    overflowcheck then
                   begin
                   begin
                     emit_const_reg(A_SHL,TCGSize2Opsize[opsize],power,left.location.register);
                     emit_const_reg(A_SHL,TCGSize2Opsize[opsize],power,left.location.register);
                   end
                   end
@@ -178,7 +180,7 @@ unit nx86add;
                     (right.location.loc=LOC_CONSTANT) and
                     (right.location.loc=LOC_CONSTANT) and
                     (right.location.value>1) and (ispowerof2(int64(right.location.value)-1,power)) and
                     (right.location.value>1) and (ispowerof2(int64(right.location.value)-1,power)) and
                     (power in [1..3]) and
                     (power in [1..3]) and
-                    not(cs_check_overflow in current_settings.localswitches) then
+                    not overflowcheck then
                   begin
                   begin
                     reference_reset_base(href,left.location.register,0,ctempposinvalid,0,[]);
                     reference_reset_base(href,left.location.register,0,ctempposinvalid,0,[]);
                     href.index:=left.location.register;
                     href.index:=left.location.register;
@@ -209,7 +211,7 @@ unit nx86add;
         { is in unsigned VAR!!                                   }
         { is in unsigned VAR!!                                   }
         if mboverflow then
         if mboverflow then
          begin
          begin
-           if cs_check_overflow in current_settings.localswitches  then
+           if overflowcheck then
             begin
             begin
               current_asmdata.getjumplabel(hl4);
               current_asmdata.getjumplabel(hl4);
               if unsigned then
               if unsigned then
@@ -1466,9 +1468,7 @@ unit nx86add;
 
 
        checkoverflow:=
        checkoverflow:=
          checkoverflow and
          checkoverflow and
-          (left.resultdef.typ<>pointerdef) and
-          (right.resultdef.typ<>pointerdef) and
-          (cs_check_overflow in current_settings.localswitches);
+         needoverflowcheck;
 
 
        opsize:=def_cgsize(left.resultdef);
        opsize:=def_cgsize(left.resultdef);
 
 

+ 2 - 2
compiler/x86_64/nx64add.pas

@@ -52,7 +52,7 @@ interface
       { filter unsigned MUL opcode, which requires special handling.
       { filter unsigned MUL opcode, which requires special handling.
         Note that when overflow checking is off, we can use IMUL instead. }
         Note that when overflow checking is off, we can use IMUL instead. }
       if (nodetype=muln) and
       if (nodetype=muln) and
-        (cs_check_overflow in current_settings.localswitches) and
+        needoverflowcheck and
         (not(is_signed(left.resultdef)) or
         (not(is_signed(left.resultdef)) or
          not(is_signed(right.resultdef))) then
          not(is_signed(right.resultdef))) then
       begin
       begin
@@ -126,7 +126,7 @@ interface
           emit_ref(A_MUL,opsize,ref)
           emit_ref(A_MUL,opsize,ref)
         else
         else
           emit_reg(A_MUL,opsize,reg);
           emit_reg(A_MUL,opsize,reg);
-        if cs_check_overflow in current_settings.localswitches  then
+        if needoverflowcheck then
          begin
          begin
            current_asmdata.getjumplabel(hl4);
            current_asmdata.getjumplabel(hl4);
            cg.a_jmp_flags(current_asmdata.CurrAsmList,F_AE,hl4);
            cg.a_jmp_flags(current_asmdata.CurrAsmList,F_AE,hl4);

+ 11 - 0
tests/tbs/tb0658.pp

@@ -0,0 +1,11 @@
+{$r+,q+}
+
+procedure test(i: int64);
+begin
+  if (i>0) and (i<$1fff) then
+    halt(1);
+end;
+
+begin
+  test(0);
+end.