From: Eric Botcazou <ebotca...@adacore.com>

This happens for very large Smalls with regard to the size of the mantissa,
because the prerequisites of the implementation used in this case are not
met, although they are documented in the head comment of Integer_To_Fixed.

This change documents them at the beginning of the body of System.Value_F
and adjusts the compiler interface accordingly.

gcc/ada/ChangeLog:

        * libgnat/s-valuef.adb: Document the prerequisites more precisely.
        * libgnat/a-tifiio.adb (OK_Get_32): Adjust to the prerequisites.
        (OK_Get_64): Likewise.
        * libgnat/a-tifiio__128.adb (OK_Get_32): Likewise.
        (OK_Get_64): Likewise.
        (OK_Get_128): Likewise.
        * libgnat/a-wtfiio.adb (OK_Get_32): Likewise.
        (OK_Get_64): Likewise.
        * libgnat/a-wtfiio__128.adb (OK_Get_32): Likewise.
        (OK_Get_64): Likewise.
        (OK_Get_128): Likewise.
        * libgnat/a-ztfiio.adb (OK_Get_32): Likewise.
        (OK_Get_64): Likewise.
        * libgnat/a-ztfiio__128.adb (OK_Get_32): Likewise.
        (OK_Get_64): Likewise.
        (OK_Get_128): Likewise.
        * exp_imgv.adb (Expand_Value_Attribute): Adjust the conditions under
        which the RE_Value_Fixed{32,64,128} routines are called for ordinary
        fixed-point types.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/exp_imgv.adb              |  7 +++----
 gcc/ada/libgnat/a-tifiio.adb      |  6 ------
 gcc/ada/libgnat/a-tifiio__128.adb |  9 ---------
 gcc/ada/libgnat/a-wtfiio.adb      |  6 ------
 gcc/ada/libgnat/a-wtfiio__128.adb |  9 ---------
 gcc/ada/libgnat/a-ztfiio.adb      |  6 ------
 gcc/ada/libgnat/a-ztfiio__128.adb |  9 ---------
 gcc/ada/libgnat/s-valuef.adb      | 16 ++++++++++------
 8 files changed, 13 insertions(+), 55 deletions(-)

diff --git a/gcc/ada/exp_imgv.adb b/gcc/ada/exp_imgv.adb
index c7cf06ba444..6c2b940736b 100644
--- a/gcc/ada/exp_imgv.adb
+++ b/gcc/ada/exp_imgv.adb
@@ -1640,23 +1640,22 @@ package body Exp_Imgv is
             Num : constant Uint := Norm_Num (Small_Value (Rtyp));
             Den : constant Uint := Norm_Den (Small_Value (Rtyp));
             Max : constant Uint := UI_Max (Num, Den);
-            Min : constant Uint := UI_Min (Num, Den);
             Siz : constant Uint := Esize (Rtyp);
 
          begin
             if Siz <= 32
               and then Max <= Uint_2 ** 31
-              and then (Min = Uint_1 or else Max <= Uint_2 ** 27)
+              and then (Num = Uint_1 or else Max <= Uint_2 ** 27)
             then
                Vid := RE_Value_Fixed32;
             elsif Siz <= 64
               and then Max <= Uint_2 ** 63
-              and then (Min = Uint_1 or else Max <= Uint_2 ** 59)
+              and then (Num = Uint_1 or else Max <= Uint_2 ** 59)
             then
                Vid := RE_Value_Fixed64;
             elsif System_Max_Integer_Size = 128
               and then Max <= Uint_2 ** 127
-              and then (Min = Uint_1 or else Max <= Uint_2 ** 123)
+              and then (Num = Uint_1 or else Max <= Uint_2 ** 123)
             then
                Vid := RE_Value_Fixed128;
             else
