[Bug target/17381] Unnecessary register move for float extend
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=17381 --- Comment #9 from Martin Sebor --- Author: msebor Date: Thu Jan 28 21:05:39 2016 New Revision: 232947 URL: https://gcc.gnu.org/viewcvs?rev=232947=gcc=rev Log: PR target/17381 - Unnecessary register move for float extend 2016-01-28 Martin SeborPR target/17381 * gcc.target/powerpc/pr17381.c: New test. Added: trunk/gcc/testsuite/gcc.target/powerpc/pr17381.c Modified: trunk/gcc/testsuite/ChangeLog
[Bug target/17381] Unnecessary register move for float extend
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=17381 Martin Sebor changed: What|Removed |Added Status|NEW |RESOLVED CC||msebor at gcc dot gnu.org Resolution|--- |FIXED --- Comment #8 from Martin Sebor --- Trunk as well as the native 4.8.3 on RHEL 7.1 do not emit the redundant fmr instruction. Below is what I get today. Closing as fixed. $ /build/gcc-trunk/gcc/xgcc -B /build/gcc-trunk/gcc -O2 -S -Wall -Wextra -Wpedantic -m32 -o/dev/stdout ~/tmp/t.c .file "t.c" .machine power4 .section".text" .align 2 .p2align 4,,15 .globl test1 .type test1, @function test1: fmr 0,1 lis 9,f@ha stfs 1,f@l(9) lis 9,d@ha stfd 0,d@l(9) blr .size test1,.-test1 .comm f,4,4 .comm d,8,8 .ident "GCC: (GNU) 6.0.0 20160125 (experimental)" .gnu_attribute 4, 1 .section.note.GNU-stack,"",@progbits
[Bug target/17381] Unnecessary register move for float extend
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17381 Andrew Pinski pinskia at gcc dot gnu.org changed: What|Removed |Added Status|ASSIGNED|NEW AssignedTo|pinskia at gcc dot gnu.org |unassigned at gcc dot ||gnu.org --- Comment #7 from Andrew Pinski pinskia at gcc dot gnu.org 2011-11-29 23:20:48 UTC --- No longer working on this though I will submit at least the regrename patch soon.
[Bug target/17381] Unnecessary register move for float extend
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17381 --- Comment #6 from Andrew Pinski pinskia at gcc dot gnu.org 2011-01-05 00:15:50 UTC --- (In reply to comment #5) This is the patch which fixes the issue:Index: regrename.c === --- regrename.c (revision 3023) +++ regrename.c (working copy) @@ -1374,6 +1374,10 @@ maybe_mode_change (enum machine_mode ori enum machine_mode new_mode, unsigned int regno, unsigned int copy_regno ATTRIBUTE_UNUSED) { + if (GET_MODE_SIZE (copy_mode) == GET_MODE_SIZE (new_mode) + hard_regno_nregs[copy_regno][copy_mode] == hard_regno_nregs[copy_regno][new_mode] + hard_regno_nregs[regno][copy_mode] == hard_regno_nregs[copy_regno][new_mode]) +return gen_rtx_raw_REG (new_mode, regno); if (orig_mode == new_mode) return gen_rtx_raw_REG (new_mode, regno); else if (mode_change_ok (orig_mode, new_mode, regno)) MIPS64 has a similar issue too, take: long long d; int test1(int fParm) { d = fParm + 1; return fParm + 1; } The same regrename.c patch is needed to fix the MIPS64 issue too.
[Bug target/17381] Unnecessary register move for float extend
--- Comment #5 from pinskia at gcc dot gnu dot org 2009-01-15 19:58 --- This is the patch which fixes the issue:Index: regrename.c === --- regrename.c (revision 3023) +++ regrename.c (working copy) @@ -1374,6 +1374,10 @@ maybe_mode_change (enum machine_mode ori enum machine_mode new_mode, unsigned int regno, unsigned int copy_regno ATTRIBUTE_UNUSED) { + if (GET_MODE_SIZE (copy_mode) == GET_MODE_SIZE (new_mode) + hard_regno_nregs[copy_regno][copy_mode] == hard_regno_nregs[copy_regno][new_mode] + hard_regno_nregs[regno][copy_mode] == hard_regno_nregs[copy_regno][new_mode]) +return gen_rtx_raw_REG (new_mode, regno); if (orig_mode == new_mode) return gen_rtx_raw_REG (new_mode, regno); else if (mode_change_ok (orig_mode, new_mode, regno)) Index: config/rs6000/rs6000.md === --- config/rs6000/rs6000.md (revision 3023) +++ config/rs6000/rs6000.md (working copy) @@ -5247,10 +5247,17 @@ (define_insn_and_split *extendsfdf2_fpr # fmr %0,%1 lfs%U1%X1 %0,%1 - reload_completed REG_P (operands[1]) REGNO (operands[0]) == REGNO (operands[1]) + reload_completed REG_P (operands[1]) [(const_int 0)] { - emit_note (NOTE_INSN_DELETED); + if (REGNO (operands[0]) == REGNO (operands[1])) +emit_note (NOTE_INSN_DELETED); + else +{ + rtx op0 = gen_rtx_REG (DFmode, REGNO (operands[0])); + rtx op1 = gen_rtx_REG (DFmode, REGNO (operands[1])); + emit_insn (gen_move_insn (op0, op1)); +} DONE; } [(set_attr type fp,fp,fpload)]) The rs6000 part is to tell the compiler what is really going on after register allocator. The regrename part allows to do a hard register copy propagation after reload. So we have: (set (reg:SF 1) ... ) (set (reg:DF 2) (reg:DF 1)) (use (reg:DF 2)) After the rs6000.md patch. Since the copy, is using the register in the larger mode (DF), the last instruction should be just (use (reg:DF 1)). This patch allows for that. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17381
[Bug target/17381] Unnecessary register move for float extend
--- Comment #4 from pinskia at gcc dot gnu dot org 2009-01-14 19:52 --- I almost have a patch for this. -- pinskia at gcc dot gnu dot org changed: What|Removed |Added AssignedTo|unassigned at gcc dot gnu |pinskia at gcc dot gnu dot |dot org |org Status|NEW |ASSIGNED http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17381
[Bug target/17381] Unnecessary register move for float extend
--- Comment #2 from pinskia at gcc dot gnu dot org 2005-12-18 02:10 --- It is even worse with: double d; float test1(float fParm) { d = fParm + 1.0; return fParm + 1.0f; } We get two extra fmr's and one extra load: _test1: fmr f12,f1 extra fmr lis r2,ha16(LC1) fmr f0,f1 extra fmr lfs f13,lo16(LC1)(r2) --- load of 1.0f lfs f1,lo16(LC1)(r2) --- load of 1.0f, extra load lis r2,ha16(_d) fadd f0,f0,f13 fadds f1,f12,f1 stfd f0,lo16(_d)(r2) blr -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17381
[Bug target/17381] Unnecessary register move for float extend
--- Comment #3 from pinskia at gcc dot gnu dot org 2005-12-18 02:37 --- (In reply to comment #2) We get two extra fmr's and one extra load: I filed the extra load as PR 25474. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17381