This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Genrecog bugfix version 2
- To: Jan Hubicka <hubicka at atrey dot karlin dot mff dot cuni dot cz>
- Subject: Re: Genrecog bugfix version 2
- From: Richard Henderson <rth at cygnus dot com>
- Date: Tue, 21 Sep 1999 18:43:28 -0700
- Cc: gcc-patches at gcc dot gnu dot org
- References: <19990725031225.23705@atrey.karlin.mff.cuni.cz>
On Sun, Jul 25, 1999 at 03:12:25AM +0200, Jan Hubicka wrote:
> Sat Jul 24 20:55:54 EDT 1999 Jan Hubicka <hubicka@freesoft.cz>
> * genrecog.c (not_both_true): Handle correctly cases when called for
> tests with different positions in the insn.
I finally understand what's going on here, and I believe your
patch to be correct. I've checked in this variant which adds
a bit of commentary as well.
r~
Index: genrecog.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/genrecog.c,v
retrieving revision 1.51
diff -c -p -d -r1.51 genrecog.c
*** genrecog.c 1999/09/20 09:59:57 1.51
--- genrecog.c 1999/09/22 01:39:25
*************** not_both_true (d1, d2, toplevel)
*** 685,690 ****
--- 685,728 ----
int toplevel;
{
struct decision *p1, *p2;
+ int cmp;
+
+ /* Don't compare strings on the different positions in insn. Doing so
+ is incorrect and results in false matches from constructs like
+
+ [(set (subreg:HI (match_operand:SI "register_operand" "r") 0)
+ (subreg:HI (match_operand:SI "register_operand" "r") 0))]
+ vs
+ [(set (match_operand:HI "register_operand" "r")
+ (match_operand:HI "register_operand" "r"))]
+
+ If we are presented with such, we are recursing through the remainder
+ of a node's success nodes (from the loop at the end of this function).
+ Skip forward until we come to a position that matches.
+
+ Due to the way position strings are constructed, we know that iterating
+ forward from the lexically lower position (e.g. "00") will run into
+ the lexically higher position (e.g. "1") and not the other way around.
+ This saves a bit of effort. */
+
+ cmp = strcmp (d1->position, d2->position);
+ if (cmp != 0)
+ {
+ if (toplevel)
+ abort();
+
+ /* If the d2->position was lexically lower, swap. */
+ if (cmp > 0)
+ p1 = d1; d1 = d2; d2 = p1;
+
+ if (d1->success.first == 0)
+ return 0;
+ for (p1 = d1->success.first; p1; p1 = p1->next)
+ if (! not_both_true (p1, d2, 0))
+ return 0;
+
+ return 1;
+ }
/* If they are both to test modes and the modes are different, they aren't
both true. Similarly for codes, integer elements, and vector lengths. */