[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