https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82062
--- Comment #8 from rguenther at suse dot de <rguenther at suse dot de> --- On Wed, 25 Oct 2017, ebotcazou at gcc dot gnu.org wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82062 > > --- Comment #7 from Eric Botcazou <ebotcazou at gcc dot gnu.org> --- > But in fact we probably just need: > > Index: fold-const.c > =================================================================== > --- fold-const.c (revision 254037) > +++ fold-const.c (working copy) > @@ -3366,7 +3366,8 @@ operand_equal_p (const_tree arg0, const_ > #undef OP_SAME_WITH_NULL > } > > > -/* Similar to operand_equal_p, but strip nops first. */ > +/* Similar to operand_equal_p, but see if ARG1 might be a variant of ARG0 > + with a different signedness or a simple conversion. */ > > static bool > operand_equal_for_comparison_p (tree arg0, tree arg1) > @@ -3378,12 +3379,15 @@ operand_equal_for_comparison_p (tree arg > || ! INTEGRAL_TYPE_P (TREE_TYPE (arg1))) > return false; > > - /* Discard any conversions that don't change the modes of ARG0 and ARG1 > - and see if the inner values are the same. This removes any > - signedness comparison, which doesn't matter here. */ > - STRIP_NOPS (arg0); > - STRIP_NOPS (arg1); > - if (operand_equal_p (arg0, arg1, 0)) > + tree op0 = arg0; > + tree op1 = arg1; > + STRIP_NOPS (op0); > + STRIP_NOPS (op1); > + if (operand_equal_p (op0, op1, 0)) > + return true; > + > + if (TREE_CODE (arg1) == NOP_EXPR > + && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0)) > return true; I would really like to see fold_cond_expr_with_comparison to be re-written into match.pd rules. Esp. due to operand_equal_for_comparison_p its correctness is far from obvious... There are two things to it, stripping sign-nops from the comparison operand (careful!) and stripping arbitrary nops from the result to look for an argument equal to the comparison operand. I guess a canonicalization transform X CMP Y ? (T') X : Z to (T') (X CMP Y ? X : (T'')Z) is what it implicitely wants to do but given the stripping of sign-nops from the comparison operand it's not obvious it does this. Maybe refactor operand_equal_for_comparison_p into sth that does not strip arg0 at all but leave that to the caller.