Problem on i386 with -fpic -fomit-frame-pointer

Bernd Schmidt crux@pool.informatik.rwth-aachen.de
Fri Aug 28 05:22:00 GMT 1998


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;
 




More information about the Gcc mailing list