This fixes the pessimization introduced by yesterday's change to the function,
which resulted in useless index checks generated for simple loops running over 
modular types and the couple of regressions in the gnat.dg testsuite.

Tested on x86_64-suse-linux, applied on the mainline.


2017-01-21  Eric Botcazou  <ebotca...@adacore.com>

        * sem_eval.adb (Compile_Time_Compare): Reinstate the expr+literal
        optimizations when the type is modular and the offsets are equal.

-- 
Eric Botcazou
Index: sem_eval.adb
===================================================================
--- sem_eval.adb	(revision 244741)
+++ sem_eval.adb	(working copy)
@@ -1329,26 +1329,29 @@ package body Sem_Eval is
          --  J .. J + 1. This code can conclude LT with a difference of 1,
          --  even if the range of J is not known.
 
-         --  This would be wrong for modular types (e.g. X < X + 1 is False if
-         --  X is the largest number).
+         declare
+            Lnode : Node_Id;
+            Loffs : Uint;
+            Rnode : Node_Id;
+            Roffs : Uint;
+
+         begin
+            Compare_Decompose (L, Lnode, Loffs);
+            Compare_Decompose (R, Rnode, Roffs);
+
+            if Is_Same_Value (Lnode, Rnode) then
+               if Loffs = Roffs then
+                  return EQ;
+               end if;
 
-         if not Is_Modular_Integer_Type (Ltyp)
-           and then not Is_Modular_Integer_Type (Rtyp)
-         then
-            declare
-               Lnode : Node_Id;
-               Loffs : Uint;
-               Rnode : Node_Id;
-               Roffs : Uint;
-
-            begin
-               Compare_Decompose (L, Lnode, Loffs);
-               Compare_Decompose (R, Rnode, Roffs);
-
-               if Is_Same_Value (Lnode, Rnode) then
-                  if Loffs = Roffs then
-                     return EQ;
-                  elsif Loffs < Roffs then
+               --  When the offsets are not equal, we can go farther only if
+               --  the types are not modular (e.g. X < X + 1 is False if X is
+               --  the largest number).
+
+               if not Is_Modular_Integer_Type (Ltyp)
+                 and then not Is_Modular_Integer_Type (Rtyp)
+               then
+                  if Loffs < Roffs then
                      Diff.all := Roffs - Loffs;
                      return LT;
                   else
@@ -1356,8 +1359,8 @@ package body Sem_Eval is
                      return GT;
                   end if;
                end if;
-            end;
-         end if;
+            end if;
+         end;
 
          --  Next, try range analysis and see if operand ranges are disjoint
 

Reply via email to