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

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org

--- Comment #13 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
So, there is the cmov splitter added in r12-1525 and extended in r12-7751.  The
r12-1525 version of this was:
;; Help combine recognize bt followed by cmov
(define_split
  [(set (match_operand:SWI248 0 "register_operand")
       (if_then_else:SWI248
        (ne
         (zero_extract:SWI48
          (match_operand:SWI48 1 "register_operand")
          (const_int 1)
          (zero_extend:SI (match_operand:QI 2 "register_operand")))
         (const_int 0))
        (match_operand:SWI248 3 "nonimmediate_operand")
        (match_operand:SWI248 4 "nonimmediate_operand")))]
  "TARGET_USE_BT && TARGET_CMOVE
   && !(MEM_P (operands[3]) && MEM_P (operands[4]))
   && ix86_pre_reload_split ()"
  [(set (reg:CCC FLAGS_REG)
       (compare:CCC
        (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
        (const_int 0)))
   (set (match_dup 0)
       (if_then_else:SWI248 (eq (reg:CCC FLAGS_REG) (const_int 0))
                            (match_dup 3)
                            (match_dup 4)))]
{
  operands[2] = lowpart_subreg (SImode, operands[2], QImode);
})

So, in my reading, op0 = (op1 & (1 << op2)) ? op3 : op4 is what is being
matched.
And by purely reading the RTL the replacement is the other way around, flags
is set to comparison of the zero extraction (i.e. 1 or 0) against 0 and if it
is
0, op3 is used, otherwise op4.  But %C1 actually prints for (eq (reg:CCC flags)
(const_int 0))
c rather than nc and for ne nc rather than c.

Reply via email to