On 07/12/11 13:11, Georg-Johann Lay wrote: > Not familiar with combine inerts, I'd like to know if > it's low hanging fruit to teach insn combine to perform > optimizations like the following. > > Suppose following C code, int = HI > > int y15; > int x15; > > void qmul8_xy (char c, int x, int y) > { > y15 = y * c; > x15 = x * c; > } > > and that the target has an insn like > > (set (reg:HI) > (mult:HI (sign_extend:HI (reg:QI)) > (reg:HI))) > > If there was just one multiplication, combine would > combine the sign_extend into the special mul insn. > (Provided costs are advantageous, of course) > > However, with the code example from above, combine > won't insert the sign_extend even if it was an > improvement, i.e. the sign_extend does not disappear > but the special mult is cheaper (or same cost) as the > ordinary mult. > > The original RTL reads: > > == Stage 0 == > > (set (reg:HI 42) > (sign_extend:HI (reg:QI 24))) > > (set (reg:HI 48) > (mult:HI (reg:HI 42) > (reg:HI 47))) > > (set (reg:HI 49) > (mult:HI (reg:HI 42) > (reg:HI 46))) > > == Stage 1 == > > Cheaper than Stage 0 but not performed > > (set (reg:HI 42) > (sign_extend:HI (reg:QI 24))) > > (set (reg:HI 48) > (mult:HI (sign_extend:HI (reg:QI 24)) > (reg:HI 47))) > > (set (reg:HI 49) > (mult:HI (reg:HI 42) > (reg:HI 46))) > > == Stage 2 == > > Cheaper than Stage 0 and Stage 1, would be performed > if we had Stage 1. > > (set (reg:HI 48) > (mult:HI (sign_extend:HI (reg:QI 24)) > (reg:HI 47))) > > (set (reg:HI 49) > (mult:HI (sign_extend:HI (reg:QI 24)) > (reg:HI 46)))
You could try the following, which allows 2->2 insn combinations assuming the costs are right. Bernd
Index: gcc/combine.c =================================================================== --- gcc/combine.c (revision 316468) +++ gcc/combine.c (working copy) @@ -3511,7 +3511,7 @@ try_combine (rtx i3, rtx i2, rtx i1, int as two separate insns. This case occurs when some SET allows two other insns to combine, but the destination of that SET is still live. */ - else if (i1 && insn_code_number < 0 && asm_noperands (newpat) < 0 + else if (insn_code_number < 0 && asm_noperands (newpat) < 0 && GET_CODE (newpat) == PARALLEL && XVECLEN (newpat, 0) == 2 && GET_CODE (XVECEXP (newpat, 0, 0)) == SET @@ -3883,7 +3883,7 @@ try_combine (rtx i3, rtx i2, rtx i1, int patterns, move from I1 to I2 then I2 to I3 so that we get the proper movement on registers that I2 modifies. */ - if (newi2pat) + if (newi2pat && i1) { move_deaths (newi2pat, NULL_RTX, DF_INSN_LUID (i1), i2, &midnotes); move_deaths (newpat, newi2pat, DF_INSN_LUID (i1), i3, &midnotes);