diff --git a/gcc/ada/libgnat/a-tifiio.adb b/gcc/ada/libgnat/a-tifiio.adb
index 735859c3f15..26f04ed726e 100644
--- a/gcc/ada/libgnat/a-tifiio.adb
+++ b/gcc/ada/libgnat/a-tifiio.adb
@@ -194,9 +194,6 @@ package body Ada.Text_IO.Fixed_IO with SPARK_Mode => Off is
          ((Num'Base'Small_Numerator = 1
             and then Num'Base'Small_Denominator <= 2**31)
            or else
-          (Num'Base'Small_Denominator = 1
-            and then Num'Base'Small_Numerator <= 2**31)
-           or else
           (Num'Base'Small_Numerator <= 2**27
             and then Num'Base'Small_Denominator <= 2**27));
    --  These conditions are derived from the prerequisites of System.Value_F
@@ -223,9 +220,6 @@ package body Ada.Text_IO.Fixed_IO with SPARK_Mode => Off is
          ((Num'Base'Small_Numerator = 1
             and then Num'Base'Small_Denominator <= 2**63)
            or else
-          (Num'Base'Small_Denominator = 1
-            and then Num'Base'Small_Numerator <= 2**63)
-           or else
           (Num'Base'Small_Numerator <= 2**59
             and then Num'Base'Small_Denominator <= 2**59));
    --  These conditions are derived from the prerequisites of System.Value_F
diff --git a/gcc/ada/libgnat/a-tifiio__128.adb 
b/gcc/ada/libgnat/a-tifiio__128.adb
index 7424346fe3d..78c25f29bc8 100644
--- a/gcc/ada/libgnat/a-tifiio__128.adb
+++ b/gcc/ada/libgnat/a-tifiio__128.adb
@@ -201,9 +201,6 @@ package body Ada.Text_IO.Fixed_IO with SPARK_Mode => Off is
          ((Num'Base'Small_Numerator = 1
             and then Num'Base'Small_Denominator <= 2**31)
            or else
-          (Num'Base'Small_Denominator = 1
-            and then Num'Base'Small_Numerator <= 2**31)
-           or else
           (Num'Base'Small_Numerator <= 2**27
             and then Num'Base'Small_Denominator <= 2**27));
    --  These conditions are derived from the prerequisites of System.Value_F
@@ -230,9 +227,6 @@ package body Ada.Text_IO.Fixed_IO with SPARK_Mode => Off is
          ((Num'Base'Small_Numerator = 1
             and then Num'Base'Small_Denominator <= 2**63)
            or else
-          (Num'Base'Small_Denominator = 1
-            and then Num'Base'Small_Numerator <= 2**63)
-           or else
           (Num'Base'Small_Numerator <= 2**59
             and then Num'Base'Small_Denominator <= 2**59));
    --  These conditions are derived from the prerequisites of System.Value_F
@@ -259,9 +253,6 @@ package body Ada.Text_IO.Fixed_IO with SPARK_Mode => Off is
          ((Num'Base'Small_Numerator = 1
             and then Num'Base'Small_Denominator <= 2**127)
            or else
-          (Num'Base'Small_Denominator = 1
-            and then Num'Base'Small_Numerator <= 2**127)
-           or else
           (Num'Base'Small_Numerator <= 2**123
             and then Num'Base'Small_Denominator <= 2**123));
    --  These conditions are derived from the prerequisites of System.Value_F
diff --git a/gcc/ada/libgnat/a-wtfiio.adb b/gcc/ada/libgnat/a-wtfiio.adb
index ed69d65df09..3ceda12b9ec 100644
--- a/gcc/ada/libgnat/a-wtfiio.adb
+++ b/gcc/ada/libgnat/a-wtfiio.adb
@@ -73,9 +73,6 @@ package body Ada.Wide_Text_IO.Fixed_IO is
          ((Num'Base'Small_Numerator = 1
             and then Num'Base'Small_Denominator <= 2**31)
            or else
-          (Num'Base'Small_Denominator = 1
-            and then Num'Base'Small_Numerator <= 2**31)
-           or else
           (Num'Base'Small_Numerator <= 2**27
             and then Num'Base'Small_Denominator <= 2**27));
    --  These conditions are derived from the prerequisites of System.Value_F
