[PATCH] Fix optimization/10904
Eric Botcazou
ebotcazou@libertysurf.fr
Sat Jun 7 20:58:00 GMT 2003
Hi,
GCC emits illegal assembly on mainline and 3.3 branch
fdtox %f10, %f7 (illegal, odd-numbered FP reg)
at -O2 for
int a = (long)(b * ((double) 0.1));
under certain circumstances on SPARC64. Note that this is a progression from
GCC 3.2.x which silently generates wrong code in the same situation.
Here's the chain of events: the combiner turns
(insn 30 29 31 0 0x40182fc0 (set (reg:DI 118)
(fix:DI (fix:DF (reg:DF 117)))) 167 {fix_truncdfdi2} (insn_list 29
(nil))
(expr_list:REG_DEAD (reg:DF 117)
(nil)))
(insn 31 30 33 0 0x40182fc0 (set (reg/v:SI 112)
(subreg:SI (reg:DI 118) 4)) 51 {*movsi_insn} (insn_list 30 (nil))
(expr_list:REG_DEAD (reg:DI 118)
(nil)))
into
(insn 31 30 33 0 0x40182fc0 (set (subreg:DI (reg/v:SI 112) 0)
(fix:DI (fix:DF (reg:DF 117)))) 167 {fix_truncdfdi2} (insn_list 29
(nil))
(expr_list:REG_DEAD (reg:DF 117)
(nil)))
which I think is correct on big-endian targets.
Then the (global) register allocator allocates %f8 to (reg/v:SI 112) because
it doesn't know that the pseudo has been paradoxically subreged. So
(subreg:DI (reg/v:SI 112) 0) ends up being assigned %f7-%f8.
I'm not sure how this is supposed to be fixed but, since the SPARC port
doesn't have constraints to enforce register alignments, I think the register
allocator must align the registers at the first go. There is already a
machinery to take into account constraints derived from subregization, based
on CANNOT_CHANGE_MODE_CLASS and regclass.c:cannot_change_mode_set_regs().
However it doesn't have the right granularity for the SPARC port, so I
overrided REG_CANNOT_CHANGE_MODE_P which gave me control on the REGNO.
Is this the right approach? I'm a bit worried because I'm afraid that reload
might screw up everything afterwards.
Bootstrapped/regtested (c,c++,objc,f77 mainline) on sparc64-sun-solaris2.9,
boostrapped on sparc-sun-solaris2.8 and i586-redhat-linux-gnu.
--
Eric Botcazou
2003-06-07 Eric Botcazou <ebotcazou@libertysurf.fr>
PR optimization/10904
* combine.c (subst): Conditionalize on REG_CANNOT_CHANGE_MODE_P
instead of CANNOT_CHANGE_MODE_CLASS.
(simplify_set): Likewise.
(gen_lowpart_for_combine): Likewise.
* flow.c (life_analysis): Likewise.
(mark_used_regs): Likewise.
* global.c (find_reg): Likewise.
* local-alloc.c (find_free_reg): Likewise.
* ra-build.c (init_one_web_common): Likewise.
(remember_web_was_spilled): Likewise.
* ra-colorize.c (colorize_one_web): Likewise.
* ra.c (init_ra): Likewise.
* recog.c (register_operand): Likewise.
* regclass.c (subregs_of_mode): Likewise.
(cannot_change_mode_set_regs): Likewise.
* regrename.c (mode_change_ok): Likewise.
* reload.c (push_reload): Likewise.
* reload1.c (choose_reload_reg): Likewise.
* simplify-rtx.c (simplify_subreg): Likewise.
* hard-reg-set.h (REG_CANNOT_CHANGE_MODE_P): Define if not defined
and CANNOT_CHANGE_MODE_CLASS is defined.
* config/sparc/sparc.h (REG_CANNOT_CHANGE_MODE_P): Define. Return
true on v9 for unaligned paradoxical subregs of floating-point registers.
* doc/tm.texi (REG_CANNOT_CHANGE_MODE_P): Document.
2003-06-07 Eric Botcazou <ebotcazou@libertysurf.fr>
* gcc.c-torture/execute/20030607-1.c: New test.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: pr10904-2.diff
Type: text/x-diff
Size: 14700 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20030607/8ce26bef/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 20030607-1.c
Type: text/x-csrc
Size: 443 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20030607/8ce26bef/attachment-0001.bin>
More information about the Gcc-patches
mailing list