https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77826
--- Comment #5 from rguenther at suse dot de <rguenther at suse dot de> --- On Tue, 4 Oct 2016, jakub at gcc dot gnu.org wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77826 > > --- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> --- > (In reply to Richard Biener from comment #3) > > --- gcc/genmatch.c (revision 240739) > > +++ gcc/genmatch.c (working copy) > > @@ -2593,8 +2601,10 @@ dt_operand::gen_match_op (FILE *f, int i > > { > > char match_opname[20]; > > match_dop->get_name (match_opname); > > - fprintf_indent (f, indent, "if (%s == %s || operand_equal_p (%s, %s, > > 0))\n", > > - opname, match_opname, opname, match_opname); > > + fprintf_indent (f, indent, "if (%s == %s || (operand_equal_p (%s, %s, 0) > > " > > + "&& types_match (%s, %s)))\n", > > + opname, match_opname, opname, match_opname, > > + opname, match_opname); > > fprintf_indent (f, indent + 2, "{\n"); > > return 1; > > } > > But that will mean the pattern will no longer match. Yes. I'm not sure if in all patterns a mismatched type wouldn't not cause wrong-code eventually. > While it is generally > safer, for the cases like this simplify, shall it then use (convert? @2) > instead and add operand_equal_p for @0 and @2? I guess all it cares is that > @0 > actually has the same type as @1 there, not a different one? Well, they have the same type by construction (being operands to bit_ior). The issue with constants is that if we had (int) x_2 and valueize x_2 to 1 then the matcher still sees (int) 1 thus valueized matching occurs on an otherwise "unfolded" tree ... The pattern fails to handle (long)(2 | Y) ^ 2L as well, so it really would need to do /* (X | Y) ^ X -> Y & ~ X*/ (simplify (bit_xor:c (convert1? (bit_ior:c @0 @1)) (convert2? @0)) (if (tree_nop_conversion_p (type, TREE_TYPE (@0))) (convert (bit_and @1 (bit_not @0))))) which then exposes the fact that if @0 == constant we might have different types in the two places. So it would need to be done as /* (X | Y) ^ X -> Y & ~ X*/ (simplify (bit_xor:c (convert1? (bit_ior:c @0 @1)) (convert2? @2)) (if (tree_nop_conversion_p (type, TREE_TYPE (@0)) && (@0 == @2 || operand_equal_p (@0, @2, 0))) (convert (bit_and @1 (bit_not @0))))) Anyway - I think the safer operand_equal_p () && types_match () is the way to go. OTOH I don't like the explicit matching with operand_equal_p ...