The following fixes recursion between a pattern in fold-const.c and one formerly in tree-ssa-forwprop.c but now in match.pd (and thus also fold-const.c). There are two conflicting transforms and the measure against recursion I put in place doesn't help for the testcase (as the conversion is useless).
Bootstrapped and tested on x86_64-unknown-linux-gnu. Richard. 2014-11-07 Richard Biener <rguent...@suse.de> PR middle-end/63770 * match.pd: Guard conflicting GENERIC pattern properly. * gcc.dg/pr63770.c: New testcase. Index: gcc/match.pd =================================================================== --- gcc/match.pd 2014-11-07 09:24:45.943027082 +0100 +++ gcc/match.pd 2014-11-07 09:23:06.573031431 +0100 @@ -129,14 +129,15 @@ along with GCC; see the file COPYING3. (bitop (convert @0) (convert? @1)) (if (((TREE_CODE (@1) == INTEGER_CST && INTEGRAL_TYPE_P (TREE_TYPE (@0)) - && int_fits_type_p (@1, TREE_TYPE (@0)) - /* ??? This transform conflicts with fold-const.c doing - Convert (T)(x & c) into (T)x & (T)c, if c is an integer - constants (if x has signed type, the sign bit cannot be set - in c). This folds extension into the BIT_AND_EXPR. - Restrict it to GIMPLE to avoid endless recursions. */ - && (bitop != BIT_AND_EXPR || GIMPLE)) - || types_compatible_p (TREE_TYPE (@0), TREE_TYPE (@1))) + && int_fits_type_p (@1, TREE_TYPE (@0))) + || (GIMPLE && types_compatible_p (TREE_TYPE (@0), TREE_TYPE (@1))) + || (GENERIC && TREE_TYPE (@0) == TREE_TYPE (@1))) + /* ??? This transform conflicts with fold-const.c doing + Convert (T)(x & c) into (T)x & (T)c, if c is an integer + constants (if x has signed type, the sign bit cannot be set + in c). This folds extension into the BIT_AND_EXPR. + Restrict it to GIMPLE to avoid endless recursions. */ + && (bitop != BIT_AND_EXPR || GIMPLE) && (/* That's a good idea if the conversion widens the operand, thus after hoisting the conversion the operation will be narrower. */ TYPE_PRECISION (TREE_TYPE (@0)) < TYPE_PRECISION (type) Index: gcc/testsuite/gcc.dg/pr63770.c =================================================================== --- gcc/testsuite/gcc.dg/pr63770.c (revision 0) +++ gcc/testsuite/gcc.dg/pr63770.c (working copy) @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +char a; + +struct S +{ + int f0:9; +}; + +volatile struct S b; + +int +fn1 () +{ + return (1 & b.f0) < a; +}