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. Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}. Also tested by building and booting the linux kernel (where the peephole2 triggers several times). I was not able to craft the testcase, the original sequence is very elusive and requires reuse of the value, set from the flags elsewhere in the function in a very specific way. Uros.
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index f83064ec335..e862368113c 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -18118,6 +18118,35 @@ (define_split 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