The COMPARE RTX has a special conversion procedure that applies only to DImode double-word operands. Do not convert single-word SImode and DImode operands for now.
2019-08-15 Uroš Bizjak <ubiz...@gmail.com> * config/i386/i386-features.c (general_scalar_chain::convert_insn) <case COMPARE>: Revert 2019-08-14 change. (convertible_comparison_p): Revert 2019-08-14 change. Return false for (TARGET_64BIT || mode != DImode). Also update a couple of nearby comments. Boostrapped and regression tested on x86_64-linux-gnu {,-m32}. Committed to mainline SVN. Uros.
Index: config/i386/i386-features.c =================================================================== --- config/i386/i386-features.c (revision 274504) +++ config/i386/i386-features.c (working copy) @@ -1030,11 +1030,11 @@ general_scalar_chain::convert_insn (rtx_insn *insn case COMPARE: src = SUBREG_REG (XEXP (XEXP (src, 0), 0)); - gcc_assert ((REG_P (src) && GET_MODE (src) == GET_MODE_INNER (vmode)) - || (SUBREG_P (src) && GET_MODE (src) == vmode)); + gcc_assert ((REG_P (src) && GET_MODE (src) == DImode) + || (SUBREG_P (src) && GET_MODE (src) == V2DImode)); if (REG_P (src)) - subreg = gen_rtx_SUBREG (vmode, src, 0); + subreg = gen_rtx_SUBREG (V2DImode, src, 0); else subreg = copy_rtx_if_shared (src); emit_insn_before (gen_vec_interleave_lowv2di (copy_rtx_if_shared (subreg), @@ -1273,8 +1273,12 @@ has_non_address_hard_reg (rtx_insn *insn) (const_int 0 [0]))) */ static bool -convertible_comparison_p (rtx_insn *insn, enum machine_mode mode) +convertible_comparison_p (rtx_insn *insn, machine_mode mode) { + /* ??? Currently convertible for double-word DImode chain only. */ + if (TARGET_64BIT || mode != DImode) + return false; + if (!TARGET_SSE4_1) return false; @@ -1306,12 +1310,12 @@ static bool if (!SUBREG_P (op1) || !SUBREG_P (op2) - || GET_MODE (op1) != mode - || GET_MODE (op2) != mode + || GET_MODE (op1) != SImode + || GET_MODE (op2) != SImode || ((SUBREG_BYTE (op1) != 0 - || SUBREG_BYTE (op2) != GET_MODE_SIZE (mode)) + || SUBREG_BYTE (op2) != GET_MODE_SIZE (SImode)) && (SUBREG_BYTE (op2) != 0 - || SUBREG_BYTE (op1) != GET_MODE_SIZE (mode)))) + || SUBREG_BYTE (op1) != GET_MODE_SIZE (SImode)))) return false; op1 = SUBREG_REG (op1); @@ -1319,13 +1323,13 @@ static bool if (op1 != op2 || !REG_P (op1) - || GET_MODE (op1) != GET_MODE_WIDER_MODE (mode).else_blk ()) + || GET_MODE (op1) != DImode) return false; return true; } -/* The DImode version of scalar_to_vector_candidate_p. */ +/* The general version of scalar_to_vector_candidate_p. */ static bool general_scalar_to_vector_candidate_p (rtx_insn *insn, enum machine_mode mode) @@ -1344,7 +1348,7 @@ general_scalar_to_vector_candidate_p (rtx_insn *in if (GET_CODE (src) == COMPARE) return convertible_comparison_p (insn, mode); - /* We are interested in DImode promotion only. */ + /* We are interested in "mode" only. */ if ((GET_MODE (src) != mode && !CONST_INT_P (src)) || GET_MODE (dst) != mode)