public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH][1/n] No longer sign-extend sizetype constants, remove TYPE_IS_SIZETYPE
@ 2012-03-06 13:45 Richard Guenther
  2012-03-06 15:38 ` Richard Guenther
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Richard Guenther @ 2012-03-06 13:45 UTC (permalink / raw)
  To: gcc-patches; +Cc: Joseph S. Myers, jason, ebotcazou


This splits out some small chunks from the patch killing 
TYPE_IS_SIZETYPE.  It introduces a helper function that
performs object-size checks and uses it in the few places
that would need adjustments when host_integerp is no longer
appropriate for verifying that the size fits in half of the
address-space.

Bootstrapped and tested on x86_64-unknown-linux-gnu, ok for trunk?

--

Eric, this starts the series of getting rid of TYPE_IS_SIZETYPE.
This patch will break Ada bootstrap (fixed by subsequent patches),
because copy_and_substitute_in_size () will sometimes (in this
case for the secondary stack size) compute a constant TYPE_SIZE_UNIT
with TREE_OVERFLOW set (compiling s-secsta.adb).  With the theory that
sizetypes cannot have overflow this looks like a latent bug somewhere in
the construction of the expression that leads to it.  When sizetypes
are finally unsigned the overflow bit will not be set anymore and
this bug does not trigger.

Happens when substitute_in_expr with
exp = (sizetype) ((bitsizetype) -<PLACEHOLDER_EXPR struct 
system__secondary_stack__chunk_id>.first + 10241)
f = first
r = 1
we then convert bitsizetype 0x100002800 to sizetype via
fold_convert_const_int_from_int (this is -m32 multilib), which
leads to an overflowed value.  Not sure how we arrive at this
call of substitute_in_expr as the original expression we substitute in
is

((sizetype) (_GLOBAL.SZ4_system.secondary_stack (<PLACEHOLDER_EXPR struct 
system__secondary_stack__chunk_id>.last, <PLACEHOLDER_EXPR struct 
system__secondary_stack__chunk_id>.first) /[cl] 8) + 15 & -16) + 16

and thus the bitsize quantity _GLOBAL.SZ4_system.secondary_stack 
(<PLACEHOLDER_EXPR struct
system__secondary_stack__chunk_id>.last, <PLACEHOLDER_EXPR struct
system__secondary_stack__chunk_id>.first) is first divided by 8
and _then_ converted to sizetype.  I suspect some existing bug
in some re-association.  It's appearantly not

2011-09-04  Richard Guenther  <rguenther@suse.de>

        Revert
        2011-08-31  Richard Guenther  <rguenther@suse.de>

        * fold-const.c (extract_muldiv_1): Remove bogus TYPE_IS_SIZETYPE
        special-casing.

though.

I'm not sure how much I need to care for Ada at this point, and I am
definitely wanting to kill off TYPE_IS_SIZETYPE and sizetypes 
sign-extending.  That's a definite prerequesite to continue on
no-undefined-overflow.

--

Thanks,
Richard.

2012-03-06  Richard Guenther  <rguenther@suse.de>

	* tree.c (valid_constant_size_p): New function.
	* tree.h (valid_constant_size_p): Declare.
	* cfgexpand.c (expand_one_var): Adjust check for too large
	variables by using valid_constant_size_p.
	* varasm.c (assemble_variable): Likewise.

	c/
	* c-decl.c (grokdeclarator): Properly check for sizes that
	cover more than half of the address-space.

	cp/
	* decl.c (grokdeclarator): Properly check for sizes that
	cover more than half of the address-space.

Index: trunk/gcc/tree.c
===================================================================
*** trunk.orig/gcc/tree.c	2011-09-05 15:27:16.000000000 +0200
--- trunk/gcc/tree.c	2011-09-05 15:51:20.000000000 +0200
*************** compare_tree_int (const_tree t, unsigned
*** 6782,6787 ****
--- 6774,6793 ----
      return 1;
  }
  
+ /* Return true if SIZE represents a constant size that is in bounds of
+    what the middle-end and the backend accepts (covering not more than
+    half of the address-space).  */
+ 
+ bool
+ valid_constant_size_p (const_tree size)
+ {
+   if (! host_integerp (size, 1)
+       || TREE_OVERFLOW (size)
+       || tree_int_cst_sign_bit (size) != 0)
+     return false;
+   return true;
+ }
+ 
  /* Return true if CODE represents an associative tree code.  Otherwise
     return false.  */
  bool
Index: trunk/gcc/varasm.c
===================================================================
*** trunk.orig/gcc/varasm.c	2011-09-05 15:27:16.000000000 +0200
--- trunk/gcc/varasm.c	2011-09-05 16:03:53.000000000 +0200
*************** assemble_variable (tree decl, int top_le
*** 1980,1986 ****
      return;
  
    if (! dont_output_data
!       && ! host_integerp (DECL_SIZE_UNIT (decl), 1))
      {
        error ("size of variable %q+D is too large", decl);
        return;
--- 1980,1986 ----
      return;
  
    if (! dont_output_data
!       && ! valid_constant_size_p (DECL_SIZE_UNIT (decl)))
      {
        error ("size of variable %q+D is too large", decl);
        return;
Index: trunk/gcc/c-decl.c
===================================================================
*** trunk.orig/gcc/c-decl.c	2011-09-05 15:27:16.000000000 +0200
--- trunk/gcc/c-decl.c	2011-09-05 15:51:20.000000000 +0200
*************** grokdeclarator (const struct c_declarato
*** 5708,5719 ****
    if (bitfield)
      check_bitfield_type_and_width (&type, width, name);
  
!   /* Did array size calculations overflow?  */
! 
    if (TREE_CODE (type) == ARRAY_TYPE
        && COMPLETE_TYPE_P (type)
        && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST
!       && TREE_OVERFLOW (TYPE_SIZE_UNIT (type)))
      {
        if (name)
  	error_at (loc, "size of array %qE is too large", name);
--- 5708,5719 ----
    if (bitfield)
      check_bitfield_type_and_width (&type, width, name);
  
!   /* Did array size calculations overflow or does the array cover more
!      than half of the address-space?  */
    if (TREE_CODE (type) == ARRAY_TYPE
        && COMPLETE_TYPE_P (type)
        && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST
!       && ! valid_constant_size_p (TYPE_SIZE_UNIT (type)))
      {
        if (name)
  	error_at (loc, "size of array %qE is too large", name);
Index: trunk/gcc/cp/decl.c
===================================================================
*** trunk.orig/gcc/cp/decl.c	2011-09-05 15:27:16.000000000 +0200
--- trunk/gcc/cp/decl.c	2011-09-05 15:51:20.000000000 +0200
*************** grokdeclarator (const cp_declarator *dec
*** 9505,9516 ****
          error ("non-parameter %qs cannot be a parameter pack", name);
      }
  
!   /* Did array size calculations overflow?  */
! 
    if (TREE_CODE (type) == ARRAY_TYPE
        && COMPLETE_TYPE_P (type)
        && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST
!       && TREE_OVERFLOW (TYPE_SIZE_UNIT (type)))
      {
        error ("size of array %qs is too large", name);
        /* If we proceed with the array type as it is, we'll eventually
--- 9505,9516 ----
          error ("non-parameter %qs cannot be a parameter pack", name);
      }
  
!   /* Did array size calculations overflow or does the array cover more
!      than half of the address-space?  */
    if (TREE_CODE (type) == ARRAY_TYPE
        && COMPLETE_TYPE_P (type)
        && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST
!       && ! valid_constant_size_p (TYPE_SIZE_UNIT (type)))
      {
        error ("size of array %qs is too large", name);
        /* If we proceed with the array type as it is, we'll eventually
Index: trunk/gcc/cfgexpand.c
===================================================================
*** trunk.orig/gcc/cfgexpand.c	2011-09-05 15:27:16.000000000 +0200
--- trunk/gcc/cfgexpand.c	2011-09-05 15:51:20.000000000 +0200
*************** expand_one_var (tree var, bool toplevel,
*** 1067,1074 ****
        if (really_expand)
          expand_one_register_var (origvar);
      }
!   else if (!host_integerp (DECL_SIZE_UNIT (var), 1))
      {
        if (really_expand)
  	{
  	  error ("size of variable %q+D is too large", var);
--- 1067,1075 ----
        if (really_expand)
          expand_one_register_var (origvar);
      }
!   else if (! valid_constant_size_p (DECL_SIZE_UNIT (var)))
      {
+       /* Reject variables which cover more than half of the address-space.  */
        if (really_expand)
  	{
  	  error ("size of variable %q+D is too large", var);
Index: trunk/gcc/tree.h
===================================================================
*** trunk.orig/gcc/tree.h	2011-09-05 15:27:16.000000000 +0200
--- trunk/gcc/tree.h	2011-09-05 15:51:20.000000000 +0200
*************** extern bool tree_expr_nonnegative_warnv_
*** 4388,4393 ****
--- 4388,4394 ----
  extern bool may_negate_without_overflow_p (const_tree);
  extern tree strip_array_types (tree);
  extern tree excess_precision_type (tree);
+ extern bool valid_constant_size_p (const_tree);
  
  /* Construct various nodes representing fract or accum data types.  */
  

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH][1/n] No longer sign-extend sizetype constants, remove TYPE_IS_SIZETYPE
  2012-03-06 13:45 [PATCH][1/n] No longer sign-extend sizetype constants, remove TYPE_IS_SIZETYPE Richard Guenther
@ 2012-03-06 15:38 ` Richard Guenther
  2012-03-06 22:11   ` Eric Botcazou
  2012-03-09 11:54   ` Eric Botcazou
  2012-03-06 17:36 ` Joseph S. Myers
  2012-03-06 18:18 ` Jason Merrill
  2 siblings, 2 replies; 9+ messages in thread
