This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] Fix PR tree-optimization/86514


Hi,

this is a regression present on the mainline and 8 branch in the form of wrong 
code generated for an Ada program manipulating bit-packed boolean array types.

The problem is in the new range optimization code of the reassoc pass: from

  _64 = _63 | 4;
  _73 = _64 & 191;
  _76 = _64 >> 6;
  _77 = (boolean) _76;
  _78 = (boolean) _64;
  _79 = _77 | _78;

it deduces:

Optimizing range tests _76 +[0, 0] and _64 +[0, 0]
|...]
  _64 = _63 | 4;
  _73 = _64 & 191;
  _76 = _64 >> 6;
  _90 = _76 | _64;
  _19 = _90 != 0;
  _77 = (boolean) _76;
  _78 = (boolean) _64;
  _79 = _19;

which is not equivalent.  The proposed fix is to avoid bypassing a conversion 
to a boolean type from a type with greater precision in init_range_entry.

Tested on x86_64-suse-linux, OK for the mainline?


2018-07-16  Eric Botcazou  <ebotcazou@adacore.com>

	PR tree-optimization/86514
	* tree-ssa-reassoc.c (init_range_entry) <CASE_CONVERT>: Return for a
	conversion to a boolean type from a type with greater precision.


2018-07-16  Eric Botcazou  <ebotcazou@adacore.com>

	* gnat.dg/opt73.adb: New test.

-- 
Eric Botcazou
Index: tree-ssa-reassoc.c
===================================================================
--- tree-ssa-reassoc.c	(revision 262658)
+++ tree-ssa-reassoc.c	(working copy)
@@ -2168,8 +2168,13 @@ init_range_entry (struct range_entry *r,
 	  continue;
 	CASE_CONVERT:
 	  if (is_bool)
-	    goto do_default;
-	  if (TYPE_PRECISION (TREE_TYPE (arg0)) == 1)
+	    {
+	      if ((TYPE_PRECISION (exp_type) == 1
+		   || TREE_CODE (exp_type) == BOOLEAN_TYPE)
+		  && TYPE_PRECISION (TREE_TYPE (arg0)) > 1)
+		return;
+	    }
+	  else if (TYPE_PRECISION (TREE_TYPE (arg0)) == 1)
 	    {
 	      if (TYPE_UNSIGNED (TREE_TYPE (arg0)))
 		is_bool = true;
-- { dg-do run }
-- { dg-options "-O" }

procedure Opt73 is

   type Terminal_Set_Indexed_By_Non_Terminal is
     array (Natural range <>, Natural  range <>) of Boolean with Pack;

   type Terminal_Set_Per_Non_Terminal
     (Last_Terminal     : Natural;
      Last_Non_Terminal : Natural) is
   record
      Map : Terminal_Set_Indexed_By_Non_Terminal
        (1 .. Last_Non_Terminal, 0 .. Last_Terminal);
   end record;

   Follow : Terminal_Set_Per_Non_Terminal (5, 4);
   Expect : Terminal_Set_Per_Non_Terminal :=
     (5, 4, (1 => (2 => True, others => False),
             others => (others => False)));

   procedure Get_Follow (Value : out Terminal_Set_Per_Non_Terminal) is
   begin
      Value.Map := (others => (others => False));
      Value.Map (1, 2) := True;
      Value.Map (2, 0) := Value.Map (2, 0) or Value.Map (1, 0);
   end;

begin
   Get_Follow (Follow);
   if Follow /= Expect then
      raise Program_Error;
   end if;
end;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]