https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82580
--- Comment #8 from Jakub Jelinek <jakub at gcc dot gnu.org> --- The fact that flags is live is the reason why the (define_peephole2 [(parallel [(set (reg FLAGS_REG) (match_operand 0)) (match_operand 4)]) (set (match_operand:QI 1 "register_operand") (match_operator:QI 2 "ix86_comparison_operator" [(reg FLAGS_REG) (const_int 0)])) (parallel [(set (match_operand 3 "any_QIreg_operand") (zero_extend (match_dup 1))) (clobber (reg:CC FLAGS_REG))])] "(peep2_reg_dead_p (3, operands[1]) || operands_match_p (operands[1], operands[3])) && ! reg_overlap_mentioned_p (operands[3], operands[0]) && ! reg_set_p (operands[3], operands[4]) && peep2_regno_dead_p (0, FLAGS_REG)" [(parallel [(set (match_dup 5) (match_dup 0)) (match_dup 4)]) (set (strict_low_part (match_dup 6)) (match_dup 2))] { operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); operands[6] = gen_lowpart (QImode, operands[3]); ix86_expand_clear (operands[3]); }) peephole doesn't trigger. What I meant is another peephole that would emit xorl %eax, %eax cmpq %rdi, %rdx sbbq %rsi, %rcx setb %al i.e. like the above peephole, but with yet another instruction. Let me try to write it...