From: Richard Guenther @ 2012-03-06 15:38 UTC (permalink / raw)
  To: gcc-patches; +Cc: ebotcazou

On Tue, 6 Mar 2012, Richard Guenther wrote:

> 
> This splits out some small chunks from the patch killing 
> TYPE_IS_SIZETYPE.  It introduces a helper function that
> performs object-size checks and uses it in the few places
> that would need adjustments when host_integerp is no longer
> appropriate for verifying that the size fits in half of the
> address-space.
> 
> Bootstrapped and tested on x86_64-unknown-linux-gnu, ok for trunk?
> 
> --
> 
> Eric, this starts the series of getting rid of TYPE_IS_SIZETYPE.
> This patch will break Ada bootstrap (fixed by subsequent patches),
> because copy_and_substitute_in_size () will sometimes (in this
> case for the secondary stack size) compute a constant TYPE_SIZE_UNIT
> with TREE_OVERFLOW set (compiling s-secsta.adb).  With the theory that
> sizetypes cannot have overflow this looks like a latent bug somewhere in
> the construction of the expression that leads to it.  When sizetypes
> are finally unsigned the overflow bit will not be set anymore and
> this bug does not trigger.
> 
> Happens when substitute_in_expr with
> exp = (sizetype) ((bitsizetype) -<PLACEHOLDER_EXPR struct 
> system__secondary_stack__chunk_id>.first + 10241)
> f = first
> r = 1
> we then convert bitsizetype 0x100002800 to sizetype via
> fold_convert_const_int_from_int (this is -m32 multilib), which
> leads to an overflowed value.  Not sure how we arrive at this
> call of substitute_in_expr as the original expression we substitute in
> is
> 
> ((sizetype) (_GLOBAL.SZ4_system.secondary_stack (<PLACEHOLDER_EXPR struct 
> system__secondary_stack__chunk_id>.last, <PLACEHOLDER_EXPR struct 
> system__secondary_stack__chunk_id>.first) /[cl] 8) + 15 & -16) + 16
> 
> and thus the bitsize quantity _GLOBAL.SZ4_system.secondary_stack 
> (<PLACEHOLDER_EXPR struct
> system__secondary_stack__chunk_id>.last, <PLACEHOLDER_EXPR struct
> system__secondary_stack__chunk_id>.first) is first divided by 8
> and _then_ converted to sizetype.  I suspect some existing bug
> in some re-association.  It's appearantly not
> 
> 2011-09-04  Richard Guenther  <rguenther@suse.de>
> 
>         Revert
>         2011-08-31  Richard Guenther  <rguenther@suse.de>
> 
>         * fold-const.c (extract_muldiv_1): Remove bogus TYPE_IS_SIZETYPE
>         special-casing.
> 
> though.
> 
> I'm not sure how much I need to care for Ada at this point, and I am
> definitely wanting to kill off TYPE_IS_SIZETYPE and sizetypes 
> sign-extending.  That's a definite prerequesite to continue on
> no-undefined-overflow.

Btw, digging down this rat-hole again shows that the first issue
you hit is the "negative" DECL_FIELD_OFFSETs.  If you paper over
some issues with

2011-09-02  Richard Guenther  <rguenther@suse.de>

	ada/
	* gcc-interface/utils.c (shift_unc_components_for_thin_pointers):
	Drop overflow bit on negative offsets.

