Vasanth <[EMAIL PROTECTED]> writes:

> I am working on a port of GCC to a 32-bit RISC machine. I am having
> trouble with .combine pass adding clobbers to instruction patterns. To
> be more specific,
> 
> (define_insn "lshrsi3_internal_reg_nohwshift"
>   [(set (match_operand:SI 0 "register_operand" "=d")
>         (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
>                      (match_operand:SI 2 "register_operand" "d")))
>    (clobber (reg:SI R_TMP))]
>   "!(TARGET_HW_SHIFT)"
>   {
>  ...
>   } 
> 
> is what I have in my md file. When compiling __lshrdi3 in libgcc2, I
> see the following RTL produced
> 
> libgcc2.i.19.life:
> 
> (insn 43 41 44 4 (set (reg:SI 93)
>         (lshiftrt:SI (subreg:SI (reg/v:DI 87 [ uu ]) 0)
>             (reg/v:SI 85 [ b ]))) -1 (nil)
>     (expr_list:REG_EQUAL (lshiftrt:SI (subreg:SI (reg/v:DI 84 [ u ]) 0)
>             (reg/v:SI 85 [ b ]))
>         (nil)))
> 
> (insn 44 43 46 4 (set (subreg:SI (reg/v:DI 89 [ w ]) 0)
>         (reg:SI 93)) 46 {movsi_internal2} (insn_list 43 (nil))
>     (expr_list:REG_DEAD (reg:SI 93)
>         (nil)))
> 
> (insn 46 44 47 4 (set (reg:SI 94)
>         (lshiftrt:SI (subreg:SI (reg/v:DI 87 [ uu ]) 4)
>             (reg/v:SI 85 [ b ]))) -1 (nil)
>     (expr_list:REG_DEAD (reg/v:DI 87 [ uu ])
>         (expr_list:REG_DEAD (reg/v:SI 85 [ b ])
>             (expr_list:REG_EQUAL (lshiftrt:SI (subreg:SI (reg/v:DI 84 [ u ]) 
> 4)
>                     (reg/v:SI 85 [ b ]))
>                 (nil)))))
> 
> After combine, I expect recog to take insn 43 and 46 and cause both to
> match lshrsi3_internal_reg_nohwshift. However, insn 46 seems to not
> get the clobber attached in a parallel while 43 does.
> 
> libgcc2.i.20.combine:
> 
> (insn 44 43 46 4 (parallel [
>             (set (subreg:SI (reg/v:DI 89 [ w ]) 0)
>                 (lshiftrt:SI (subreg:SI (reg/v:DI 87 [ uu ]) 0)
>                     (reg/v:SI 85 [ b ])))
>             (clobber (reg:SI 18 r18))
>         ]) 72 {lshrsi3_internal_reg_nohwshift} (nil)
>     (expr_list:REG_UNUSED (reg:SI 18 r18)
>         (nil)))
> 
> (insn 46 44 47 4 (set (reg:SI 94)
>         (lshiftrt:SI (subreg:SI (reg/v:DI 87 [ uu ]) 4)
>             (reg/v:SI 85 [ b ]))) -1 (nil)
>     (expr_list:REG_DEAD (reg/v:DI 87 [ uu ])
>         (expr_list:REG_DEAD (reg/v:SI 85 [ b ])
>             (expr_list:REG_EQUAL (lshiftrt:SI (subreg:SI (reg/v:DI 84 [ u ]) 
> 4)
>                     (reg/v:SI 85 [ b ]))
>                 (nil)))))
> 
> 
> Hence, I get an unrecognized insn error soon after. The only
> difference between 43 and 46 seems to be that 43 underwent a
> combination with 44 and is subregging 0, while 46 is subregging to
> byte 4.
> 
> Taking away the clobber makes the insn match and the code to compile.

When combining instructions, the combine pass will add clobbers if
needed to recognize the combined instruction.  This is documented in
the description of the RTL code CLOBBER.  What is happening here is
that combine sees that it can combine insns 43 and 44 if it adds a
clobber.  So it does that.

combine can't see how to combine insn 46 with anything, so it doesn't
add a clobber.

You seem to be saying that insn 44 as generated by combined is not
recognized.  I don't see why.  Doesn't it match the
lshrsi3_internal_reg_nohwshift pattern?  If it didn't, combine would
not generate it.

Ian

Reply via email to