I have a instruction pattern for my port that reads in part:

  [(parallel [(set (subreg:DI (match_operand:TI 0 "register_operand" "=r") 0)
                   (mem:DI (plus:DI (match_operand:DI 1 "register_operand" "r")
                                    (match_operand:DI 2 "const_int_operand" 
""))))
              (set (subreg:DI (match_dup 0) 8)
                   (mem:DI (plus:DI (match_dup 1)
                                    (match_operand:DI 3 
"const_int_operand"))))])]

The subreg seems to give web.c fits.  web is looking for the match_dup and 
failing to find it, due to the fact that DF_REF_LOC is of the form (subreg:DI 
(reg:TI 5) 8), not (reg:TI 5).  If I add a case for SUBREG like in the below, 
we can then find and process the subreg.

So, the question is, is the port completely wrong for trying to use subreg in 
this fashion?  If not, is processing subregs in this way the right way?  If 
yes, Ok?

diff --git a/gcc/web.c b/gcc/web.c
index b602615..702a4e9 100644
--- a/gcc/web.c
+++ b/gcc/web.c
@@ -133,8 +133,16 @@ union_match_dups (rtx insn, struct web_entry *def_entry,
       ref = type == OP_IN ? use_link : def_link;
       entry = type == OP_IN ? use_entry : def_entry;
       for (; *ref; ref++)
-       if (DF_REF_LOC (*ref) == recog_data.operand_loc[op])
-         break;
+       {
+         if (DF_REF_LOC (*ref) == recog_data.operand_loc[op])
+           break;
+         /* DF_REF_LOC can be (subreg:DI (reg:TI 5) 8) and
+            recog_data.operand_loc[op] can be (reg:TI 5), and the above
+            won't find it.  */
+         if (GET_CODE (*DF_REF_LOC (*ref)) == SUBREG &&
+             &SUBREG_REG (*DF_REF_LOC (*ref)) == recog_data.operand_loc[op])
+           break;
+       }
 
       if (!*ref && type == OP_INOUT)
        {


Reply via email to