https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113576
--- Comment #44 from Hongtao Liu <liuhongt at gcc dot gnu.org> --- > > Note the AND is removed by combine if I add it: > > Successfully matched this instruction: > (set (reg:CCZ 17 flags) > (compare:CCZ (and:HI (not:HI (subreg:HI (reg:QI 102 [ tem_3 ]) 0)) > (const_int 15 [0xf])) > (const_int 0 [0]))) > > (*testhi_not) > > - 9: {r103:QI=r102:QI&0xf;clobber flags:CC;} > + REG_DEAD r99:QI > + 9: NOTE_INSN_DELETED > + 12: flags:CCZ=cmp(~r102:QI#0&0xf,0) > REG_DEAD r102:QI > - REG_UNUSED flags:CC > - 12: flags:CCZ=cmp(r103:QI,0xf) > - REG_DEAD r103:QI > > and we get > > foo: > .LFB0: > .cfi_startproc > notl %esi > orl %esi, %edi > notl %edi > testb $15, %dil > je .L6 > ret > > which I'm not sure is OK? > Yes, I think it's on purpose 11508;; Split and;cmp (as optimized by combine) into not;test 11509;; Except when TARGET_BMI provides andn (*andn_<mode>_ccno). 11510(define_insn_and_split "*test<mode>_not" 11511 [(set (reg:CCZ FLAGS_REG) 11512 (compare:CCZ 11513 (and:SWI 11514 (not:SWI (match_operand:SWI 0 "register_operand")) 11515 (match_operand:SWI 1 "<nonmemory_szext_operand>")) 11516 (const_int 0)))] 11517 "ix86_pre_reload_split () 11518 && (!TARGET_BMI || !REG_P (operands[1]))" 11519 "#" 11520 "&& 1" 11521 [(set (match_dup 2) (not:SWI (match_dup 0))) 11522 (set (reg:CCZ FLAGS_REG) 11523 (compare:CCZ (and:SWI (match_dup 2) (match_dup 1)) 11524 (const_int 0)))] 11525 "operands[2] = gen_reg_rtx (<MODE>mode);") 11526 11527;; Split and;cmp (as optimized by combine) into andn;cmp $0 11528(define_insn_and_split "*test<mode>_not_doubleword"