From 90e261e494a5f1fda83b815f513c5621fa5f8c83 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Tue, 25 Oct 2016 17:11:49 +0000 Subject: [PATCH] tree.h (wi::fits_to_tree_p): Accept only 0 and 1 for boolean types. * tree.h (wi::fits_to_tree_p): Accept only 0 and 1 for boolean types. * tree.c (int_fits_type_p): Likewise. Adjust head comment. From-SVN: r241529 --- gcc/ChangeLog | 5 +++ gcc/testsuite/ChangeLog | 7 +++++ gcc/testsuite/gnat.dg/opt59.adb | 49 +++++++++++++++++++++++++++++ gcc/testsuite/gnat.dg/opt59_pkg.adb | 20 ++++++++++++ gcc/testsuite/gnat.dg/opt59_pkg.ads | 11 +++++++ gcc/testsuite/gnat.dg/opt60.adb | 17 ++++++++++ gcc/tree.c | 9 ++++-- gcc/tree.h | 5 +++ 8 files changed, 121 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/opt59.adb create mode 100644 gcc/testsuite/gnat.dg/opt59_pkg.adb create mode 100644 gcc/testsuite/gnat.dg/opt59_pkg.ads create mode 100644 gcc/testsuite/gnat.dg/opt60.adb diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 68ae6878416..9f1ddc7b562 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2016-10-25 Eric Botcazou + + * tree.h (wi::fits_to_tree_p): Accept only 0 and 1 for boolean types. + * tree.c (int_fits_type_p): Likewise. Adjust head comment. + 2016-10-25 David Malcolm * ggc-tests.c (forcibly_ggc_collect): Rename to... diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 35b366aeafc..2dc44319323 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2016-10-25 Eric Botcazou + + * gnat.dg/opt59.adb: New test. + * gnat.dg/opt59_pkg.ad[sb]: New helper. + + * gnat.dg/opt60.adb: New test. + 2016-10-25 Andre Vehreschild PR fortran/72770 diff --git a/gcc/testsuite/gnat.dg/opt59.adb b/gcc/testsuite/gnat.dg/opt59.adb new file mode 100644 index 00000000000..29665f4ac64 --- /dev/null +++ b/gcc/testsuite/gnat.dg/opt59.adb @@ -0,0 +1,49 @@ +-- { dg-do run } +-- { dg-options "-O" } + +with Opt59_Pkg; use Opt59_Pkg; + +procedure Opt59 is + + type Enum is (Zero, One, Two); + + function Has_True (V : Boolean_Vector) return Boolean is + begin + for I in V'Range loop + if V (I) then + return True; + end if; + end loop; + return False; + end; + + Data1 : constant Boolean_Vector := Get_BV1; + Data2 : constant Boolean_Vector := Get_BV2; + Result : Boolean_Vector; + + function F return Enum is + Res : Enum := Zero; + Set1 : constant Boolean := Has_True (Data1); + Set2 : constant Boolean := Has_True (Data2); + begin + if Set1 then + Res := Two; + elsif Set2 then + Res := One; + end if; + return Res; + end; + + Val : constant Enum := F; + +begin + + for I in Result'Range loop + Result (I) := Data1 (I) or Data2 (I); + end loop; + + if Val /= Zero then + Test (Val = Two); + end if; + +end; diff --git a/gcc/testsuite/gnat.dg/opt59_pkg.adb b/gcc/testsuite/gnat.dg/opt59_pkg.adb new file mode 100644 index 00000000000..16a183b47e5 --- /dev/null +++ b/gcc/testsuite/gnat.dg/opt59_pkg.adb @@ -0,0 +1,20 @@ +package body Opt59_Pkg is + + function Get_BV1 return Boolean_Vector is + begin + return (others => True); + end; + + function Get_BV2 return Boolean_Vector is + begin + return (others => False); + end; + + procedure Test (B : Boolean) is + begin + if not B then + raise Program_Error; + end if; + end; + +end Opt59_Pkg; diff --git a/gcc/testsuite/gnat.dg/opt59_pkg.ads b/gcc/testsuite/gnat.dg/opt59_pkg.ads new file mode 100644 index 00000000000..f5628be9863 --- /dev/null +++ b/gcc/testsuite/gnat.dg/opt59_pkg.ads @@ -0,0 +1,11 @@ +package Opt59_Pkg is + + type Boolean_Vector is array (1 .. 8) of Boolean; + + function Get_BV1 return Boolean_Vector; + + function Get_BV2 return Boolean_Vector; + + procedure Test (B : Boolean); + +end Opt59_Pkg; diff --git a/gcc/testsuite/gnat.dg/opt60.adb b/gcc/testsuite/gnat.dg/opt60.adb new file mode 100644 index 00000000000..9154fb46fa6 --- /dev/null +++ b/gcc/testsuite/gnat.dg/opt60.adb @@ -0,0 +1,17 @@ +-- { dg-do compile } +-- { dg-options "-gnatws -O2 -fdump-tree-optimized" } + +with System; use System; +with System.CRTL; use System.CRTL; + +function Opt60 (Size : size_t) return System.Address is + Result : System.Address; +begin + Result := malloc (Size); + if Result = System.Null_Address then + raise Program_Error; + end if; + return Result; +end; + +-- { dg-final { scan-tree-dump "== 0B" "optimized" } } diff --git a/gcc/tree.c b/gcc/tree.c index 30d4373a20d..56cc653c875 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -9065,8 +9065,8 @@ get_narrower (tree op, int *unsignedp_ptr) return win; } -/* Returns true if integer constant C has a value that is permissible - for type TYPE (an INTEGER_TYPE). */ +/* Return true if integer constant C has a value that is permissible + for TYPE, an integral type. */ bool int_fits_type_p (const_tree c, const_tree type) @@ -9075,6 +9075,11 @@ int_fits_type_p (const_tree c, const_tree type) bool ok_for_low_bound, ok_for_high_bound; signop sgn_c = TYPE_SIGN (TREE_TYPE (c)); + /* Short-circuit boolean types since various transformations assume that + they can only take values 0 and 1. */ + if (TREE_CODE (type) == BOOLEAN_TYPE) + return integer_zerop (c) || integer_onep (c); + retry: type_low_bound = TYPE_MIN_VALUE (type); type_high_bound = TYPE_MAX_VALUE (type); diff --git a/gcc/tree.h b/gcc/tree.h index 9624a01676b..c494f23c90d 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -5295,6 +5295,11 @@ template bool wi::fits_to_tree_p (const T &x, const_tree type) { + /* Short-circuit boolean types since various transformations assume that + they can only take values 0 and 1. */ + if (TREE_CODE (type) == BOOLEAN_TYPE) + return eq_p (x, 0) || eq_p (x, 1); + if (TYPE_SIGN (type) == UNSIGNED) return eq_p (x, zext (x, TYPE_PRECISION (type))); else -- 2.30.2