The following will fix PR77826, the issue that in match.pd matching up two things uses operand_equal_p which is too lax about the type of the toplevel entity (at least for integer constants).
Bootstrap / regtest pending on x86_64-unknown-linux-gnu. Richard. 2016-10-04 Richard Biener <rguent...@suse.de> PR middle-end/77826 * genmatch.c (dt_operand::gen_match_op): Amend operand_equal_p with types_match to handle type mismatched constants properly. * gcc.dg/torture/pr77826.c: New testcase. Index: gcc/genmatch.c =================================================================== --- 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; } Index: gcc/testsuite/gcc.dg/torture/pr77826.c =================================================================== --- gcc/testsuite/gcc.dg/torture/pr77826.c (revision 0) +++ gcc/testsuite/gcc.dg/torture/pr77826.c (working copy) @@ -0,0 +1,12 @@ +/* { dg-do compile } */ + +void +fi(unsigned long int *v0, unsigned int ow, int q2) +{ + if (ow + q2 != 0) + if (q2 == 1) + { + *v0 |= q2; + q2 ^= *v0; + } +}