This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug rtl-optimization/29930] New: Omitted conversion float -> double in x86 back-end
- From: "roberto dot costa at st dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 21 Nov 2006 16:47:16 -0000
- Subject: [Bug rtl-optimization/29930] New: Omitted conversion float -> double in x86 back-end
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
In a sequence of conversions signed long long -> float -> double, x86 back-end
eats the intermediate conversion away.
In this case, the conversion to float isn't redundant because it lowers the
precision of the computation (which is something a programmer may want to do).
Here is a simple example:
------------- float_conv.c ------------
double foo(signed long long l)
{
return (float)l;
}
---------------------------------------
Files float_conv.c.026t.fixupcfg and float_conv.s are the outcome of the
following compilation:
gcc -O0 float_conv.c -S -fdump-tree-all
------ float_conv.c.026t.fixupcfg -----
;; Function foo (foo)
foo (l)
{
float D.1524;
double D.1523;
<bb 2>:
D.1524 = (float) l;
D.1523 = (double) D.1524;
return D.1523;
}
---------------------------------------
------------- float_conv.s ------------
.file "float_conv.c"
.text
.globl foo
.type foo, @function
foo:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
movl 8(%ebp), %eax
movl %eax, -8(%ebp)
movl 12(%ebp), %eax
movl %eax, -4(%ebp)
fildll -8(%ebp)
leave
ret
.size foo, .-foo
.ident "GCC: (GNU) 4.2.0 20060826 (experimental)"
.section .note.GNU-stack,"",@progbits
---------------------------------------
The conversion is still there at the end of GIMPLE passes, which leads to the
conclusion that it is removed in RTL compilation.
With -O2 after expand we have
;; return (double) (float) l
(insn 10 9 11 (set (reg:SF 62)
(float:SF (reg/v:DI 60 [ l ]))) -1 (nil)
(nil))
(insn 11 10 12 (set (reg:DF 61)
(float_extend:DF (reg:SF 62))) -1 (nil)
(nil))
(insn 12 11 13 (set (reg:DF 59 [ <result> ])
(reg:DF 61)) -1 (nil)
(nil))
which is ok. Even after combine it's ok:
(insn 10 7 15 2 (set (reg:SF 62)
(float:SF (mem/c/i:DI (reg/f:SI 16 argp) [3 l+0 S8 A32]))) 172
{*floatdisf2_i387} (nil)
(nil))
(note 15 10 18 2 NOTE_INSN_FUNCTION_END)
(insn 18 15 24 2 (set (reg/i:DF 8 st [ <result> ])
(float_extend:DF (reg:SF 62))) 125 {*extendsfdf2_i387}
(insn_list:REG_DEP_TRUE 10 (nil))
(expr_list:REG_DEAD (reg:SF 62)
(nil)))
(insn 24 18 0 2 (use (reg/i:DF 8 st [ <result> ])) -1
(insn_list:REG_DEP_TRUE 18 (nil))
(nil))
but then regstack comes along and
(insn:TI 10 32 33 2 (set (reg:SF 8 st)
(float:SF (mem/c/i:DI (plus:SI (reg/f:SI 6 bp)
(const_int 8 [0x8])) [3 l+0 S8 A32]))) 172
{*floatdisf2_i387} (nil)
(nil))
(note 33 10 34 2 NOTE_INSN_EPILOGUE_BEG)
(insn:TI 34 33 24 2 (parallel [
(set (reg/f:SI 6 bp)
(mem:SI (reg/f:SI 7 sp) [0 S4 A8]))
(set (reg/f:SI 7 sp)
(plus:SI (reg/f:SI 7 sp)
(const_int 4 [0x4])))
]) 37 {popsi1} (nil)
(nil))
(insn 24 34 35 2 (use (reg/i:DF 8 st [ <result> ])) -1 (nil)
(nil))
where the *floatdisf2_i387 pattern misses the truncation to SFmode.
--
Summary: Omitted conversion float -> double in x86 back-end
Product: gcc
Version: 4.3.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: rtl-optimization
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: roberto dot costa at st dot com
GCC build triplet: i486-linux-gnu
GCC host triplet: i486-linux-gnu
GCC target triplet: i486-linux-gnu
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29930