Index: trunk/gcc/ada/gcc-interface/utils.c
===================================================================
*** trunk.orig/gcc/ada/gcc-interface/utils.c	2012-03-06 16:00:04.000000000 +0100
--- trunk/gcc/ada/gcc-interface/utils.c	2012-03-06 16:04:26.000000000 +0100
*************** shift_unc_components_for_thin_pointers (
*** 3447,3452 ****
--- 3447,3460 ----
  
    DECL_FIELD_OFFSET (bounds_field)
      = size_binop (MINUS_EXPR, size_zero_node, byte_position (array_field));
+   /* The above computation overflows to a "negative" unsigned value.
+      Drop the overflow flag.  */
+   if (TREE_CODE (DECL_FIELD_OFFSET (bounds_field)) == INTEGER_CST
+       && TREE_OVERFLOW (DECL_FIELD_OFFSET (bounds_field)))
+     DECL_FIELD_OFFSET (bounds_field)
+       = build_int_cst_wide (sizetype,
+ 			    TREE_INT_CST_LOW (DECL_FIELD_OFFSET (bounds_field)),
+ 			    TREE_INT_CST_HIGH (DECL_FIELD_OFFSET (bounds_field)));
  
    DECL_FIELD_OFFSET (array_field) = size_zero_node;
    DECL_FIELD_BIT_OFFSET (array_field) = bitsize_zero_node;
Index: trunk/gcc/ada/gcc-interface/trans.c
===================================================================
*** trunk.orig/gcc/ada/gcc-interface/trans.c	2012-03-06 16:00:03.000000000 +0100
--- trunk/gcc/ada/gcc-interface/trans.c	2012-03-06 16:02:37.000000000 +0100
*************** Attribute_to_gnu (Node_Id gnat_node, tre
*** 1959,1964 ****
--- 1959,1971 ----
        gnu_type = TYPE_OBJECT_RECORD_TYPE (gnu_type);
        gnu_result = size_binop (MINUS_EXPR, bitsize_zero_node,
                                 bit_position (TYPE_FIELDS (gnu_type)));
+       /* The above computation overflows from "negative" to positive.
+ 	 Drop the overflow flag.  */
+       if (TREE_CODE (gnu_result) == INTEGER_CST
+ 	  && TREE_OVERFLOW (gnu_result))
+ 	gnu_result = build_int_cst_wide (bitsizetype,
+ 					 TREE_INT_CST_LOW (gnu_result),
+ 					 TREE_INT_CST_HIGH (gnu_result));
        gnu_result_type = get_unpadded_type (Etype (gnat_node));
        prefix_unused = true;
        break;

then you run into the above code

      gnu_result = size_binop (MINUS_EXPR, bitsize_zero_node,
                               bit_position (TYPE_FIELDS (gnu_type)));

where bit_position computes sth way off (because the "negative" byte
offset is not sign-extended and on a 64bit HWI platform bitsizetype
has precision 64 - that makes it a poor twos-complement arithmetic
type.  Subtracting a non-sign-extended 35-bit value from 64-bit
zero makes it very off.  Now I bet there is a reason for choosing
the TYPE_PRECISION of bitsize types to match an available mode
(but never larger than 2 * HWI) - but I doubt, or at least I hope,
that we never emit code for computations in bitsizetype (which would
make the 'sizetypes never overflow'-thing not apply to bitsizetype,
as then it wouldn't be true twos-complement semantics anymore but
a-bit-more-but-not-arbitrary-precision arithmetic).

Well.  I suppose fixing that negative DECL_FIELD_OFFSET thing should
be #1 priority.

Trying what happens with a properly precisioned bitsizetype now ...

Richard.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH][1/n] No longer sign-extend sizetype constants, remove TYPE_IS_SIZETYPE
  2012-03-06 13:45 [PATCH][1/n] No longer sign-extend sizetype constants, remove TYPE_IS_SIZETYPE Richard Guenther
  2012-03-06 15:38 ` Richard Guenther
@ 2012-03-06 17:36 ` Joseph S. Myers
  2012-03-06 18:18 ` Jason Merrill
  2 siblings, 0 replies; 9+ messages in thread
From: Joseph S. Myers @ 2012-03-06 17:36 UTC (permalink / raw)
  To: Richard Guenther; +Cc: gcc-patches, jason, ebotcazou

On Tue, 6 Mar 2012, Richard Guenther wrote:

> 	* c-decl.c (grokdeclarator): Properly check for sizes that
> 	cover more than half of the address-space.

The C front-end change is OK.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH][1/n] No longer sign-extend sizetype constants, remove TYPE_IS_SIZETYPE
  2012-03-06 13:45 [PATCH][1/n] No longer sign-extend sizetype constants, remove TYPE_IS_SIZETYPE Richard Guenther
  2012-03-06 15:38 ` Richard Guenther
  2012-03-06 17:36 ` Joseph S. Myers
@ 2012-03-06 18:18 ` Jason Merrill
  2 siblings, 0 replies; 9+ messages in thread
From: Jason Merrill @ 2012-03-06 18:18 UTC (permalink / raw)
  To: Richard Guenther; +Cc: gcc-patches, Joseph S. Myers, ebotcazou

OK.

Jason

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH][1/n] No longer sign-extend sizetype constants, remove TYPE_IS_SIZETYPE
  2012-03-06 15:38 ` Richard Guenther
@ 2012-03-06 22:11   ` Eric Botcazou
  2012-03-07  9:22     ` Richard Guenther
  2012-03-09 11:54   ` Eric Botcazou
  1 sibling, 1 reply; 9+ messages in thread
From: Eric Botcazou @ 2012-03-06 22:11 UTC (permalink / raw)
  To: Richard Guenther; +Cc: gcc-patches

> Well.  I suppose fixing that negative DECL_FIELD_OFFSET thing should
> be #1 priority.

OK, let me try over the next few days.

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH][1/n] No longer sign-extend sizetype constants, remove TYPE_IS_SIZETYPE
  2012-03-06 22:11   ` Eric Botcazou
@ 2012-03-07  9:22     ` Richard Guenther
  0 siblings, 0 replies; 9+ messages in thread
From: Richard Guenther @ 2012-03-07  9:22 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: gcc-patches

On Tue, 6 Mar 2012, Eric Botcazou wrote:

> > Well.  I suppose fixing that negative DECL_FIELD_OFFSET thing should
> > be #1 priority.
> 
> OK, let me try over the next few days.

Thanks.

Btw, making [s]bitsizetype have TYPE_PRECISION of [s]sizetype plus
log2 (BITS_PER_UNIT) solves quite some issues with no longer
sign-extending sizetype constants.  A proper-precision bitsizetype
behaves more like a twos-complement type (and avoids similar
issues we have when doing "twos-complement" arithmetic on an
unsigned HOST_WIDE_INT variable that we get from a -m32
sizetype constant on a 64bit HWI host - for that we'd need a
HOST_SIZE_INT, maybe a good idea anyway?).

Richard.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH][1/n] No longer sign-extend sizetype constants, remove TYPE_IS_SIZETYPE
  2012-03-06 15:38 ` Richard Guenther
  2012-03-06 22:11   ` Eric Botcazou
@ 2012-03-09 11:54   ` Eric Botcazou
  2012-03-12 15:41     ` Richard Guenther
  1 sibling, 1 reply; 9+ messages in thread
From: Eric Botcazou @ 2012-03-09 11:54 UTC (permalink / raw)
  To: Richard Guenther; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 983 bytes --]

> Well.  I suppose fixing that negative DECL_FIELD_OFFSET thing should
> be #1 priority.

Tentative patch attached (you need an up-to-date tree).  We cannot really get 
rid of the negative offsets for thin pointers, so the patch pulls them out of 
record types and uses pointer arithmetics instead.


        * gcc-interface/gigi.h (shift_unc_components_for_thin_pointers): Kill.
        * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Array_Type>: Remove call
        to above function.
        * gcc-interface/trans.c (Attribute_to_gnu) <Attr_Pool_Address>: Adjust
        handling of thin pointers.
        <Attr_Descriptor_Size>: Likewise.
        (gnat_to_gnu) <N_Free_Statement>: Likewise.
        * gcc-interface/utils.c (shift_unc_components_for_thin_pointers): Kill.
        (convert_to_fat_pointer): Adjust handling of thin pointers.
        (convert) <POINTER_TYPE>: Likewise.
        * gcc-interface/utils2.c (build_unary_op) <INDIRECT_REF>: Likewise.


-- 
Eric Botcazou

