Przeglądaj źródła

* 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 6 lat temu
rodzic
commit
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/tb0656.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/tb610.pp svneol=native#text/pascal
 tests/tbs/tb613.pp svneol=native#text/plain

+ 1 - 1
compiler/arm/narmadd.pas

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

+ 4 - 4
compiler/i386/n386add.pas

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

+ 6 - 3
compiler/i8086/n8086add.pas

@@ -315,7 +315,7 @@ interface
         { is in unsigned VAR!!                              }
         if mboverflow then
          begin
-           if cs_check_overflow in current_settings.localswitches  then
+           if needoverflowcheck then
             begin
               current_asmdata.getjumplabel(hl4);
               if unsigned then
@@ -1002,6 +1002,7 @@ interface
         ref:Treference;
         use_ref:boolean;
         hl4 : tasmlabel;
+        overflowcheck: boolean;
 
     const
       asmops: array[boolean] of tasmop = (A_IMUL, A_MUL);
@@ -1012,10 +1013,12 @@ interface
 
       pass_left_right;
 
+      overflowcheck:=needoverflowcheck;
+
       { 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
         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
         unsigned:=true;
 
@@ -1048,7 +1051,7 @@ interface
         emit_ref(asmops[unsigned],S_W,ref)
       else
         emit_reg(asmops[unsigned],S_W,reg);
-      if (cs_check_overflow in current_settings.localswitches) and
+      if overflowcheck and
         { 16->32 bit cannot overflow }
         (not is_32bitint(resultdef)) then
         begin

+ 2 - 4
compiler/m68k/n68kadd.pas

@@ -399,9 +399,7 @@ implementation
       begin
         { if we need to handle overflow checking, fall back to the generic cg }
         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
             inherited;
             exit;
@@ -609,7 +607,7 @@ implementation
 
     function t68kaddnode.use_generic_mul64bit: boolean;
     begin
-      result:=(cs_check_overflow in current_settings.localswitches) or
+      result:=needoverflowcheck  or
         (cs_opt_size in current_settings.optimizerswitches) or
         not (CPUM68K_HAS_64BITMUL in cpu_capabilities[current_settings.cputype]);
     end;

+ 1 - 1
compiler/mips/ncpuadd.pas

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

+ 12 - 3
compiler/ncgadd.pas

@@ -66,6 +66,8 @@ interface
           procedure second_cmpsmallset;virtual;abstract;
           procedure second_cmp64bit;virtual;abstract;
           procedure second_cmpordinal;virtual;abstract;
+
+          function needoverflowcheck: boolean;
        end;
 
   implementation
@@ -518,9 +520,7 @@ interface
 
         checkoverflow:=
           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)}
         case nodetype of
@@ -763,6 +763,15 @@ interface
         second_cmpordinal;
       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;

+ 4 - 7
compiler/powerpc/nppcadd.pas

@@ -325,11 +325,10 @@ interface
             current_asmdata.getjumplabel(falselabel);
           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
           begin
             case nodetype of
@@ -657,9 +656,7 @@ interface
 
          checkoverflow:=
            (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);
 

+ 1 - 5
compiler/powerpc64/nppcadd.pas

@@ -219,11 +219,7 @@ begin
   else
     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);
 

+ 1 - 1
compiler/sparcgen/ncpuadd.pas

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

+ 8 - 8
compiler/x86/nx86add.pas

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

+ 2 - 2
compiler/x86_64/nx64add.pas

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