public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-4302] [Ada] Fix internal error on fixed-point divide, multiply and scaling
@ 2021-10-11 13:39 Pierre-Marie de Rodat
0 siblings, 0 replies; only message in thread
From: Pierre-Marie de Rodat @ 2021-10-11 13:39 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:cea83351a2a023a07ba5577cd91b5edcd690299b
commit r12-4302-gcea83351a2a023a07ba5577cd91b5edcd690299b
Author: Eric Botcazou <ebotcazou@adacore.com>
Date: Thu Sep 30 12:50:38 2021 +0200
[Ada] Fix internal error on fixed-point divide, multiply and scaling
gcc/ada/
* exp_fixd.adb (Get_Size_For_Value): New function returning a size
suitable for a non-negative integer value.
(Get_Type_For_Size): New function returning a standard type suitable
for a size.
(Build_Divide): Call both functions to compute the result type, but
make sure to pass a non-negative value to the first.
(Build_Multiply): Likewise.
(Do_Multiply_Fixed_Universal): Minor consistency tweak.
(Integer_Literal): Call both functions to compute the type.
Diff:
---
gcc/ada/exp_fixd.adb | 171 +++++++++++++++++++++++++++------------------------
1 file changed, 92 insertions(+), 79 deletions(-)
diff --git a/gcc/ada/exp_fixd.adb b/gcc/ada/exp_fixd.adb
index 8d7624f8532..94a61df4511 100644
--- a/gcc/ada/exp_fixd.adb
+++ b/gcc/ada/exp_fixd.adb
@@ -190,6 +190,15 @@ package body Exp_Fixd is
-- The expression returned is neither analyzed nor resolved. The Etype
-- of the result is properly set (to Universal_Real).
+ function Get_Size_For_Value (V : Uint) return Pos;
+ -- Given a non-negative universal integer value, return the size of a small
+ -- signed integer type covering -V .. V, or Pos'Max if no such type exists.
+
+ function Get_Type_For_Size (Siz : Pos; Force : Boolean) return Entity_Id;
+ -- Return the smallest signed integer type containing at least Siz bits.
+ -- If no such type exists, return Empty if Force is False or the largest
+ -- signed integer type if Force is True.
+
function Integer_Literal
(N : Node_Id;
V : Uint;
@@ -324,7 +333,6 @@ package body Exp_Fixd is
Right_Type : constant Entity_Id := Base_Type (Etype (R));
Left_Size : Int;
Right_Size : Int;
- Rsize : Int;
Result_Type : Entity_Id;
Rnode : Node_Id;
@@ -354,20 +362,17 @@ package body Exp_Fixd is
-- the effective size of an operand is the RM_Size of the operand.
-- But a special case arises with operands whose size is known at
-- compile time. In this case, we can use the actual value of the
- -- operand to get its size if it would fit in signed 8/16/32 bits.
+ -- operand to get a size if it would fit in a small signed integer.
Left_Size := UI_To_Int (RM_Size (Left_Type));
if Compile_Time_Known_Value (L) then
declare
- Val : constant Uint := Expr_Value (L);
+ Siz : constant Int :=
+ Get_Size_For_Value (UI_Abs (Expr_Value (L)));
begin
- if Val < Uint_2 ** 7 then
- Left_Size := 8;
- elsif Val < Uint_2 ** 15 then
- Left_Size := 16;
- elsif Val < Uint_2 ** 31 then
- Left_Size := 32;
+ if Siz < Left_Size then
+ Left_Size := Siz;
end if;
end;
end if;
@@ -376,35 +381,19 @@ package body Exp_Fixd is
if Compile_Time_Known_Value (R) then
declare
- Val : constant Uint := Expr_Value (R);
+ Siz : constant Int :=
+ Get_Size_For_Value (UI_Abs (Expr_Value (R)));
begin
- if Val <= Int'(2 ** 7) then
- Right_Size := 8;
- elsif Val <= Int'(2 ** 15) then
- Right_Size := 16;
+ if Siz < Right_Size then
+ Right_Size := Siz;
end if;
end;
end if;
-- Do the operation using the longer of the two sizes
- Rsize := Int'Max (Left_Size, Right_Size);
-
- if Rsize <= 8 then
- Result_Type := Standard_Integer_8;
-
- elsif Rsize <= 16 then
- Result_Type := Standard_Integer_16;
-
- elsif Rsize <= 32 then
- Result_Type := Standard_Integer_32;
-
- elsif Rsize <= 64 or else System_Max_Integer_Size < 128 then
- Result_Type := Standard_Integer_64;
-
- else
- Result_Type := Standard_Integer_128;
- end if;
+ Result_Type :=
+ Get_Type_For_Size (Int'Max (Left_Size, Right_Size), Force => True);
Rnode :=
Make_Op_Divide (Loc,
@@ -664,7 +653,6 @@ package body Exp_Fixd is
Right_Type : constant Entity_Id := Etype (R);
Left_Size : Int;
Right_Size : Int;
- Rsize : Int;
Result_Type : Entity_Id;
Rnode : Node_Id;
@@ -697,20 +685,17 @@ package body Exp_Fixd is
-- the effective size of an operand is the RM_Size of the operand.
-- But a special case arises with operands whose size is known at
-- compile time. In this case, we can use the actual value of the
- -- operand to get its size if it would fit in signed 8/16/32 bits.
+ -- operand to get a size if it would fit in a small signed integer.
Left_Size := UI_To_Int (RM_Size (Left_Type));
if Compile_Time_Known_Value (L) then
declare
- Val : constant Uint := Expr_Value (L);
+ Siz : constant Int :=
+ Get_Size_For_Value (UI_Abs (Expr_Value (L)));
begin
- if Val < Uint_2 ** 7 then
- Left_Size := 8;
- elsif Val < Uint_2 ** 15 then
- Left_Size := 16;
- elsif Val < Uint_2 ** 31 then
- Left_Size := 32;
+ if Siz < Left_Size then
+ Left_Size := Siz;
end if;
end;
end if;
@@ -719,12 +704,11 @@ package body Exp_Fixd is
if Compile_Time_Known_Value (R) then
declare
- Val : constant Uint := Expr_Value (R);
+ Siz : constant Int :=
+ Get_Size_For_Value (UI_Abs (Expr_Value (R)));
begin
- if Val <= Int'(2 ** 7) then
- Right_Size := 8;
- elsif Val <= Int'(2 ** 15) then
- Right_Size := 16;
+ if Siz < Right_Size then
+ Right_Size := Siz;
end if;
end;
end if;
@@ -732,23 +716,8 @@ package body Exp_Fixd is
-- Now the result size must be at least the sum of the two sizes,
-- to accommodate all possible results.
- Rsize := Left_Size + Right_Size;
-
- if Rsize <= 8 then
- Result_Type := Standard_Integer_8;
-
- elsif Rsize <= 16 then
- Result_Type := Standard_Integer_16;
-
- elsif Rsize <= 32 then
- Result_Type := Standard_Integer_32;
-
- elsif Rsize <= 64 or else System_Max_Integer_Size < 128 then
- Result_Type := Standard_Integer_64;
-
- else
- Result_Type := Standard_Integer_128;
- end if;
+ Result_Type :=
+ Get_Type_For_Size (Left_Size + Right_Size, Force => True);
Rnode :=
Make_Op_Multiply (Loc,
@@ -1542,7 +1511,7 @@ package body Exp_Fixd is
else
Lit_Int := Integer_Literal (N, Frac_Den, UR_Is_Negative (Frac));
- Lit_K := Integer_Literal (N, Frac_Num);
+ Lit_K := Integer_Literal (N, Frac_Num, False);
if Present (Lit_Int) and then Present (Lit_K) then
Set_Result (N, Build_Scaled_Divide (N, Left, Lit_K, Lit_Int));
@@ -2422,6 +2391,64 @@ package body Exp_Fixd is
return Build_Conversion (N, Universal_Real, N);
end Fpt_Value;
+ ------------------------
+ -- Get_Size_For_Value --
+ ------------------------
+
+ function Get_Size_For_Value (V : Uint) return Pos is
+ begin
+ pragma Assert (V >= Uint_0);
+
+ if V < Uint_2 ** 7 then
+ return 8;
+
+ elsif V < Uint_2 ** 15 then
+ return 16;
+
+ elsif V < Uint_2 ** 31 then
+ return 32;
+
+ elsif V < Uint_2 ** 63 then
+ return 64;
+
+ elsif V < Uint_2 ** 127 then
+ return 128;
+
+ else
+ return Pos'Last;
+ end if;
+ end Get_Size_For_Value;
+
+ -----------------------
+ -- Get_Type_For_Size --
+ -----------------------
+
+ function Get_Type_For_Size (Siz : Pos; Force : Boolean) return Entity_Id is
+ begin
+ if Siz <= 8 then
+ return Standard_Integer_8;
+
+ elsif Siz <= 16 then
+ return Standard_Integer_16;
+
+ elsif Siz <= 32 then
+ return Standard_Integer_32;
+
+ elsif Siz <= 64
+ or else (Force and then System_Max_Integer_Size < 128)
+ then
+ return Standard_Integer_64;
+
+ elsif (Siz <= 128 and then System_Max_Integer_Size = 128)
+ or else Force
+ then
+ return Standard_Integer_128;
+
+ else
+ return Empty;
+ end if;
+ end Get_Type_For_Size;
+
---------------------
-- Integer_Literal --
---------------------
@@ -2435,22 +2462,8 @@ package body Exp_Fixd is
L : Node_Id;
begin
- if V < Uint_2 ** 7 then
- T := Standard_Integer_8;
-
- elsif V < Uint_2 ** 15 then
- T := Standard_Integer_16;
-
- elsif V < Uint_2 ** 31 then
- T := Standard_Integer_32;
-
- elsif V < Uint_2 ** 63 then
- T := Standard_Integer_64;
-
- elsif V < Uint_2 ** 127 and then System_Max_Integer_Size = 128 then
- T := Standard_Integer_128;
-
- else
+ T := Get_Type_For_Size (Get_Size_For_Value (V), Force => False);
+ if No (T) then
return Empty;
end if;
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2021-10-11 13:39 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-11 13:39 [gcc r12-4302] [Ada] Fix internal error on fixed-point divide, multiply and scaling Pierre-Marie de Rodat
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).