From: Richard Biener Date: Wed, 21 Aug 2019 13:44:45 +0000 (+0000) Subject: re PR tree-optimization/91510 (r253207 fixed a wrong-code bug) X-Git-Tag: releases/gcc-7.5.0~306 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=af7b538019edb9a38581b0a078a3c86572ec7dcf;p=thirdparty%2Fgcc.git re PR tree-optimization/91510 (r253207 fixed a wrong-code bug) 2019-08-21 Richard Biener PR tree-optimization/91510 Backport from mainline 2017-09-26 Martin Jambor * tree-sra.c (compare_access_positions): Put integral types first, stabilize sorting of integral types, remove conditions putting non-full-precision integers last. (sort_and_splice_var_accesses): Disable scalarization if a non-integert would be represented by a non-full-precision integer. From-SVN: r274798 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fd3b5183e83f..a16f442b3b03 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2019-08-21 Richard Biener + + PR tree-optimization/91510 + Backport from mainline + 2017-09-26 Martin Jambor + + * tree-sra.c (compare_access_positions): Put integral types first, + stabilize sorting of integral types, remove conditions putting + non-full-precision integers last. + (sort_and_splice_var_accesses): Disable scalarization if a + non-integert would be represented by a non-full-precision integer. + 2019-08-20 Eric Botcazou PR rtl-optimization/91347 diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index 0334d0615075..cb9dacd9c8c6 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -1516,19 +1516,20 @@ compare_access_positions (const void *a, const void *b) && TREE_CODE (f2->type) != COMPLEX_TYPE && TREE_CODE (f2->type) != VECTOR_TYPE) return -1; - /* Put the integral type with the bigger precision first. */ + /* Put any integral type before any non-integral type. When splicing, we + make sure that those with insufficient precision and occupying the + same space are not scalarized. */ else if (INTEGRAL_TYPE_P (f1->type) + && !INTEGRAL_TYPE_P (f2->type)) + return -1; + else if (!INTEGRAL_TYPE_P (f1->type) && INTEGRAL_TYPE_P (f2->type)) - return TYPE_PRECISION (f2->type) - TYPE_PRECISION (f1->type); - /* Put any integral type with non-full precision last. */ - else if (INTEGRAL_TYPE_P (f1->type) - && (TREE_INT_CST_LOW (TYPE_SIZE (f1->type)) - != TYPE_PRECISION (f1->type))) return 1; - else if (INTEGRAL_TYPE_P (f2->type) - && (TREE_INT_CST_LOW (TYPE_SIZE (f2->type)) - != TYPE_PRECISION (f2->type))) - return -1; + /* Put the integral type with the bigger precision first. */ + else if (INTEGRAL_TYPE_P (f1->type) + && INTEGRAL_TYPE_P (f2->type) + && (TYPE_PRECISION (f2->type) != TYPE_PRECISION (f1->type))) + return TYPE_PRECISION (f2->type) - TYPE_PRECISION (f1->type); /* Stabilize the sort. */ return TYPE_UID (f1->type) - TYPE_UID (f2->type); } @@ -2029,6 +2030,11 @@ sort_and_splice_var_accesses (tree var) bool grp_partial_lhs = access->grp_partial_lhs; bool first_scalar = is_gimple_reg_type (access->type); bool unscalarizable_region = access->grp_unscalarizable_region; + bool bf_non_full_precision + = (INTEGRAL_TYPE_P (access->type) + && TYPE_PRECISION (access->type) != access->size + && TREE_CODE (access->expr) == COMPONENT_REF + && DECL_BIT_FIELD (TREE_OPERAND (access->expr, 1))); if (first || access->offset >= high) { @@ -2076,6 +2082,22 @@ sort_and_splice_var_accesses (tree var) this combination of size and offset, the comparison function should have put the scalars first. */ gcc_assert (first_scalar || !is_gimple_reg_type (ac2->type)); + /* It also prefers integral types to non-integral. However, when the + precision of the selected type does not span the entire area and + should also be used for a non-integer (i.e. float), we must not + let that happen. Normally analyze_access_subtree expands the type + to cover the entire area but for bit-fields it doesn't. */ + if (bf_non_full_precision && !INTEGRAL_TYPE_P (ac2->type)) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "Cannot scalarize the following access " + "because insufficient precision integer type was " + "selected.\n "); + dump_access (dump_file, access, false); + } + unscalarizable_region = true; + } ac2->group_representative = access; j++; }