Bootstrap build failure in ss20000201

Richard Henderson rth@cygnus.com
Tue Feb 1 23:47:00 GMT 2000


On Tue, Feb 01, 2000 at 12:58:54PM -0500, David Ronis wrote:
> ./genflags ../../egcs/gcc/config/i386/i386.md > tmp-flags.h
> make[2]: *** [s-flags] Error 139

This isn't pretty.  We had an instruction

	(set (mem:si (pre_dec:si (reg:si sp)))
	     (reg:si argp))

that caused reload to decide that the argp->sp elimination
wasn't valid.  Which left us with an argp->fp elimiation,
except that we didn't have a frame pointer to eliminate to.

My gut says there's a bug in the elimination code here, but
I'm not sure exactly what it is that should happen instead.
Much easier is to simply avoid this corner case.


r~

        * i386.c (general_no_elim_operand): New.
        (nonmemory_no_elim_operand): New.
        (ix86_expand_move): Copy eliminable operands before a push.
        * i386-protos.h: Declare new functions.
        * i386.h (CAN_ELIMINATE): Simplify.
        (PREDICATE_CODES): Update.
        * i386.md (push insns): Don't allow eliminable register operands.

Index: config/i386/i386-protos.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/i386/i386-protos.h,v
retrieving revision 1.11
diff -c -p -d -r1.11 i386-protos.h
*** i386-protos.h	2000/01/25 05:59:17	1.11
--- i386-protos.h	2000/02/02 07:37:23
*************** extern int const1_operand PARAMS ((rtx, 
*** 50,55 ****
--- 50,57 ----
  extern int const248_operand PARAMS ((rtx, enum machine_mode));
  extern int incdec_operand PARAMS ((rtx, enum machine_mode));
  extern int reg_no_sp_operand PARAMS ((rtx, enum machine_mode));
+ extern int general_no_elim_operand PARAMS ((rtx, enum machine_mode));
+ extern int nonmemory_no_elim_operand PARAMS ((rtx, enum machine_mode));
  extern int q_regs_operand PARAMS ((rtx, enum machine_mode));
  extern int non_q_regs_operand PARAMS ((rtx, enum machine_mode));
  extern int no_comparison_operator PARAMS ((rtx, enum machine_mode));
Index: config/i386/i386.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/i386/i386.c,v
retrieving revision 1.131
diff -c -p -d -r1.131 i386.c
*** i386.c	2000/02/01 23:51:38	1.131
--- i386.c	2000/02/02 07:37:23
*************** reg_no_sp_operand (op, mode)
*** 1168,1173 ****
--- 1168,1211 ----
    return register_operand (op, mode);
  }
  
+ /* Return false if this is any eliminable register.  Otherwise
+    general_operand.  */
+ 
+ int
+ general_no_elim_operand (op, mode)
+      register rtx op;
+      enum machine_mode mode;
+ {
+   rtx t = op;
+   if (GET_CODE (t) == SUBREG)
+     t = SUBREG_REG (t);
+   if (t == arg_pointer_rtx || t == frame_pointer_rtx
+       || t == virtual_incoming_args_rtx || t == virtual_stack_vars_rtx
+       || t == virtual_stack_dynamic_rtx)
+     return 0;
+ 
+   return general_operand (op, mode);
+ }
+ 
+ /* Return false if this is any eliminable register.  Otherwise
+    register_operand or const_int.  */
+ 
+ int
+ nonmemory_no_elim_operand (op, mode)
+      register rtx op;
+      enum machine_mode mode;
+ {
+   rtx t = op;
+   if (GET_CODE (t) == SUBREG)
+     t = SUBREG_REG (t);
+   if (t == arg_pointer_rtx || t == frame_pointer_rtx
+       || t == virtual_incoming_args_rtx || t == virtual_stack_vars_rtx
+       || t == virtual_stack_dynamic_rtx)
+     return 0;
+ 
+   return GET_CODE (op) == CONST_INT || register_operand (op, mode);
+ }
+ 
  /* Return true if op is a Q_REGS class register.  */
  
  int
*************** ix86_expand_move (mode, operands)
*** 3986,3991 ****
--- 4024,4033 ----
  	      || !push_operand (operands[0], mode))
  	  && GET_CODE (operands[1]) == MEM)
  	operands[1] = force_reg (mode, operands[1]);
+ 
+       if (push_operand (operands[0], mode)
+ 	  && ! general_no_elim_operand (operands[1], mode))
+ 	operands[1] = copy_to_mode_reg (mode, operands[1]);
  
        if (FLOAT_MODE_P (mode))
  	{
Index: config/i386/i386.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/i386/i386.h,v
retrieving revision 1.97
diff -c -p -d -r1.97 i386.h
*** i386.h	2000/02/01 23:51:38	1.97
--- i386.h	2000/02/02 07:37:23
*************** pop{l} %0"							\
*** 1411,1429 ****
   { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM},		\
   { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}}	\
  
! /* Given FROM and TO register numbers, say whether this elimination is allowed.
!    Frame pointer elimination is automatically handled.
! 
!    For the i386, if frame pointer elimination is being done, we would like to
!    convert ap into sp, not fp.
  
     All other eliminations are valid.  */
  
! #define CAN_ELIMINATE(FROM, TO)						\
!  ((((FROM) == ARG_POINTER_REGNUM || (FROM) == FRAME_POINTER_REGNUM)	\
!    && (TO) == STACK_POINTER_REGNUM)					\
!   ? ! frame_pointer_needed						\
!   : 1)
  
  /* Define the offset between two registers, one to be eliminated, and the other
     its replacement, at the start of a routine.  */
--- 1411,1423 ----
   { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM},		\
   { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}}	\
  