[-- Attachment #2: ada_offsets.diff --]
[-- Type: text/x-diff, Size: 7835 bytes --]

Index: gcc-interface/utils.c
===================================================================
--- gcc-interface/utils.c	(revision 185132)
+++ gcc-interface/utils.c	(working copy)
@@ -3411,27 +3411,6 @@ build_unc_object_type_from_ptr (tree thi
   return
     build_unc_object_type (template_type, object_type, name, debug_info_p);
 }
-
-/* Shift the component offsets within an unconstrained object TYPE to make it
-   suitable for use as a designated type for thin pointers.  */
-
-void
-shift_unc_components_for_thin_pointers (tree type)
-{
-  /* Thin pointer values designate the ARRAY data of an unconstrained object,
-     allocated past the BOUNDS template.  The designated type is adjusted to
-     have ARRAY at position zero and the template at a negative offset, so
-     that COMPONENT_REFs on (*thin_ptr) designate the proper location.  */
-
-  tree bounds_field = TYPE_FIELDS (type);
-  tree array_field  = DECL_CHAIN (TYPE_FIELDS (type));
-
-  DECL_FIELD_OFFSET (bounds_field)
-    = size_binop (MINUS_EXPR, size_zero_node, byte_position (array_field));
-
-  DECL_FIELD_OFFSET (array_field) = size_zero_node;
-  DECL_FIELD_BIT_OFFSET (array_field) = bitsize_zero_node;
-}
 \f
 /* Update anything previously pointing to OLD_TYPE to point to NEW_TYPE.
    In the normal case this is just two adjustments, but we have more to
@@ -3616,7 +3595,18 @@ convert_to_fat_pointer (tree type, tree
       if (TREE_CODE (expr) == ADDR_EXPR)
 	expr = TREE_OPERAND (expr, 0);
       else
-	expr = build1 (INDIRECT_REF, TREE_TYPE (etype), expr);
+	{
+	  /* If we have a TYPE_UNCONSTRAINED_ARRAY attached to the RECORD_TYPE,
+	     the thin pointer value has been shifted so we first need to shift
+	     it back to get the template address.  */
+	  if (TYPE_UNCONSTRAINED_ARRAY (TREE_TYPE (etype)))
+	    expr
+	      = build_binary_op (POINTER_PLUS_EXPR, etype, expr,
+				 fold_build1 (NEGATE_EXPR, sizetype,
+					      byte_position
+					      (DECL_CHAIN (field))));
+	  expr = build1 (INDIRECT_REF, TREE_TYPE (etype), expr);
+	}
 
       template_tree = build_component_ref (expr, NULL_TREE, field, false);
       expr = build_unary_op (ADDR_EXPR, NULL_TREE,
@@ -4103,12 +4093,19 @@ convert (tree type, tree expr)
     case POINTER_TYPE:
     case REFERENCE_TYPE:
       /* If converting between two thin pointers, adjust if needed to account
-	 for any differing offsets, since one of them might be negative.  */
+	 for differing offsets from the base pointer, depending on whether
+	 there is a TYPE_UNCONSTRAINED_ARRAY attached to the record type.  */
       if (TYPE_IS_THIN_POINTER_P (etype) && TYPE_IS_THIN_POINTER_P (type))
 	{
-	  tree byte_diff
-	    = size_diffop (byte_position (TYPE_FIELDS (TREE_TYPE (etype))),
-			   byte_position (TYPE_FIELDS (TREE_TYPE (type))));
+	  tree etype_pos
+	    = TYPE_UNCONSTRAINED_ARRAY (TREE_TYPE (etype)) != NULL_TREE
+	      ? byte_position (DECL_CHAIN (TYPE_FIELDS (TREE_TYPE (etype))))
+	      : size_zero_node;
+	  tree type_pos
+	    = TYPE_UNCONSTRAINED_ARRAY (TREE_TYPE (type)) != NULL_TREE
+	      ? byte_position (DECL_CHAIN (TYPE_FIELDS (TREE_TYPE (type))))
+	      : size_zero_node;
+	  tree byte_diff = size_diffop (type_pos, etype_pos);
 
 	  expr = build1 (NOP_EXPR, type, expr);
 	  if (integer_zerop (byte_diff))
Index: gcc-interface/decl.c
===================================================================
--- gcc-interface/decl.c	(revision 185130)
+++ gcc-interface/decl.c	(working copy)
@@ -2280,13 +2280,14 @@ gnat_to_gnu_entity (Entity_Id gnat_entit
 			  gnu_fat_type, NULL, !Comes_From_Source (gnat_entity),
 			  debug_info_p, gnat_entity);
 
-	/* Create the type to be used as what a thin pointer designates:
-	   a record type for the object and its template with the fields
-	   shifted to have the template at a negative offset.  */
+	/* Create the type to be designated by thin pointers: a record type for
+	   the array and its template.  We used to shift the fields to have the
+	   template at a negative offset, but this was somewhat of a kludge; we
+	   now shift thin pointer values explicitly but only those which have a
+	   TYPE_UNCONSTRAINED_ARRAY attached to the designated RECORD_TYPE.  */
 	tem = build_unc_object_type (gnu_template_type, tem,
 				     create_concat_name (gnat_name, "XUT"),
 				     debug_info_p);
-	shift_unc_components_for_thin_pointers (tem);
 
 	SET_TYPE_UNCONSTRAINED_ARRAY (tem, gnu_type);
 	TYPE_OBJECT_RECORD_TYPE (gnu_type) = tem;
Index: gcc-interface/utils2.c
===================================================================
--- gcc-interface/utils2.c	(revision 185132)
+++ gcc-interface/utils2.c	(working copy)
@@ -1396,9 +1396,8 @@ build_unary_op (enum tree_code op_code,
 	    tree rec_type = TREE_TYPE (type);
 
 	    if (TREE_CODE (operand) == POINTER_PLUS_EXPR
-		&& integer_zerop
-		   (size_binop (PLUS_EXPR, TREE_OPERAND (operand, 1),
-				byte_position (TYPE_FIELDS (rec_type))))
+		&& TREE_OPERAND (operand, 1)
+		   == byte_position (DECL_CHAIN (TYPE_FIELDS (rec_type)))
 		&& TREE_CODE (TREE_OPERAND (operand, 0)) == NOP_EXPR)
 	      {
 		operand = TREE_OPERAND (TREE_OPERAND (operand, 0), 0);
Index: gcc-interface/gigi.h
===================================================================
--- gcc-interface/gigi.h	(revision 185130)
+++ gcc-interface/gigi.h	(working copy)
@@ -736,10 +736,6 @@ extern tree build_unc_object_type_from_p
 					    tree object_type, tree name,
 					    bool debug_info_p);
 
-/* Shift the component offsets within an unconstrained object TYPE to make it
-   suitable for use as a designated type for thin pointers.  */
-extern void shift_unc_components_for_thin_pointers (tree type);
-
 /* Update anything previously pointing to OLD_TYPE to point to NEW_TYPE.  In
    the normal case this is just two adjustments, but we have more to do
    if NEW is an UNCONSTRAINED_ARRAY_TYPE.  */
Index: gcc-interface/trans.c
===================================================================
--- gcc-interface/trans.c	(revision 185132)
+++ gcc-interface/trans.c	(working copy)
@@ -1439,7 +1439,10 @@ Attribute_to_gnu (Node_Id gnat_node, tre
 	  gnu_ptr
 	    = build_binary_op (POINTER_PLUS_EXPR, TREE_TYPE (gnu_ptr),
 			       gnu_ptr,
-			       byte_position (TYPE_FIELDS (gnu_obj_type)));
+			       fold_build1 (NEGATE_EXPR, sizetype,
+					    byte_position
+					    (DECL_CHAIN
+					     TYPE_FIELDS ((gnu_obj_type)))));
 
 	gnu_result = convert (gnu_result_type, gnu_ptr);
       }
@@ -1950,12 +1953,10 @@ Attribute_to_gnu (Node_Id gnat_node, tre
       gnu_type = TREE_TYPE (gnu_prefix);
       gcc_assert (TREE_CODE (gnu_type) == UNCONSTRAINED_ARRAY_TYPE);
 
-      /* What we want is the offset of the ARRAY field in the record that the
-        thin pointer designates, but the components have been shifted so this
-        is actually the opposite of the offset of the BOUNDS field.  */
+      /* What we want is the offset of the ARRAY field in the record
+	 that the thin pointer designates.  */
       gnu_type = TYPE_OBJECT_RECORD_TYPE (gnu_type);
-      gnu_result = size_binop (MINUS_EXPR, bitsize_zero_node,
-                               bit_position (TYPE_FIELDS (gnu_type)));
+      gnu_result = bit_position (DECL_CHAIN (TYPE_FIELDS (gnu_type)));
       gnu_result_type = get_unpadded_type (Etype (gnat_node));
       prefix_unused = true;
       break;
@@ -6622,7 +6623,10 @@ gnat_to_gnu (Node_Id gnat_node)
 	    gnu_ptr
 	      = build_binary_op (POINTER_PLUS_EXPR, TREE_TYPE (gnu_ptr),
 				 gnu_ptr,
-				 byte_position (TYPE_FIELDS (gnu_obj_type)));
+				 fold_build1 (NEGATE_EXPR, sizetype,
+					      byte_position
+					      (DECL_CHAIN
+					       TYPE_FIELDS ((gnu_obj_type)))));
 
 	  /* If we have a special dynamic constrained subtype on the node, use
 	     it to compute the size; otherwise, use the designated subtype.  */

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH][1/n] No longer sign-extend sizetype constants, remove TYPE_IS_SIZETYPE
  2012-03-09 11:54   ` Eric Botcazou
@ 2012-03-12 15:41     ` Richard Guenther
  2012-03-12 20:41       ` Eric Botcazou
  0 siblings, 1 reply; 9+ messages in thread
From: Richard Guenther @ 2012-03-12 15:41 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: gcc-patches

On Fri, 9 Mar 2012, Eric Botcazou wrote:

> > Well.  I suppose fixing that negative DECL_FIELD_OFFSET thing should
> > be #1 priority.
> 
> Tentative patch attached (you need an up-to-date tree).  We cannot really get 
> rid of the negative offsets for thin pointers, so the patch pulls them out of 
> record types and uses pointer arithmetics instead.

Thanks.  That seems to get me into Ada bootstrap land together with
the following two patches applied (but not when I apply only the
first patch due to the stale TREE_OVERFLOW bits on type/decl sizes).

Richard.

2012-03-06  Richard Guenther  <rguenther@suse.de>

	* tree.c (valid_constant_size_p): New function.
	* tree.h (valid_constant_size_p): Declare.
	* cfgexpand.c (expand_one_var): Adjust check for too large
	variables by using valid_constant_size_p.
	* varasm.c (assemble_variable): Likewise.

	c/
	* c-decl.c (grokdeclarator): Properly check for sizes that
	cover more than half of the address-space.

	cp/
	* decl.c (grokdeclarator): Properly check for sizes that
	cover more than half of the address-space.

Index: trunk/gcc/tree.c
===================================================================
*** trunk.orig/gcc/tree.c	2012-03-06 13:54:25.000000000 +0100
--- trunk/gcc/tree.c	2012-03-06 14:46:08.000000000 +0100
*************** compare_tree_int (const_tree t, unsigned
*** 6829,6834 ****
--- 6829,6848 ----
      return 1;
  }
  
+ /* Return true if SIZE represents a constant size that is in bounds of
+    what the middle-end and the backend accepts (covering not more than
+    half of the address-space).  */
+ 
+ bool
+ valid_constant_size_p (const_tree size)
+ {
+   if (! host_integerp (size, 1)
+       || TREE_OVERFLOW (size)
+       || tree_int_cst_sign_bit (size) != 0)
+     return false;
+   return true;
+ }
+ 
  /* Return true if CODE represents an associative tree code.  Otherwise
     return false.  */
  bool
Index: trunk/gcc/varasm.c
===================================================================
*** trunk.orig/gcc/varasm.c	2012-03-06 13:54:25.000000000 +0100
--- trunk/gcc/varasm.c	2012-03-06 14:46:08.000000000 +0100
*************** assemble_variable (tree decl, int top_le
*** 1987,1993 ****
      return;
  
    if (! dont_output_data
!       && ! host_integerp (DECL_SIZE_UNIT (decl), 1))
      {
        error ("size of variable %q+D is too large", decl);
        return;
--- 1987,1993 ----
      return;
  
    if (! dont_output_data
!       && ! valid_constant_size_p (DECL_SIZE_UNIT (decl)))
      {
        error ("size of variable %q+D is too large", decl);
        return;
Index: trunk/gcc/c-decl.c
===================================================================
*** trunk.orig/gcc/c-decl.c	2012-03-06 13:54:25.000000000 +0100
--- trunk/gcc/c-decl.c	2012-03-06 14:46:08.000000000 +0100
*************** grokdeclarator (const struct c_declarato
*** 5798,5809 ****
  	}
      }
  
!   /* Did array size calculations overflow?  */
! 
    if (TREE_CODE (type) == ARRAY_TYPE
        && COMPLETE_TYPE_P (type)
        && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST
!       && TREE_OVERFLOW (TYPE_SIZE_UNIT (type)))
      {
        if (name)
  	error_at (loc, "size of array %qE is too large", name);
--- 5798,5809 ----
  	}
      }
  
!   /* Did array size calculations overflow or does the array cover more
!      than half of the address-space?  */
    if (TREE_CODE (type) == ARRAY_TYPE
        && COMPLETE_TYPE_P (type)
        && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST
!       && ! valid_constant_size_p (TYPE_SIZE_UNIT (type)))
      {
        if (name)
  	error_at (loc, "size of array %qE is too large", name);
Index: trunk/gcc/cp/decl.c
===================================================================
*** trunk.orig/gcc/cp/decl.c	2012-03-06 13:54:25.000000000 +0100
--- trunk/gcc/cp/decl.c	2012-03-06 14:46:08.000000000 +0100
*************** grokdeclarator (const cp_declarator *dec
*** 9635,9646 ****
          error ("non-parameter %qs cannot be a parameter pack", name);
      }
  
!   /* Did array size calculations overflow?  */
! 
    if (TREE_CODE (type) == ARRAY_TYPE
        && COMPLETE_TYPE_P (type)
        && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST
!       && TREE_OVERFLOW (TYPE_SIZE_UNIT (type)))
      {
        error ("size of array %qs is too large", name);
        /* If we proceed with the array type as it is, we'll eventually
--- 9635,9646 ----
          error ("non-parameter %qs cannot be a parameter pack", name);
      }
  
!   /* Did array size calculations overflow or does the array cover more
!      than half of the address-space?  */
    if (TREE_CODE (type) == ARRAY_TYPE
        && COMPLETE_TYPE_P (type)
        && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST
!       && ! valid_constant_size_p (TYPE_SIZE_UNIT (type)))
      {
        error ("size of array %qs is too large", name);
        /* If we proceed with the array type as it is, we'll eventually
Index: trunk/gcc/cfgexpand.c
===================================================================
*** trunk.orig/gcc/cfgexpand.c	2012-03-06 13:54:25.000000000 +0100
--- trunk/gcc/cfgexpand.c	2012-03-06 14:46:08.000000000 +0100
*************** expand_one_var (tree var, bool toplevel,
*** 1238,1245 ****
        if (really_expand)
          expand_one_register_var (origvar);
      }
!   else if (!host_integerp (DECL_SIZE_UNIT (var), 1))
      {
        if (really_expand)
  	{
  	  error ("size of variable %q+D is too large", var);
--- 1238,1246 ----
        if (really_expand)
          expand_one_register_var (origvar);
      }
!   else if (! valid_constant_size_p (DECL_SIZE_UNIT (var)))
      {
+       /* Reject variables which cover more than half of the address-space.  */
        if (really_expand)
  	{
  	  error ("size of variable %q+D is too large", var);
Index: trunk/gcc/tree.h
===================================================================
*** trunk.orig/gcc/tree.h	2012-03-06 13:54:25.000000000 +0100
--- trunk/gcc/tree.h	2012-03-06 14:46:08.000000000 +0100
*************** extern bool tree_expr_nonnegative_warnv_
*** 4439,4444 ****
--- 4439,4445 ----
  extern bool may_negate_without_overflow_p (const_tree);
  extern tree strip_array_types (tree);
  extern tree excess_precision_type (tree);
+ extern bool valid_constant_size_p (const_tree);
  
  /* Construct various nodes representing fract or accum data types.  */
  


2012-03-06  Richard Guenther  <rguenther@suse.de>

	* fold-const.c (div_if_zero_remainder): sizetypes no longer
	sign-extend.
	(int_const_binop_1): New worker for int_const_binop with
	overflowable parameter.  Pass it through
	to force_fit_type_double.
	(int_const_binop): Wrap around int_const_binop_1 with overflowable
	equal to one.
	(size_binop_loc): Call int_const_binop_1 with overflowable equal
	to minus one, forcing overflow detection for even unsigned types.
	(extract_muldiv_1): Remove bogus TYPE_IS_SIZETYPE special-casing.
	(fold_binary_loc): Call try_move_mult_to_index with signed offset.
	* stor-layout.c (initialize_sizetypes): sizetypes no longer
	sign-extend.
	(layout_type): For zero-sized arrays ignore overflow on the
	size calculations.
	* tree-ssa-ccp.c (bit_value_unop_1): Likewise.
	(bit_value_binop_1): Likewise.
	* tree.c (double_int_to_tree): Likewise.
	(double_int_fits_to_tree_p): Likewise.
	(force_fit_type_double): Likewise.
	(host_integerp): Likewise.
	(int_fits_type_p): Likewise.
	* varasm.c (output_constructor_regular_field): Sign-extend the
	field-offset to cater for negative offsets produced by the Ada frontend.
	* omp-low.c (extract_omp_for_data): Convert the loop step to
	signed for pointer adjustments.

	* g++.dg/tree-ssa/pr19807.C: Adjust.

Index: trunk/gcc/fold-const.c
===================================================================
*** trunk.orig/gcc/fold-const.c	2012-03-06 12:41:10.000000000 +0100
--- trunk/gcc/fold-const.c	2012-03-06 14:46:25.000000000 +0100
*************** div_if_zero_remainder (enum tree_code co
*** 191,199 ****
       does the correct thing for POINTER_PLUS_EXPR where we want
       a signed division.  */
    uns = TYPE_UNSIGNED (TREE_TYPE (arg2));
-   if (TREE_CODE (TREE_TYPE (arg2)) == INTEGER_TYPE
-       && TYPE_IS_SIZETYPE (TREE_TYPE (arg2)))
-     uns = false;
  
    quo = double_int_divmod (tree_to_double_int (arg1),
  			   tree_to_double_int (arg2),
--- 191,196 ----
*************** int_binop_types_match_p (enum tree_code
*** 935,942 ****
     to produce a new constant.  Return NULL_TREE if we don't know how
     to evaluate CODE at compile-time.  */
  
! tree
! int_const_binop (enum tree_code code, const_tree arg1, const_tree arg2)
  {
    double_int op1, op2, res, tmp;
    tree t;
--- 932,940 ----
     to produce a new constant.  Return NULL_TREE if we don't know how
     to evaluate CODE at compile-time.  */
  
! static tree
! int_const_binop_1 (enum tree_code code, const_tree arg1, const_tree arg2,
! 		   int overflowable)
  {
    double_int op1, op2, res, tmp;
    tree t;
*************** int_const_binop (enum tree_code code, co
*** 1078,1090 ****
        return NULL_TREE;
      }
  
!   t = force_fit_type_double (TREE_TYPE (arg1), res, 1,
  			     ((!uns || is_sizetype) && overflow)
  			     | TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2));
  
    return t;
  }
  
  /* Combine two constants ARG1 and ARG2 under operation CODE to produce a new
     constant.  We assume ARG1 and ARG2 have the same data type, or at least
     are the same kind of constant and the same machine mode.  Return zero if
--- 1076,1094 ----
        return NULL_TREE;
      }
  
!   t = force_fit_type_double (TREE_TYPE (arg1), res, overflowable,
  			     ((!uns || is_sizetype) && overflow)
  			     | TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2));
  
    return t;
  }
  
+ tree
+ int_const_binop (enum tree_code code, const_tree arg1, const_tree arg2)
+ {
+   return int_const_binop_1 (code, arg1, arg2, 1);
+ }
+ 
  /* Combine two constants ARG1 and ARG2 under operation CODE to produce a new
     constant.  We assume ARG1 and ARG2 have the same data type, or at least
     are the same kind of constant and the same machine mode.  Return zero if
*************** size_binop_loc (location_t loc, enum tre
*** 1445,1452 ****
  	    return arg1;
  	}
  
!       /* Handle general case of two integer constants.  */
!       return int_const_binop (code, arg0, arg1);
      }
  
    return fold_build2_loc (loc, code, type, arg0, arg1);
--- 1449,1458 ----
  	    return arg1;
  	}
  
!       /* Handle general case of two integer constants.  For sizetype
!          constant calculations we always want to know about overflow,
! 	 even in the unsigned case.  */
!       return int_const_binop_1 (code, arg0, arg1, -1);
      }
  
    return fold_build2_loc (loc, code, type, arg0, arg1);
*************** extract_muldiv_1 (tree t, tree c, enum t
*** 5924,5934 ****
  	 multiple of the other, in which case we replace this with either an
  	 operation or CODE or TCODE.
  
! 	 If we have an unsigned type that is not a sizetype, we cannot do
! 	 this since it will change the result if the original computation
! 	 overflowed.  */
!       if ((TYPE_OVERFLOW_UNDEFINED (ctype)
! 	   || (TREE_CODE (ctype) == INTEGER_TYPE && TYPE_IS_SIZETYPE (ctype)))
  	  && ((code == MULT_EXPR && tcode == EXACT_DIV_EXPR)
  	      || (tcode == MULT_EXPR
  		  && code != TRUNC_MOD_EXPR && code != CEIL_MOD_EXPR
--- 5930,5938 ----
  	 multiple of the other, in which case we replace this with either an
  	 operation or CODE or TCODE.
  
! 	 If we have an unsigned type, we cannot do this since it will change
! 	 the result if the original computation overflowed.  */
!       if (TYPE_OVERFLOW_UNDEFINED (ctype)
  	  && ((code == MULT_EXPR && tcode == EXACT_DIV_EXPR)
  	      || (tcode == MULT_EXPR
  		  && code != TRUNC_MOD_EXPR && code != CEIL_MOD_EXPR
*************** fold_binary_loc (location_t loc,
*** 9953,9959 ****
        if (TREE_CODE (arg0) == ADDR_EXPR)
  	{
  	  tem = try_move_mult_to_index (loc, arg0,
! 					fold_convert_loc (loc, sizetype, arg1));
  	  if (tem)
  	    return fold_convert_loc (loc, type, tem);
  	}
--- 9957,9964 ----
        if (TREE_CODE (arg0) == ADDR_EXPR)
  	{
  	  tem = try_move_mult_to_index (loc, arg0,
! 					fold_convert_loc (loc,
! 							  ssizetype, arg1));
  	  if (tem)
  	    return fold_convert_loc (loc, type, tem);
  	}
Index: trunk/gcc/stor-layout.c
===================================================================
*** trunk.orig/gcc/stor-layout.c	2012-03-06 11:36:46.000000000 +0100
--- trunk/gcc/stor-layout.c	2012-03-06 14:46:25.000000000 +0100
*************** layout_type (tree type)
*** 1970,1975 ****
--- 1970,1983 ----
  					    build_int_cst (TREE_TYPE (lb), 1),
  					    size_binop (MINUS_EXPR, ub, lb)));
  
+ 	    /* If we arrived at a length of zero ignore any overflow
+ 	       that occured as part of the calculation.  There exists
+ 	       an association of the plus one where that overflow would
+ 	       not happen.  */
+ 	    if (integer_zerop (length)
+ 		&& TREE_OVERFLOW (length))
+ 	      length = size_zero_node;
+ 
  	    TYPE_SIZE (type) = size_binop (MULT_EXPR, element_size,
  					   fold_convert (bitsizetype,
  							 length));
*************** initialize_sizetypes (void)
*** 2235,2245 ****
    TYPE_SIZE_UNIT (sizetype) = size_int (GET_MODE_SIZE (TYPE_MODE (sizetype)));
    set_min_and_max_values_for_integral_type (sizetype, precision,
  					    /*is_unsigned=*/true);
-   /* sizetype is unsigned but we need to fix TYPE_MAX_VALUE so that it is
-      sign-extended in a way consistent with force_fit_type.  */
-   TYPE_MAX_VALUE (sizetype)
-     = double_int_to_tree (sizetype,
- 			  tree_to_double_int (TYPE_MAX_VALUE (sizetype)));
  
    SET_TYPE_MODE (bitsizetype, smallest_mode_for_size (bprecision, MODE_INT));
    TYPE_ALIGN (bitsizetype) = GET_MODE_ALIGNMENT (TYPE_MODE (bitsizetype));
--- 2243,2248 ----
*************** initialize_sizetypes (void)
*** 2248,2258 ****
      = size_int (GET_MODE_SIZE (TYPE_MODE (bitsizetype)));
    set_min_and_max_values_for_integral_type (bitsizetype, bprecision,
  					    /*is_unsigned=*/true);
-   /* bitsizetype is unsigned but we need to fix TYPE_MAX_VALUE so that it is
-      sign-extended in a way consistent with force_fit_type.  */
-   TYPE_MAX_VALUE (bitsizetype)
-     = double_int_to_tree (bitsizetype,
- 			  tree_to_double_int (TYPE_MAX_VALUE (bitsizetype)));
  
    /* Create the signed variants of *sizetype.  */
    ssizetype = make_signed_type (TYPE_PRECISION (sizetype));
--- 2251,2256 ----
Index: trunk/gcc/tree-ssa-ccp.c
===================================================================
*** trunk.orig/gcc/tree-ssa-ccp.c	2012-03-06 11:36:46.000000000 +0100
--- trunk/gcc/tree-ssa-ccp.c	2012-03-06 14:46:25.000000000 +0100
*************** bit_value_unop_1 (enum tree_code code, t
*** 1101,1114 ****
  	bool uns;
  
  	/* First extend mask and value according to the original type.  */
! 	uns = (TREE_CODE (rtype) == INTEGER_TYPE && TYPE_IS_SIZETYPE (rtype)
! 	       ? 0 : TYPE_UNSIGNED (rtype));
  	*mask = double_int_ext (rmask, TYPE_PRECISION (rtype), uns);
  	*val = double_int_ext (rval, TYPE_PRECISION (rtype), uns);
  
  	/* Then extend mask and value according to the target type.  */
! 	uns = (TREE_CODE (type) == INTEGER_TYPE && TYPE_IS_SIZETYPE (type)
! 	       ? 0 : TYPE_UNSIGNED (type));
  	*mask = double_int_ext (*mask, TYPE_PRECISION (type), uns);
  	*val = double_int_ext (*val, TYPE_PRECISION (type), uns);
  	break;
--- 1101,1112 ----
  	bool uns;
  
  	/* First extend mask and value according to the original type.  */
! 	uns = TYPE_UNSIGNED (rtype);
  	*mask = double_int_ext (rmask, TYPE_PRECISION (rtype), uns);
  	*val = double_int_ext (rval, TYPE_PRECISION (rtype), uns);
  
  	/* Then extend mask and value according to the target type.  */
! 	uns = TYPE_UNSIGNED (type);
  	*mask = double_int_ext (*mask, TYPE_PRECISION (type), uns);
  	*val = double_int_ext (*val, TYPE_PRECISION (type), uns);
  	break;
*************** bit_value_binop_1 (enum tree_code code,
*** 1130,1137 ****
  		   tree r1type, double_int r1val, double_int r1mask,
  		   tree r2type, double_int r2val, double_int r2mask)
  {
!   bool uns = (TREE_CODE (type) == INTEGER_TYPE
! 	      && TYPE_IS_SIZETYPE (type) ? 0 : TYPE_UNSIGNED (type));
    /* Assume we'll get a constant result.  Use an initial varying value,
       we fall back to varying in the end if necessary.  */
    *mask = double_int_minus_one;
--- 1128,1134 ----
  		   tree r1type, double_int r1val, double_int r1mask,
  		   tree r2type, double_int r2val, double_int r2mask)
  {
!   bool uns = TYPE_UNSIGNED (type);
    /* Assume we'll get a constant result.  Use an initial varying value,
       we fall back to varying in the end if necessary.  */
    *mask = double_int_minus_one;
*************** bit_value_binop_1 (enum tree_code code,
*** 1198,1210 ****
  	    }
  	  else if (shift < 0)
  	    {
- 	      /* ???  We can have sizetype related inconsistencies in
- 		 the IL.  */
- 	      if ((TREE_CODE (r1type) == INTEGER_TYPE
- 		   && (TYPE_IS_SIZETYPE (r1type)
- 		       ? 0 : TYPE_UNSIGNED (r1type))) != uns)
- 		break;
- 
  	      shift = -shift;
  	      *mask = double_int_rshift (r1mask, shift,
  					 TYPE_PRECISION (type), !uns);
--- 1195,1200 ----
*************** bit_value_binop_1 (enum tree_code code,
*** 1316,1327 ****
  	  break;
  
  	/* For comparisons the signedness is in the comparison operands.  */
! 	uns = (TREE_CODE (r1type) == INTEGER_TYPE
! 	       && TYPE_IS_SIZETYPE (r1type) ? 0 : TYPE_UNSIGNED (r1type));
! 	/* ???  We can have sizetype related inconsistencies in the IL.  */
! 	if ((TREE_CODE (r2type) == INTEGER_TYPE
! 	     && TYPE_IS_SIZETYPE (r2type) ? 0 : TYPE_UNSIGNED (r2type)) != uns)
! 	  break;
  
  	/* If we know the most significant bits we know the values
  	   value ranges by means of treating varying bits as zero
--- 1306,1312 ----
  	  break;
  
  	/* For comparisons the signedness is in the comparison operands.  */
! 	uns = TYPE_UNSIGNED (r1type);
  
  	/* If we know the most significant bits we know the values
  	   value ranges by means of treating varying bits as zero
Index: trunk/gcc/tree.c
===================================================================
*** trunk.orig/gcc/tree.c	2012-03-06 14:46:08.000000000 +0100
--- trunk/gcc/tree.c	2012-03-06 14:53:36.000000000 +0100
*************** tree
*** 1059,1067 ****
  double_int_to_tree (tree type, double_int cst)
  {
    /* Size types *are* sign extended.  */
!   bool sign_extended_type = (!TYPE_UNSIGNED (type)
! 			     || (TREE_CODE (type) == INTEGER_TYPE
! 				 && TYPE_IS_SIZETYPE (type)));
  
    cst = double_int_ext (cst, TYPE_PRECISION (type), !sign_extended_type);
  
--- 1059,1065 ----
  double_int_to_tree (tree type, double_int cst)
  {
    /* Size types *are* sign extended.  */
!   bool sign_extended_type = !TYPE_UNSIGNED (type);
  
    cst = double_int_ext (cst, TYPE_PRECISION (type), !sign_extended_type);
  
*************** bool
*** 1075,1083 ****
  double_int_fits_to_tree_p (const_tree type, double_int cst)
  {
    /* Size types *are* sign extended.  */
!   bool sign_extended_type = (!TYPE_UNSIGNED (type)
! 			     || (TREE_CODE (type) == INTEGER_TYPE
! 				 && TYPE_IS_SIZETYPE (type)));
  
    double_int ext
      = double_int_ext (cst, TYPE_PRECISION (type), !sign_extended_type);
--- 1073,1079 ----
  double_int_fits_to_tree_p (const_tree type, double_int cst)
  {
    /* Size types *are* sign extended.  */
!   bool sign_extended_type = !TYPE_UNSIGNED (type);
  
    double_int ext
      = double_int_ext (cst, TYPE_PRECISION (type), !sign_extended_type);
*************** force_fit_type_double (tree type, double
*** 1107,1115 ****
    bool sign_extended_type;
  
    /* Size types *are* sign extended.  */
!   sign_extended_type = (!TYPE_UNSIGNED (type)
!                         || (TREE_CODE (type) == INTEGER_TYPE
!                             && TYPE_IS_SIZETYPE (type)));
  
    /* If we need to set overflow flags, return a new unshared node.  */
    if (overflowed || !double_int_fits_to_tree_p(type, cst))
--- 1103,1109 ----
    bool sign_extended_type;
  
    /* Size types *are* sign extended.  */
!   sign_extended_type = !TYPE_UNSIGNED (type);
  
    /* If we need to set overflow flags, return a new unshared node.  */
    if (overflowed || !double_int_fits_to_tree_p(type, cst))
*************** host_integerp (const_tree t, int pos)
*** 6532,6540 ****
  	       && (HOST_WIDE_INT) TREE_INT_CST_LOW (t) >= 0)
  	      || (! pos && TREE_INT_CST_HIGH (t) == -1
  		  && (HOST_WIDE_INT) TREE_INT_CST_LOW (t) < 0
! 		  && (!TYPE_UNSIGNED (TREE_TYPE (t))
! 		      || (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE
! 			  && TYPE_IS_SIZETYPE (TREE_TYPE (t)))))
  	      || (pos && TREE_INT_CST_HIGH (t) == 0)));
  }
  
--- 6526,6532 ----
  	       && (HOST_WIDE_INT) TREE_INT_CST_LOW (t) >= 0)
  	      || (! pos && TREE_INT_CST_HIGH (t) == -1
  		  && (HOST_WIDE_INT) TREE_INT_CST_LOW (t) < 0
! 		  && !TYPE_UNSIGNED (TREE_TYPE (t)))
  	      || (pos && TREE_INT_CST_HIGH (t) == 0)));
  }
  
*************** int_fits_type_p (const_tree c, const_tre
*** 8264,8281 ****
    dc = tree_to_double_int (c);
    unsc = TYPE_UNSIGNED (TREE_TYPE (c));
  
-   if (TREE_CODE (TREE_TYPE (c)) == INTEGER_TYPE
-       && TYPE_IS_SIZETYPE (TREE_TYPE (c))
-       && unsc)
-     /* So c is an unsigned integer whose type is sizetype and type is not.
-        sizetype'd integers are sign extended even though they are
-        unsigned. If the integer value fits in the lower end word of c,
-        and if the higher end word has all its bits set to 1, that
-        means the higher end bits are set to 1 only for sign extension.
-        So let's convert c into an equivalent zero extended unsigned
-        integer.  */
-     dc = double_int_zext (dc, TYPE_PRECISION (TREE_TYPE (c)));
- 
  retry:
    type_low_bound = TYPE_MIN_VALUE (type);
    type_high_bound = TYPE_MAX_VALUE (type);
--- 8256,8261 ----
*************** retry:
*** 8294,8303 ****
    if (type_low_bound && TREE_CODE (type_low_bound) == INTEGER_CST)
      {
        dd = tree_to_double_int (type_low_bound);
-       if (TREE_CODE (type) == INTEGER_TYPE
- 	  && TYPE_IS_SIZETYPE (type)
- 	  && TYPE_UNSIGNED (type))
- 	dd = double_int_zext (dd, TYPE_PRECISION (type));
        if (unsc != TYPE_UNSIGNED (TREE_TYPE (type_low_bound)))
  	{
  	  int c_neg = (!unsc && double_int_negative_p (dc));
--- 8274,8279 ----
*************** retry:
*** 8319,8328 ****
    if (type_high_bound && TREE_CODE (type_high_bound) == INTEGER_CST)
      {
        dd = tree_to_double_int (type_high_bound);
-       if (TREE_CODE (type) == INTEGER_TYPE
- 	  && TYPE_IS_SIZETYPE (type)
- 	  && TYPE_UNSIGNED (type))
- 	dd = double_int_zext (dd, TYPE_PRECISION (type));
        if (unsc != TYPE_UNSIGNED (TREE_TYPE (type_high_bound)))
  	{
  	  int c_neg = (!unsc && double_int_negative_p (dc));
--- 8295,8300 ----
Index: trunk/gcc/varasm.c
===================================================================
*** trunk.orig/gcc/varasm.c	2012-03-06 14:46:08.000000000 +0100
--- trunk/gcc/varasm.c	2012-03-06 14:48:30.000000000 +0100
*************** output_constructor_regular_field (oc_loc
*** 4756,4764 ****
  
    if (local->index != NULL_TREE)
      {
        double_int idx = double_int_sub (tree_to_double_int (local->index),
  				       tree_to_double_int (local->min_index));
!       gcc_assert (double_int_fits_in_shwi_p (idx));
        fieldpos = (tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (local->val)), 1)
  		  * idx.low);
      }
--- 4756,4768 ----
  
    if (local->index != NULL_TREE)
      {
+       /* Perform the index calculation in modulo arithmetic but
+ 	 sign-extend the result because Ada has negative DECL_FIELD_OFFSETs
+ 	 but we are using an unsigned sizetype.  */
+       unsigned prec = TYPE_PRECISION (sizetype);
        double_int idx = double_int_sub (tree_to_double_int (local->index),
  				       tree_to_double_int (local->min_index));
!       idx = double_int_sext (idx, prec);
        fieldpos = (tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (local->val)), 1)
  		  * idx.low);
      }
Index: trunk/gcc/omp-low.c
===================================================================
*** trunk.orig/gcc/omp-low.c	2012-03-06 11:36:46.000000000 +0100
--- trunk/gcc/omp-low.c	2012-03-06 14:46:25.000000000 +0100
*************** extract_omp_for_data (gimple for_stmt, s
*** 336,344 ****
        switch (TREE_CODE (t))
  	{
  	case PLUS_EXPR:
- 	case POINTER_PLUS_EXPR:
  	  loop->step = TREE_OPERAND (t, 1);
  	  break;
  	case MINUS_EXPR:
  	  loop->step = TREE_OPERAND (t, 1);
  	  loop->step = fold_build1_loc (loc,
--- 336,346 ----
        switch (TREE_CODE (t))
  	{
  	case PLUS_EXPR:
  	  loop->step = TREE_OPERAND (t, 1);
  	  break;
+ 	case POINTER_PLUS_EXPR:
+ 	  loop->step = fold_convert (ssizetype, TREE_OPERAND (t, 1));
+ 	  break;
  	case MINUS_EXPR:
  	  loop->step = TREE_OPERAND (t, 1);
  	  loop->step = fold_build1_loc (loc,
Index: trunk/gcc/testsuite/g++.dg/tree-ssa/pr19807.C
===================================================================
*** trunk.orig/gcc/testsuite/g++.dg/tree-ssa/pr19807.C	2012-03-06 11:36:46.000000000 +0100
--- trunk/gcc/testsuite/g++.dg/tree-ssa/pr19807.C	2012-03-06 14:46:25.000000000 +0100
*************** void bar(int i)
*** 25,30 ****
     Simply test for the existence of +1 and -1 once, which also ensures
     the above.  If the addition/subtraction would be applied to the
     pointer we would instead see +-4 (or 8, depending on sizeof(int)).  */
! /* { dg-final { scan-tree-dump-times "\\\+ -1;" 1 "optimized" } } */
  /* { dg-final { scan-tree-dump-times "\\\+ 1;" 1 "optimized" } } */
  /* { dg-final { cleanup-tree-dump "optimized" } } */
--- 25,30 ----
     Simply test for the existence of +1 and -1 once, which also ensures
     the above.  If the addition/subtraction would be applied to the
     pointer we would instead see +-4 (or 8, depending on sizeof(int)).  */
! /* { dg-final { scan-tree-dump "\\\+ (0x0f*|18446744073709551615|4294967295|-1);" "optimized" } } */
  /* { dg-final { scan-tree-dump-times "\\\+ 1;" 1 "optimized" } } */
  /* { dg-final { cleanup-tree-dump "optimized" } } */

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH][1/n] No longer sign-extend sizetype constants, remove TYPE_IS_SIZETYPE
  2012-03-12 15:41     ` Richard Guenther
@ 2012-03-12 20:41       ` Eric Botcazou
  0 siblings, 0 replies; 9+ messages in thread
From: Eric Botcazou @ 2012-03-12 20:41 UTC (permalink / raw)
  To: Richard Guenther; +Cc: gcc-patches

> Thanks.  That seems to get me into Ada bootstrap land together with
> the following two patches applied (but not when I apply only the
> first patch due to the stale TREE_OVERFLOW bits on type/decl sizes).

You're welcome.  Let me give them a whirl...

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2012-03-12 20:41 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-03-06 13:45 [PATCH][1/n] No longer sign-extend sizetype constants, remove TYPE_IS_SIZETYPE Richard Guenther
2012-03-06 15:38 ` Richard Guenther
2012-03-06 22:11   ` Eric Botcazou
2012-03-07  9:22     ` Richard Guenther
2012-03-09 11:54   ` Eric Botcazou
2012-03-12 15:41     ` Richard Guenther
2012-03-12 20:41       ` Eric Botcazou
2012-03-06 17:36 ` Joseph S. Myers
2012-03-06 18:18 ` Jason Merrill

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).