@@ -102,9 +99,6 @@ package body Ada.Wide_Text_IO.Fixed_IO is
          ((Num'Base'Small_Numerator = 1
             and then Num'Base'Small_Denominator <= 2**63)
            or else
-          (Num'Base'Small_Denominator = 1
-            and then Num'Base'Small_Numerator <= 2**63)
-           or else
           (Num'Base'Small_Numerator <= 2**59
             and then Num'Base'Small_Denominator <= 2**59));
    --  These conditions are derived from the prerequisites of System.Value_F
diff --git a/gcc/ada/libgnat/a-wtfiio__128.adb 
b/gcc/ada/libgnat/a-wtfiio__128.adb
index ec8deca6ca4..8757ffb2514 100644
--- a/gcc/ada/libgnat/a-wtfiio__128.adb
+++ b/gcc/ada/libgnat/a-wtfiio__128.adb
@@ -80,9 +80,6 @@ package body Ada.Wide_Text_IO.Fixed_IO is
          ((Num'Base'Small_Numerator = 1
             and then Num'Base'Small_Denominator <= 2**31)
            or else
-          (Num'Base'Small_Denominator = 1
-            and then Num'Base'Small_Numerator <= 2**31)
-           or else
           (Num'Base'Small_Numerator <= 2**27
             and then Num'Base'Small_Denominator <= 2**27));
    --  These conditions are derived from the prerequisites of System.Value_F
@@ -109,9 +106,6 @@ package body Ada.Wide_Text_IO.Fixed_IO is
          ((Num'Base'Small_Numerator = 1
             and then Num'Base'Small_Denominator <= 2**63)
            or else
-          (Num'Base'Small_Denominator = 1
-            and then Num'Base'Small_Numerator <= 2**63)
-           or else
           (Num'Base'Small_Numerator <= 2**59
             and then Num'Base'Small_Denominator <= 2**59));
    --  These conditions are derived from the prerequisites of System.Value_F
@@ -138,9 +132,6 @@ package body Ada.Wide_Text_IO.Fixed_IO is
          ((Num'Base'Small_Numerator = 1
             and then Num'Base'Small_Denominator <= 2**127)
            or else
-          (Num'Base'Small_Denominator = 1
-            and then Num'Base'Small_Numerator <= 2**127)
-           or else
           (Num'Base'Small_Numerator <= 2**123
             and then Num'Base'Small_Denominator <= 2**123));
    --  These conditions are derived from the prerequisites of System.Value_F
diff --git a/gcc/ada/libgnat/a-ztfiio.adb b/gcc/ada/libgnat/a-ztfiio.adb
index edf58ad85ea..b9f4f43226f 100644
--- a/gcc/ada/libgnat/a-ztfiio.adb
+++ b/gcc/ada/libgnat/a-ztfiio.adb
@@ -73,9 +73,6 @@ package body Ada.Wide_Wide_Text_IO.Fixed_IO is
          ((Num'Base'Small_Numerator = 1
             and then Num'Base'Small_Denominator <= 2**31)
            or else
-          (Num'Base'Small_Denominator = 1
-            and then Num'Base'Small_Numerator <= 2**31)
-           or else
           (Num'Base'Small_Numerator <= 2**27
             and then Num'Base'Small_Denominator <= 2**27));
    --  These conditions are derived from the prerequisites of System.Value_F
@@ -102,9 +99,6 @@ package body Ada.Wide_Wide_Text_IO.Fixed_IO is
          ((Num'Base'Small_Numerator = 1
             and then Num'Base'Small_Denominator <= 2**63)
            or else
-          (Num'Base'Small_Denominator = 1
-            and then Num'Base'Small_Numerator <= 2**63)
-           or else
           (Num'Base'Small_Numerator <= 2**59
             and then Num'Base'Small_Denominator <= 2**59));
    --  These conditions are derived from the prerequisites of System.Value_F
