https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78200

--- Comment #9 from Richard Biener <rguenth at gcc dot gnu.org> ---
So RTL expansion ends up in

          /* If jumps are cheap and the target does not support conditional
             compare, turn some more codes into jumpy sequences.  */
          else if (BRANCH_COST (optimize_insn_for_speed_p (), false) < 4
                   && targetm.gen_ccmp_first == NULL)
            {
              if ((code2 == BIT_AND_EXPR
                   && TYPE_PRECISION (TREE_TYPE (op0)) == 1
                   && TREE_CODE (gimple_assign_rhs2 (second)) != INTEGER_CST)
                  || code2 == TRUTH_AND_EXPR)
                {
                  code = TRUTH_ANDIF_EXPR;
                  op0 = gimple_assign_rhs1 (second);
                  op1 = gimple_assign_rhs2 (second);

where we could adjust operand order based on the immediately dominating
condition.

Unfortunately sth as simple as

                  /* We'll expand RTL for op0 first, see if we'd better
                     expand RTL for op1 first.  */
                  if (TREE_CODE (op1) == SSA_NAME
                      && single_pred_p (bb))
                    {
                      gimple *def1 = SSA_NAME_DEF_STMT (op1);
                      if (is_gimple_assign (def1)
                          && TREE_CODE_CLASS (gimple_assign_rhs_code (def1)) ==
tcc_comparison)
                        {
                          basic_block pred = single_pred (bb);
                          gimple *last = last_stmt (pred);
                          if (last
                              && gimple_code (last) == GIMPLE_COND
                              && gimple_assign_rhs1 (def1) == gimple_cond_lhs
(last))
                            std::swap (op0, op1);
                        }
                    }

doesn't work as the predecessor is no longer in GIMPLE (we dropped the seq
for the GIMPLE stmts and GIMPLE_CONDs have no DEFs...).  Also I'm not sure
the half-way RTL CFG will still point to the original block.

Of course the above heuristic is really only applicable if there's not much
code expanded between this jump and the one in the predecessor.

OTOH if we have the BRANCH_COST check during RTL expansion (similar to
what we have for LOGICAL_OP_NON_SHORT_CIRCUIT in fold-const.c) then maybe
if-combining shouldn't combine the conditionals.  There's a slight disconnect
here, the above is BRANCH_COST < 4 while the other is BRANCH_COST >= 2 ...

The cfgexpand code could also be done as a pre-pass on the IL turning
the straight-line code back to CFG (I guess that's a good idea anyway).

Reply via email to