https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106070
--- Comment #5 from Richard Biener <rguenth at gcc dot gnu.org> --- +Applying pattern match.pd:4591, gimple-match.cc:59644 ... @@ -31,7 +41,7 @@ var_4.3_3 = (unsigned int) var_4.2_2; iftmp.0_9 = (long unsigned int) var_2.1_1; iftmp.0_10 = (long unsigned int) var_4.2_2; _4 = var_2.1_1 != var_4.3_3; - iftmp.0_6 = _4 ? iftmp.0_10 : iftmp.0_9; + iftmp.0_6 = (long unsigned int) var_4.3_3; <bb 4> [local count: 955630225]: # a_16 = PHI <a_12(7), 0(3)> so that's var_2 != (unsigned) var_4 ? -> (unsigned long) var_4 : (unsigned long) var_2 which we turn into (unsigned long) (unsigned) var_4. I thought that's what generic also does but I have to double-check operand_equal_for_comparison_p here. Ah, it checks /* Discard a single widening conversion from ARG1 and see if the inner value is the same as ARG0. */ if (CONVERT_EXPR_P (arg1) && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (arg1, 0))) && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg1, 0))) < TYPE_PRECISION (TREE_TYPE (arg1)) && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0)) and the operand_equal_p matches against the non-NOP-stripped arg0. So it's either a same precision or widening of the comparison op. Hmm, will have to think how to translate that into a sign check to make it fit match.pd (I don't want to export and use operand_equal_for_comparison_p)