This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Ada] Fix ACATS failures on PowerPC/Linux
- From: Eric Botcazou <ebotcazou at adacore dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 8 Sep 2011 23:14:09 +0200
- Subject: [Ada] Fix ACATS failures on PowerPC/Linux
This fixes the 6 ACATS failures present at -O2 on PowerPC/Linux:
FAIL: cd1009a
FAIL: cd1009i
FAIL: cd1c03a
FAIL: cd2a21c
FAIL: cd2a24a
FAIL: cd2a32a
The problem is a very aggressive SCCVN pass looking through a special view
conversion we build in gigi. The optimization relies exclusively on types of
bitfields in lieu of their sizes and this doesn't play nice with this view
conversion. The patch adjusts the types so as to make the pass happy.
Tested on x86-64/Linux and PowerPC/Linux, applied on the mainline.
2011-09-08 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/utils.c (unchecked_convert): Use a field of the right
precision when converting to or from an integral type whose precision
is not equal to its size.
--
Eric Botcazou
Index: gcc-interface/utils.c
===================================================================
--- gcc-interface/utils.c (revision 178601)
+++ gcc-interface/utils.c (working copy)
@@ -4403,39 +4403,60 @@ unchecked_convert (tree type, tree expr,
}
/* If we are converting to an integral type whose precision is not equal
- to its size, first unchecked convert to a record that contains an
- object of the output type. Then extract the field. */
+ to its size, first unchecked convert to a record type that contains an
+ field of the given precision. Then extract the field. */
else if (INTEGRAL_TYPE_P (type)
&& TYPE_RM_SIZE (type)
&& 0 != compare_tree_int (TYPE_RM_SIZE (type),
GET_MODE_BITSIZE (TYPE_MODE (type))))
{
tree rec_type = make_node (RECORD_TYPE);
- tree field = create_field_decl (get_identifier ("OBJ"), type, rec_type,
- NULL_TREE, NULL_TREE, 1, 0);
+ unsigned HOST_WIDE_INT prec = TREE_INT_CST_LOW (TYPE_RM_SIZE (type));
+ tree field_type, field;
+
+ if (TYPE_UNSIGNED (type))
+ field_type = make_unsigned_type (prec);
+ else
+ field_type = make_signed_type (prec);
+ SET_TYPE_RM_SIZE (field_type, TYPE_RM_SIZE (type));
+
+ field = create_field_decl (get_identifier ("OBJ"), field_type, rec_type,
+ NULL_TREE, NULL_TREE, 1, 0);
TYPE_FIELDS (rec_type) = field;
layout_type (rec_type);
expr = unchecked_convert (rec_type, expr, notrunc_p);
expr = build_component_ref (expr, NULL_TREE, field, false);
+ expr = fold_build1 (NOP_EXPR, type, expr);
}
- /* Similarly if we are converting from an integral type whose precision
- is not equal to its size. */
+ /* Similarly if we are converting from an integral type whose precision is
+ not equal to its size, first copy into a field of the given precision
+ and unchecked convert the record type. */
else if (INTEGRAL_TYPE_P (etype)
&& TYPE_RM_SIZE (etype)
&& 0 != compare_tree_int (TYPE_RM_SIZE (etype),
GET_MODE_BITSIZE (TYPE_MODE (etype))))
{
tree rec_type = make_node (RECORD_TYPE);
- tree field = create_field_decl (get_identifier ("OBJ"), etype, rec_type,
- NULL_TREE, NULL_TREE, 1, 0);
+ unsigned HOST_WIDE_INT prec = TREE_INT_CST_LOW (TYPE_RM_SIZE (etype));
VEC(constructor_elt,gc) *v = VEC_alloc (constructor_elt, gc, 1);
+ tree field_type, field;
+
+ if (TYPE_UNSIGNED (etype))
+ field_type = make_unsigned_type (prec);
+ else
+ field_type = make_signed_type (prec);
+ SET_TYPE_RM_SIZE (field_type, TYPE_RM_SIZE (etype));
+
+ field = create_field_decl (get_identifier ("OBJ"), field_type, rec_type,
+ NULL_TREE, NULL_TREE, 1, 0);
TYPE_FIELDS (rec_type) = field;
layout_type (rec_type);
+ expr = fold_build1 (NOP_EXPR, field_type, expr);
CONSTRUCTOR_APPEND_ELT (v, field, expr);
expr = gnat_build_constructor (rec_type, v);
expr = unchecked_convert (type, expr, notrunc_p);