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 ...

Reply via email to