[PATCH] Improve MIN_EXPR/MAX_EXPR constant folding

Eric Botcazou ebotcazou@adacore.com
Sat Jan 14 13:00:00 GMT 2006


Hi,

The attached Ada testcase triggers an ICE in the gimplifier

eric@linux:~/build/gcc/native> gcc/xgcc -Bgcc -S bug_list.adb
+===========================GNAT BUG DETECTED==============================+
| 4.2.0 20060108 (experimental) (x86_64-suse-linux-gnu) GCC error:         |
| in create_tmp_var, at gimplify.c:410                                     |
| Error detected at bug_list.adb:9:8

because the compiler is trying to create a temporary with a variable-sized 
type.  It turns out that the type actually has a fixed size, but the 
expression of the size is of the form:

PLUS_EXPR 
 /      \
4     MULT_EXPR
      /      \
     4      MIN_EXPR
            /     \
           0     MAX_EXPR
                 /     \
                0     ...

The calculation's type is signed (long int sizetype) so the compiler cannot 
constant-fold the tree to 4.  The proposed fix is to teach fold how to 
simplify MIN (MAX (arg, val), val) and its sibling expression.

The fix triggers a tree checking failure in place_field on c52103g because of 
an inconsistency in the code:

  /* Now add size of this field to the size of the record.  If the size is
     not constant, treat the field as being a multiple of bytes and just
     adjust the offset, resetting the bit position.  Otherwise, apportion the
     size amongst the bit position and offset.  First handle the case of an
     unspecified size, which can happen when we have an invalid nested struct
     definition, such as struct j { struct j { int i; } }.  The error message
     is printed in finish_struct.  */
  if (DECL_SIZE (field) == 0)
    /* Do nothing.  */;
  else if (TREE_CODE (DECL_SIZE_UNIT (field)) != INTEGER_CST
	   || TREE_CONSTANT_OVERFLOW (DECL_SIZE_UNIT (field)))
    {
      rli->offset
	= size_binop (PLUS_EXPR, rli->offset,
		      fold_convert (sizetype,
				    size_binop (CEIL_DIV_EXPR, rli->bitpos,
						bitsize_unit_node)));
      rli->offset
	= size_binop (PLUS_EXPR, rli->offset, DECL_SIZE_UNIT (field));
      rli->bitpos = bitsize_zero_node;
      rli->offset_align = MIN (rli->offset_align, desired_align);
    }
  else
    {
      rli->bitpos = size_binop (PLUS_EXPR, rli->bitpos, DECL_SIZE (field));
      normalize_rli (rli);
    }

rli->bitpos must be an INTEGER_CST and that is checked in normalize_offset 
through the call to normalize_rli, so DECL_SIZE (field) must be an 
INTEGER_CST.  But the test is on DECL_SIZE_UNIT (field) and the latter is
an INTEGER_CST while the former is not (the constant folder has folded 
DECL_SIZE_UNIT (field) but not DECL_SIZE (field) because it is more complex).

Bootstrapped/regtested on x86_64-linux-gnu.  OK for mainline?


2006-01-14  Eric Botcazou  <ebotcazou@adacore.com>

	* fold-const.c (fold_binary) <MIN_EXPR>: For integral types,
	simplify MIN (MAX (arg, val), val)	
	<MAX_EXPR>: For integral types, simplify MAX (MIN (arg, val), val).
	* stor-layout.c (place_field): Use DECL_SIZE consistently in the
	computation of the new record size.


-- 
Eric Botcazou
-------------- next part --------------
A non-text attachment was scrubbed...
Name: bug_tt.ads
Type: text/x-adasrc
Size: 109 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20060114/43e09e3c/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: bug_list.ads
Type: text/x-adasrc
Size: 454 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20060114/43e09e3c/attachment-0001.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: bug_list.adb
Type: text/x-adasrc
Size: 301 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20060114/43e09e3c/attachment-0002.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: eb28-011_41.diff
Type: text/x-diff
Size: 2191 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20060114/43e09e3c/attachment-0003.bin>


More information about the Gcc-patches mailing list