Hi David,

在 2022/11/17 21:24, David Edelsohn 写道:
> This is better, but the pattern should be near and after the existing 
> cbranch<mode>4 patterns earlier in the file, not the *cbranch pattern.  It 
> doesn't match the comment.
Sure, I will put it after existing "cbranch<mode>4" patterns.

> 
> Why are you using zero_constant predicate instead of matching (const_int 0) 
> for operand 2?
The "const_int 0" is an operand other than a predicate. We need a predicate 
here.

> 
> Why does this need the new all_branch_comparison_operator?  Can the ifcvt 
> optimization correctly elide the 2 insn sequence?
Because rs6000 defines "*cbranch_2insn" insn, such insns are generated after 
expand.

(jump_insn 50 47 51 11 (set (pc)
        (if_then_else (ge (reg:CCFP 156)
                (const_int 0 [0]))
            (label_ref 53)
            (pc))) 
"/home/guihaoc/gcc/gcc-mainline-base/gmp/mpz/cmpabs_d.c":80:7 884 
{*cbranch_2insn}
     (expr_list:REG_DEAD (reg:CCFP 156)
        (int_list:REG_BR_PROB 633507684 (nil)))
 -> 53)

In prepare_cmp_insn, the comparison is verified by insn_operand_matches. If
extra_insn_branch_comparison_operator is not included in "cbranchcc4" predicate,
it hits ICE here.

  if (GET_MODE_CLASS (mode) == MODE_CC)
    {
      enum insn_code icode = optab_handler (cbranch_optab, CCmode);
      test = gen_rtx_fmt_ee (comparison, VOIDmode, x, y);
      gcc_assert (icode != CODE_FOR_nothing
                  && insn_operand_matches (icode, 0, test));
      *ptest = test;
      return;
    }

The real conditional move is generated by emit_conditional_move_1. Commonly
"*cbranch_2insn" can't be optimized out and it returns NULL_RTX.

      if (COMPARISON_P (comparison))
        {
          saved_pending_stack_adjust save;
          save_pending_stack_adjust (&save);
          last = get_last_insn ();
          do_pending_stack_adjust ();
          machine_mode cmpmode = comp.mode;
          prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1),
                            GET_CODE (comparison), NULL_RTX, unsignedp,
                            OPTAB_WIDEN, &comparison, &cmpmode);
          if (comparison)
            {
               rtx res = emit_conditional_move_1 (target, comparison,
                                                  op2, op3, mode);
               if (res != NULL_RTX)
                 return res;
            }
          delete_insns_since (last);
          restore_pending_stack_adjust (&save);

I think that extra_insn_branch_comparison_operator should be included in
"cbranchcc4" predicates as such insns exist. And leave it to
emit_conditional_move which decides whether it can be optimized or not.

Thanks for your comments
Gui Haochen

Reply via email to