On Thu, Sep 27, 2012 at 11:13 AM, Uros Bizjak <ubiz...@gmail.com> wrote: > On Thu, Sep 27, 2012 at 8:08 PM, <paul_kon...@dell.com> wrote: > >>>>>>> I agree (subreg:M (op:N A C) 0) to (op:M (subreg:N (A 0)) C) is >>>>>>> a good transformation, but why do we need to handle as special >>>>>>> the case where the subreg is itself the operand of a plus or minus? >>>>>>> I think it should happen regardless of where the subreg occurs. >>>>>> >>>>>> Don't we need to restrict this to the low part though? >>>>> >>>>> ... >>> >>> After some off-line discussion with Richard, attached is v2 of the patch. >>> >>> 2012-09-27 Uros Bizjak <ubiz...@gmail.com> >>> >>> PR rtl-optimization/54457 >>> * simplify-rtx.c (simplify_subreg): >>> Simplify (subreg:SI (op:DI ((x:DI) (y:DI)), 0) >>> to (op:SI (subreg:SI (x:DI) 0) (subreg:SI (x:DI) 0)). >>> ... >> >> Is it just specific to DI -> SI, or is it for any large mode -> smaller >> mode, like SI -> HI? > > Oh, I just copied v1 ChangeLog. The patch converts all modes where > size of mode M < size of mode N. Updated ChangeLog reads: > > 2012-09-27 Uros Bizjak <ubiz...@gmail.com> > > PR rtl-optimization/54457 > * simplify-rtx.c (simplify_subreg): > Simplify (subreg:M (op:N ((x:N) (y:N)), 0) > to (op:M (subreg:M (x:N) 0) (subreg:M (x:N) 0)), where > the outer subreg is effectively a truncation to the original mode M.
When I was doing something similar on our internal toolchain at Cavium. I found doing this caused a regression on MIPS64 n32 in gcc.c-torture/execute/20040709-1.c Where: (insn 15 14 16 2 (set (reg/v:DI 200 [ y ]) (reg:DI 2 $2)) t.c:16 301 {*movdi_64bit} (expr_list:REG_DEAD (reg:DI 2 $2) (nil))) (insn 16 15 17 2 (set (reg:DI 210) (zero_extract:DI (reg/v:DI 200 [ y ]) (const_int 29 [0x1d]) (const_int 0 [0]))) t.c:16 249 {extzvdi} (expr_list:REG_DEAD (reg/v:DI 200 [ y ]) (nil))) (insn 17 16 23 2 (set (reg:SI 211) (truncate:SI (reg:DI 210))) t.c:16 175 {truncdisi2} (expr_list:REG_DEAD (reg:DI 210) (nil))) Gets converted to: (insn 23 17 26 2 (set (reg/i:SI 2 $2) (and:SI (reg:SI 2 $2 [+4 ]) (const_int 536870911 [0x1fffffff]))) t.c:18 156 {*andsi3} (nil)) Which is considered an ext instruction And with the Octeon simulator which causes undefined arguments to 32bit word operations to come out as 0xDEADBEEF which showed the regression. I fixed it by changing it to produce TRUNCATE instead of the subreg. I did the simplification on ior/and rather than plus/minus/mult so the issue is only when expanding to this to and/ior. Thanks, Andrew Pinski > > testsuite/ChangeLog: > > 2012-09-27 Uros Bizjak <ubiz...@gmail.com> > > PR rtl-optimization/54457 > * gcc.target/i386/pr54457.c: New test. > > Uros.