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;
+}

Reply via email to