This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] tree-sra: fix compare_access_positions qsort comparator
- From: Alexander Monakov <amonakov at ispras dot ru>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Martin Jambor <mjambor at suse dot cz>
- Date: Thu, 21 Sep 2017 20:27:31 +0300 (MSK)
- Subject: [PATCH] tree-sra: fix compare_access_positions qsort comparator
- Authentication-results: sourceware.org; auth=none
Hi,
The compare_access_positions qsort comparator lacks transitivity, although
somewhat surprisingly this issue didn't manifest on 64-bit x86 bootstraps.
The first invalid comparison step is here (tree-sra.c:1545):
/* Put the integral type with the bigger precision first. */
else if (INTEGRAL_TYPE_P (f1->type)
&& INTEGRAL_TYPE_P (f2->type))
return TYPE_PRECISION (f2->type) - TYPE_PRECISION (f1->type);
Imagine you have items A, B, C such that they compare equal according to
preceding comparison steps, A and C are integral and have precision 64 resp.
32, B is non-integral. Then you have C < A according to this step, but
comparisons against B depend on TYPE_UID, so you can end up with A < B < C < A.
A minimal fix would be to order all integral items before/after non-integral,
like preceding code already does for aggregate/vector/complex types.
Bootstrapped/regtested on 32-bit x86.
Thanks.
Alexander
* tree-sra (compare_access_positions): Order non-integral types before
integral types.
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 163b7a2d03b..4f9a8802aeb 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -1542,19 +1542,17 @@ compare_access_positions (const void *a, const void *b)
&& TREE_CODE (f2->type) != COMPLEX_TYPE
&& TREE_CODE (f2->type) != VECTOR_TYPE)
return -1;
+ /* Put any non-integral type before any integral type. */
+ 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 -1;
/* Put the integral type with the bigger precision first. */
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;
/* Stabilize the sort. */
return TYPE_UID (f1->type) - TYPE_UID (f2->type);
}