i386: Eliminate redundant compare between set{z,nz} and j{z,nz}

Eliminate redundant compare between set{z,nz} and j{z,nz}:
setz %al; test %al,%al; jz <...> -> setz %al; jnz <...> and
setnz %al, test %al,%al; jz <...> -> setnz %al; jz <...>.

We can use the original Zero-flag value instead of setting the
temporary register and testing it for zero.

gcc/ChangeLog:

	* config/i386/i386.md (redundant compare peephole2):
	New peephole2 pattern.
This commit is contained in:
Uros Bizjak 2023-12-18 22:18:05 +01:00
parent b77691a90f
commit 86b6daefc8

View file

@ -18118,6 +18118,35 @@
FAIL;
})
;; Eliminate redundant compare between set{z,nz} and j{z,nz}:
;; setz %al; test %al,%al; jz <...> -> setz %al; jnz <...> and
;; setnz %al, test %al,%al; jz <...> -> setnz %al; jz <...>.
(define_peephole2
[(set (match_operand:QI 0 "nonimmediate_operand")
(match_operator:QI 1 "bt_comparison_operator"
[(reg:CCZ FLAGS_REG) (const_int 0)]))
(set (reg:CCZ FLAGS_REG)
(compare:CCZ (match_dup 0) (const_int 0)))
(set (pc)
(if_then_else (match_operator 2 "bt_comparison_operator"
[(reg:CCZ FLAGS_REG) (const_int 0)])
(match_operand 3)
(pc)))]
"peep2_regno_dead_p (3, FLAGS_REG)"
[(set (match_dup 0)
(match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)]))
(set (pc)
(if_then_else (match_dup 2)
(match_dup 3)
(pc)))]
{
if (GET_CODE (operands[1]) == EQ)
{
operands[2] = shallow_copy_rtx (operands[2]);
PUT_CODE (operands[2], reverse_condition (GET_CODE (operands[2])));
}
})
;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
;; subsequent logical operations are used to imitate conditional moves.
;; 0xffffffff is NaN, but not in normalized form, so we can't represent