This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Problem on i386 with -fpic -fomit-frame-pointer
- To: egcs at cygnus dot com
- Subject: Problem on i386 with -fpic -fomit-frame-pointer
- From: Bernd Schmidt <crux at pool dot informatik dot rwth-aachen dot de>
- Date: Fri, 28 Aug 1998 13:56:57 +0200 (MET DST)
- cc: hjl at gnu dot org
With the reload patch I sent in on Monday, gcc miscompiled the file e_hypotl.c
from glibc-2.0.95. The problem appears to be in i386.md, in the mov[sdx]f
patterns. I believe the following change is incomplete:
Sun Jul 26 01:11:12 1998 H.J. Lu (hjl@gnu.org)
* i386.h (CONST_DOUBLE_OK_FOR_LETTER_P): Return 0 when eliminating
the frame pointer and compiling PIC code and reload has not completed.
If using -fomit-frame-pointer together with -fPIC, this will not accept any
floating point constants, and reload will substitute memory references for
them. However, the expander patterns have not been updated together with
this patch, they still assume that certain constants are valid. The result
was that in the file that was miscompiled, a load instruction using the PIC
register was emitted, but during reload the variable
current_function_uses_pic_offset_table remains set to zero. This causes
incorrect register elimination offsets, which in turn causes some of the
generated store instructions to write data outside the stack frame and
clobber one of the callee-saved registers.
Bernd
* i386.md (movsf, movdf, movxf): Accept no constants if -fPIC and
-fomit-frame-pointer.
diff -u -r1.1.1.28 i386.md
--- i386.md 1998/08/05 12:00:31 1.1.1.28
+++ i386.md 1998/08/28 10:07:09
@@ -1230,14 +1230,15 @@
operands[1] = force_reg (SFmode, operands[1]);
}
- /* If we are loading a floating point constant that isn't 0 or 1
- into a register, indicate we need the pic register loaded. This could
- be optimized into stores of constants if the target eventually moves
- to memory, but better safe than sorry. */
+ /* If we are loading a floating point constant that isn't 0 or 1 into a
+ register, indicate we need the pic register loaded. This could be
+ optimized into stores of constants if the target eventually moves to
+ memory, but better safe than sorry. */
else if ((reload_in_progress | reload_completed) == 0
&& GET_CODE (operands[0]) != MEM
&& GET_CODE (operands[1]) == CONST_DOUBLE
- && !standard_80387_constant_p (operands[1]))
+ && ((flag_pic && flag_omit_frame_pointer)
+ || ! standard_80387_constant_p (operands[1])))
{
rtx insn, note, fp_const;
@@ -1385,7 +1386,8 @@
else if ((reload_in_progress | reload_completed) == 0
&& GET_CODE (operands[0]) != MEM
&& GET_CODE (operands[1]) == CONST_DOUBLE
- && !standard_80387_constant_p (operands[1]))
+ && ((flag_pic && flag_omit_frame_pointer)
+ || ! standard_80387_constant_p (operands[1])))
{
rtx insn, note, fp_const;
@@ -1527,14 +1529,15 @@
operands[1] = force_reg (XFmode, operands[1]);
}
- /* If we are loading a floating point constant that isn't 0 or 1
- into a register, indicate we need the pic register loaded. This could
- be optimized into stores of constants if the target eventually moves
- to memory, but better safe than sorry. */
+ /* If we are loading a floating point constant that isn't 0 or 1 into a
+ register, indicate we need the pic register loaded. This could be
+ optimized into stores of constants if the target eventually moves to
+ memory, but better safe than sorry. */
else if ((reload_in_progress | reload_completed) == 0
&& GET_CODE (operands[0]) != MEM
&& GET_CODE (operands[1]) == CONST_DOUBLE
- && !standard_80387_constant_p (operands[1]))
+ && ((flag_pic && flag_omit_frame_pointer)
+ || ! standard_80387_constant_p (operands[1])))
{
rtx insn, note, fp_const;