This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Fix sort_by_operand_rank with qsort checking (PR tree-optimization/82381, #2)
- From: Richard Biener <rguenther at suse dot de>
- To: Jakub Jelinek <jakub at redhat dot com>,Alexander Monakov <amonakov at ispras dot ru>
- Cc: Kugan Vivekanandarajah <kuganv at linaro dot org>,gcc-patches at gcc dot gnu dot org
- Date: Tue, 03 Oct 2017 15:30:31 +0200
- Subject: Re: [PATCH] Fix sort_by_operand_rank with qsort checking (PR tree-optimization/82381, #2)
- Authentication-results: sourceware.org; auth=none
- References: <20171003100021.GJ18588@tucnak> <alpine.LNX.2.20.13.1710031313360.24074@monopod.intra.ispras.ru> <20171003115535.GK18588@tucnak>
On October 3, 2017 1:55:35 PM GMT+02:00, Jakub Jelinek <jakub@redhat.com> wrote:
>On Tue, Oct 03, 2017 at 01:24:32PM +0300, Alexander Monakov wrote:
>> On Tue, 3 Oct 2017, Jakub Jelinek wrote:
>> > The qsort cmp transitivity checks may fail with the
>sort_by_operand_rank
>> > comparator, because if one of the operands has stmt_to_insert and
>the
>> > other doesn't (but likely also if one SSA_NAME is (D) and the other
>is not),
>> > we fallthrough into SSA_NAME_VERSION comparison, but if both aren't
>(D) and
>> > both don't have stmt_to_insert, we use different comparison rules.
>>
>> When looking at the code I've noticed another issue, so the fix seems
>> incomplete (but I don't know if the other problem can/should be fixed
>> independently), see below:
>>
>>
>> > --- gcc/tree-ssa-reassoc.c.jj 2017-10-02 17:33:14.270282226 +0200
>> > +++ gcc/tree-ssa-reassoc.c 2017-10-02 18:18:07.328611132 +0200
>> > @@ -514,36 +514,37 @@ sort_by_operand_rank (const void *pa, co
>> > && TREE_CODE (oea->op) == SSA_NAME
>> > && TREE_CODE (oeb->op) == SSA_NAME)
>> > {
>>
>> The containing if statement condition reads:
>>
>> if (oeb->rank == oea->rank
>> && TREE_CODE (oea->op) == SSA_NAME
>> && TREE_CODE (oeb->op) == SSA_NAME)
>>
>> so as far as I can tell it's possible to have items A, B, C such that
>> all have same rank, A and C correspond to SSA_NAMEs and compare C <
>A,
>> but B does not, so comparisons of A or C against B fall down to
>>
>> return oeb->id > oea->id ? 1 : -1;
>>
>> and ultimately result in A < B < C < A.
>
>I think it is likely only hypothetical, because get_rank for
>non-SSA_NAME
>should be 0 and thus handled earlier (for SSA_NAME I think rank of 0 is
>still possible).
>
>That said, this untested patch reshuffles stuff a little bit, ok for
>trunk
>if it passes testing?
OK.
Richard.
>2017-10-03 Jakub Jelinek <jakub@redhat.com>
>
> PR tree-optimization/82381
> * tree-ssa-reassoc.c (sort_by_operand_rank): Check for different
> oeN->rank first. Return 1 or -1 if one op is SSA_NAME and the other
> is not.
>
>--- gcc/tree-ssa-reassoc.c.jj 2017-10-03 13:24:00.000000000 +0200
>+++ gcc/tree-ssa-reassoc.c 2017-10-03 13:41:23.098183270 +0200
>@@ -495,10 +495,13 @@ sort_by_operand_rank (const void *pa, co
> const operand_entry *oea = *(const operand_entry *const *)pa;
> const operand_entry *oeb = *(const operand_entry *const *)pb;
>
>+ if (oeb->rank != oea->rank)
>+ return oeb->rank > oea->rank ? 1 : -1;
>+
> /* It's nicer for optimize_expression if constants that are likely
>- to fold when added/multiplied//whatever are put next to each
>+ to fold when added/multiplied/whatever are put next to each
> other. Since all constants have rank 0, order them by type. */
>- if (oeb->rank == 0 && oea->rank == 0)
>+ if (oea->rank == 0)
> {
> if (constant_type (oeb->op) != constant_type (oea->op))
> return constant_type (oeb->op) - constant_type (oea->op);
>@@ -508,51 +511,50 @@ sort_by_operand_rank (const void *pa, co
> return oeb->id > oea->id ? 1 : -1;
> }
>
>+ if (TREE_CODE (oea->op) != SSA_NAME)
>+ {
>+ if (TREE_CODE (oeb->op) != SSA_NAME)
>+ return oeb->id > oea->id ? 1 : -1;
>+ else
>+ return 1;
>+ }
>+ else if (TREE_CODE (oeb->op) != SSA_NAME)
>+ return -1;
>+
> /* Lastly, make sure the versions that are the same go next to each
> other. */
>- if (oeb->rank == oea->rank
>- && TREE_CODE (oea->op) == SSA_NAME
>- && TREE_CODE (oeb->op) == SSA_NAME)
>+ if (SSA_NAME_VERSION (oeb->op) != SSA_NAME_VERSION (oea->op))
> {
>- if (SSA_NAME_VERSION (oeb->op) != SSA_NAME_VERSION (oea->op))
>+ /* As SSA_NAME_VERSION is assigned pretty randomly, because we
>reuse
>+ versions of removed SSA_NAMEs, so if possible, prefer to sort
>+ based on basic block and gimple_uid of the SSA_NAME_DEF_STMT.
>+ See PR60418. */
>+ gimple *stmta = SSA_NAME_DEF_STMT (oea->op);
>+ gimple *stmtb = SSA_NAME_DEF_STMT (oeb->op);
>+ basic_block bba = gimple_bb (stmta);
>+ basic_block bbb = gimple_bb (stmtb);
>+ if (bbb != bba)
> {
>- /* As SSA_NAME_VERSION is assigned pretty randomly, because we
>reuse
>- versions of removed SSA_NAMEs, so if possible, prefer to sort
>- based on basic block and gimple_uid of the SSA_NAME_DEF_STMT.
>- See PR60418. */
>- gimple *stmta = SSA_NAME_DEF_STMT (oea->op);
>- gimple *stmtb = SSA_NAME_DEF_STMT (oeb->op);
>- basic_block bba = gimple_bb (stmta);
>- basic_block bbb = gimple_bb (stmtb);
>- if (bbb != bba)
>- {
>- /* One of the SSA_NAMEs can be defined in oeN->stmt_to_insert
>- but the other might not. */
>- if (!bba)
>- return 1;
>- if (!bbb)
>- return -1;
>- /* If neither is, compare bb_rank. */
>- if (bb_rank[bbb->index] != bb_rank[bba->index])
>- return bb_rank[bbb->index] - bb_rank[bba->index];
>- }
>-
>- bool da = reassoc_stmt_dominates_stmt_p (stmta, stmtb);
>- bool db = reassoc_stmt_dominates_stmt_p (stmtb, stmta);
>- if (da != db)
>- return da ? 1 : -1;
>-
>- return (SSA_NAME_VERSION (oeb->op) > SSA_NAME_VERSION (oea->op)
>- ? 1 : -1);
>+ /* One of the SSA_NAMEs can be defined in oeN->stmt_to_insert
>+ but the other might not. */
>+ if (!bba)
>+ return 1;
>+ if (!bbb)
>+ return -1;
>+ /* If neither is, compare bb_rank. */
>+ if (bb_rank[bbb->index] != bb_rank[bba->index])
>+ return bb_rank[bbb->index] - bb_rank[bba->index];
> }
>- else
>- return oeb->id > oea->id ? 1 : -1;
>+
>+ bool da = reassoc_stmt_dominates_stmt_p (stmta, stmtb);
>+ bool db = reassoc_stmt_dominates_stmt_p (stmtb, stmta);
>+ if (da != db)
>+ return da ? 1 : -1;
>+
>+ return SSA_NAME_VERSION (oeb->op) > SSA_NAME_VERSION (oea->op) ?
>1 : -1;
> }
>
>- if (oeb->rank != oea->rank)
>- return oeb->rank > oea->rank ? 1 : -1;
>- else
>- return oeb->id > oea->id ? 1 : -1;
>+ return oeb->id > oea->id ? 1 : -1;
> }
>
> /* Add an operand entry to *OPS for the tree operand OP. */
>
>
> Jakub