]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR tree-optimization/91510 (r253207 fixed a wrong-code bug)
authorRichard Biener <rguenther@suse.de>
Wed, 21 Aug 2019 13:44:45 +0000 (13:44 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 21 Aug 2019 13:44:45 +0000 (13:44 +0000)
2019-08-21  Richard Biener  <rguenther@suse.de>

PR tree-optimization/91510
Backport from mainline
2017-09-26  Martin Jambor  <mjambor@suse.cz>

* 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

gcc/ChangeLog
gcc/tree-sra.c

index fd3b5183e83f02a19ddb4c43a452cdbf80f31b41..a16f442b3b037265eda5a91ddc8c6fbf2ca4badc 100644 (file)
@@ -1,3 +1,15 @@
+2019-08-21  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/91510
+       Backport from mainline
+       2017-09-26  Martin Jambor  <mjambor@suse.cz>
+
+       * 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  <ebotcazou@adacore.com>
 
        PR rtl-optimization/91347
index 0334d0615075117389358539cf9292d45535ae4a..cb9dacd9c8c69ca4edbcf620631b461963a74a25 100644 (file)
@@ -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++;
        }