[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