[backport gcc-4.9/trunk r198896 ] List-Archive: From: Mike Stump Subject: web ICEs on subreg Date: Fri, 10 May 2013 14:51:04 -0700 I have a instruction pattern for my port that reads in part: [(parallel [(set (subreg:DI (match_operand:TI 0 "register_operand" "=3Dr"= ) 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 b= elow, 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? gcc/ 2013-05-14 Mike Stump * web.c (union_match_dups): Also check DF_REF_REAL_LOC. --- gcc-4.8.0/gcc/web.c.~1~ 2013-01-10 21:38:27.000000000 +0100 +++ gcc-4.8.0/gcc/web.c 2013-05-18 12:09:15.336278228 +0200 @@ -132,14 +132,22 @@ union_match_dups (rtx insn, struct web_e 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; + if (DF_REF_REAL_LOC (*ref) == recog_data.operand_loc[op]) + break; + } if (!*ref && type == OP_INOUT) { for (ref = use_link, entry = use_entry; *ref; ref++) - if (DF_REF_LOC (*ref) == recog_data.operand_loc[op]) - break; + { + if (DF_REF_LOC (*ref) == recog_data.operand_loc[op]) + break; + if (DF_REF_REAL_LOC (*ref) == recog_data.operand_loc[op]) + break; + } } gcc_assert (*ref);