This is a backport of the fix for PR target/105930 from mainline to the gcc12 release branch. This patch has been retested against the gcc12 branch on x86_64-pc-linux-gnu with make bootstrap and make -k check, both with and without --target_board=unix{-m32} with no new failures. Ok for the gcc12 branch?
2022-07-09 Roger Sayle <ro...@nextmovesoftware.com> Uroš Bizjak <ubiz...@gmail.com> gcc/ChangeLog PR target/105930 * config/i386/i386.md (*<any_or>di3_doubleword): Split after reload. Use rtx_equal_p to avoid creating memory-to-memory moves, and emit NOTE_INSN_DELETED if operand[2] is zero (i.e. with -O0). Thanks in advance, Roger --
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 7c9560fc4..1c4781d 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -10400,22 +10400,25 @@ "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;") (define_insn_and_split "*<code>di3_doubleword" - [(set (match_operand:DI 0 "nonimmediate_operand") + [(set (match_operand:DI 0 "nonimmediate_operand" "=ro,r") (any_or:DI - (match_operand:DI 1 "nonimmediate_operand") - (match_operand:DI 2 "x86_64_szext_general_operand"))) + (match_operand:DI 1 "nonimmediate_operand" "0,0") + (match_operand:DI 2 "x86_64_szext_general_operand" "re,o"))) (clobber (reg:CC FLAGS_REG))] "!TARGET_64BIT - && ix86_binary_operator_ok (<CODE>, DImode, operands) - && ix86_pre_reload_split ()" + && ix86_binary_operator_ok (<CODE>, DImode, operands)" "#" - "&& 1" + "&& reload_completed" [(const_int 0)] { + /* This insn may disappear completely when operands[2] == const0_rtx + and operands[0] == operands[1], which requires a NOTE_INSN_DELETED. */ + bool emit_insn_deleted_note_p = false; + split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]); if (operands[2] == const0_rtx) - emit_move_insn (operands[0], operands[1]); + emit_insn_deleted_note_p = true; else if (operands[2] == constm1_rtx) { if (<CODE> == IOR) @@ -10427,7 +10430,10 @@ ix86_expand_binary_operator (<CODE>, SImode, &operands[0]); if (operands[5] == const0_rtx) - emit_move_insn (operands[3], operands[4]); + { + if (emit_insn_deleted_note_p) + emit_note (NOTE_INSN_DELETED); + } else if (operands[5] == constm1_rtx) { if (<CODE> == IOR)