diff --git a/gcc/ada/libgnat/a-ztfiio__128.adb 
b/gcc/ada/libgnat/a-ztfiio__128.adb
index bc0062f9d9f..eb02a4a2cec 100644
--- a/gcc/ada/libgnat/a-ztfiio__128.adb
+++ b/gcc/ada/libgnat/a-ztfiio__128.adb
@@ -81,9 +81,6 @@ package body Ada.Wide_Wide_Text_IO.Fixed_IO is
          ((Num'Base'Small_Numerator = 1
             and then Num'Base'Small_Denominator <= 2**31)
            or else
-          (Num'Base'Small_Denominator = 1
-            and then Num'Base'Small_Numerator <= 2**31)
-           or else
           (Num'Base'Small_Numerator <= 2**27
             and then Num'Base'Small_Denominator <= 2**27));
    --  These conditions are derived from the prerequisites of System.Value_F
@@ -110,9 +107,6 @@ package body Ada.Wide_Wide_Text_IO.Fixed_IO is
          ((Num'Base'Small_Numerator = 1
             and then Num'Base'Small_Denominator <= 2**63)
            or else
-          (Num'Base'Small_Denominator = 1
-            and then Num'Base'Small_Numerator <= 2**63)
-           or else
           (Num'Base'Small_Numerator <= 2**59
             and then Num'Base'Small_Denominator <= 2**59));
    --  These conditions are derived from the prerequisites of System.Value_F
@@ -139,9 +133,6 @@ package body Ada.Wide_Wide_Text_IO.Fixed_IO is
          ((Num'Base'Small_Numerator = 1
             and then Num'Base'Small_Denominator <= 2**127)
            or else
-          (Num'Base'Small_Denominator = 1
-            and then Num'Base'Small_Numerator <= 2**127)
-           or else
           (Num'Base'Small_Numerator <= 2**123
             and then Num'Base'Small_Denominator <= 2**123));
    --  These conditions are derived from the prerequisites of System.Value_F
diff --git a/gcc/ada/libgnat/s-valuef.adb b/gcc/ada/libgnat/s-valuef.adb
index 1743749f542..f38f2cc66ac 100644
--- a/gcc/ada/libgnat/s-valuef.adb
+++ b/gcc/ada/libgnat/s-valuef.adb
@@ -36,12 +36,13 @@ with System.Value_R;
 package body System.Value_F is
 
    --  The prerequisite of the implementation is that the computation of the
-   --  operands of the scaled divide does not unduly overflow when the small
-   --  is neither an integer nor the reciprocal of an integer, which means
-   --  that its numerator and denominator must be both not larger than the
-   --  smallest divide 2**(Int'Size - 1) / Base where Base ranges over the
-   --  supported values for the base of the literal. Given that the largest
-   --  supported base is 16, this gives a limit of 2**(Int'Size - 5).
+   --  operands of the scaled divide does not unduly overflow, which means
+   --  that the numerator and the denominator of the small must be both not
+   --  larger than the smallest divide 2**(Int'Size - 1) / Base where Base
+   --  ranges over the supported values for the base of the literal, except
+   --  when the numerator is 1, in which case up to 2**(Int'Size - 1) is
+   --  permitted for the denominator. Given that the largest supported base
+   --  is 16, this gives a limit of 2**(Int'Size - 5) in the general case.
 
    pragma Assert (Int'Size <= Uns'Size);
    --  We need an unsigned type large enough to represent the mantissa
@@ -135,6 +136,9 @@ package body System.Value_F is
    --    Num * (Base ** -ScaleB) <= Num * (B ** N) < Den * B
 
    --  which means that the product does not overflow if Den <= 2**(M-1) / B.
+   --  Moreover, if 2**(M-1) / B < Den <= 2**(M-1), we can add 1 to ScaleB and
+   --  divide Val by B while preserving the rightmost B-digit of Val in Extra2
+   --  without changing the computation when Num = 1.
 
    ----------------------
    -- Integer_To_Fixed --
-- 
2.43.0

Reply via email to