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); }