! /* Given FROM and TO register numbers, say whether this elimination is
!    allowed.  Frame pointer elimination is automatically handled.
  
     All other eliminations are valid.  */
  
! #define CAN_ELIMINATE(FROM, TO) \
!   ((TO) == STACK_POINTER_REGNUM ? ! frame_pointer_needed : 1)
  
  /* Define the offset between two registers, one to be eliminated, and the other
     its replacement, at the start of a routine.  */
*************** do { long l;						\
*** 2436,2441 ****
--- 2430,2438 ----
    {"const248_operand", {CONST_INT}},					\
    {"incdec_operand", {CONST_INT}},					\
    {"reg_no_sp_operand", {SUBREG, REG}},					\
+   {"general_no_elim_operand", {CONST_INT, CONST_DOUBLE, CONST,		\
+ 			SYMBOL_REF, LABEL_REF, SUBREG, REG, MEM}},	\
+   {"nonmemory_no_elim_operand", {CONST_INT, REG, SUBREG}},		\
    {"q_regs_operand", {SUBREG, REG}},					\
    {"non_q_regs_operand", {SUBREG, REG}},				\
    {"no_comparison_operator", {EQ, NE, LT, GE, LTU, GTU, LEU, GEU}},	\
Index: config/i386/i386.md
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/i386/i386.md,v
retrieving revision 1.131
diff -c -p -d -r1.131 i386.md
*** i386.md	2000/01/24 15:54:35	1.131
--- i386.md	2000/02/02 07:37:23
***************
*** 1281,1287 ****
  
  (define_insn "pushsi2"
    [(set (match_operand:SI 0 "push_operand" "=<")
! 	(match_operand:SI 1 "general_operand" "ri*m"))]
    ""
    "push{l}\\t%1"
    [(set_attr "type" "push")])
--- 1281,1287 ----
  
  (define_insn "pushsi2"
    [(set (match_operand:SI 0 "push_operand" "=<")
! 	(match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
    ""
    "push{l}\\t%1"
    [(set_attr "type" "push")])
***************
*** 1361,1367 ****
  
  (define_insn "pushhi2"
    [(set (match_operand:HI 0 "push_operand" "=<,<")
! 	(match_operand:HI 1 "general_operand" "n,r*m"))]
    ""
    "@
     push{w}\\t{|WORD PTR }%1
--- 1361,1367 ----
  
  (define_insn "pushhi2"
    [(set (match_operand:HI 0 "push_operand" "=<,<")
! 	(match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
    ""
    "@
     push{w}\\t{|WORD PTR }%1
***************
*** 1479,1485 ****
  
  (define_insn "pushqi2"
    [(set (match_operand:QI 0 "push_operand" "=<,<")
! 	(match_operand:QI 1 "nonmemory_operand" "n,r"))]
    ""
    "@
     push{w}\\t{|word ptr }%1
--- 1479,1485 ----
  
  (define_insn "pushqi2"
    [(set (match_operand:QI 0 "push_operand" "=<,<")
! 	(match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
    ""
    "@
     push{w}\\t{|word ptr }%1
***************
*** 1693,1699 ****
  
  (define_insn "*pushdi"
    [(set (match_operand:DI 0 "push_operand" "=<")
! 	(match_operand:DI 1 "general_operand" "riF*m"))]
    ""
    "#")
  
--- 1693,1699 ----
  
  (define_insn "*pushdi"
    [(set (match_operand:DI 0 "push_operand" "=<")
! 	(match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
    ""
    "#")
  
***************
*** 1727,1733 ****
  
  (define_insn "*pushsf"
    [(set (match_operand:SF 0 "push_operand" "=<,<")
! 	(match_operand:SF 1 "general_operand" "f#r,rFm#f"))]
    ""
    "*
  {
--- 1727,1733 ----
  
  (define_insn "*pushsf"
    [(set (match_operand:SF 0 "push_operand" "=<,<")
! 	(match_operand:SF 1 "general_no_elim_operand" "f#r,rFm#f"))]
    ""
    "*
  {
***************
*** 1861,1867 ****
  
  (define_insn "*pushdf"
    [(set (match_operand:DF 0 "push_operand" "=<,<")
! 	(match_operand:DF 1 "general_operand" "f#r,rFo#f"))]
    ""
    "*
  {
--- 1861,1867 ----
  
  (define_insn "*pushdf"
    [(set (match_operand:DF 0 "push_operand" "=<,<")
! 	(match_operand:DF 1 "general_no_elim_operand" "f#r,rFo#f"))]
    ""
    "*
  {
***************
*** 2057,2063 ****
  
  (define_insn "*pushxf_nointeger"
    [(set (match_operand:XF 0 "push_operand" "=<,<,<")
! 	(match_operand:XF 1 "general_operand" "f,Fo,*r"))]
    "optimize_size"
    "*
  {
--- 2057,2063 ----
  
  (define_insn "*pushxf_nointeger"
    [(set (match_operand:XF 0 "push_operand" "=<,<,<")
! 	(match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
    "optimize_size"
    "*
  {
***************
*** 2085,2091 ****
  
  (define_insn "*pushxf_integer"
    [(set (match_operand:XF 0 "push_operand" "=<,<")
! 	(match_operand:XF 1 "general_operand" "f#r,rFo#f"))]
    "!optimize_size"
    "*
  {
--- 2085,2091 ----
  
  (define_insn "*pushxf_integer"
    [(set (match_operand:XF 0 "push_operand" "=<,<")
! 	(match_operand:XF 1 "general_no_elim_operand" "f#r,rFo#f"))]
    "!optimize_size"
    "*
  {


More information about the Gcc-bugs mailing list