This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

fix aix -fcprop-register miscompilation


Finally got around to examining this.

We miscompiled compute_dom_prob_ps in sched-rgn.c.  The comment in the
first hunk of the patch describes the sequence of register moves that
led to the bug.

Bootstrapped and checked on aix4.3, i686 and alpha linux.


r~



        * regrename.c (find_oldest_value_reg): Ignore the value chain if
        the original register was copied in a mode with a fewer number of
        hard registers than the desired mode.
        (copyprop_hardreg_forward_1): Likewise.
        (debug_value_data): Fix loop test.
        * toplev.c (parse_options_and_default_flags): Reenable
        -fcprop-registers at -O1.

Index: regrename.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/regrename.c,v
retrieving revision 1.33
diff -c -p -d -r1.33 regrename.c
*** regrename.c	2001/12/31 23:16:05	1.33
--- regrename.c	2002/01/08 06:05:45
*************** find_oldest_value_reg (class, reg, vd)
*** 1282,1287 ****
--- 1282,1301 ----
    enum machine_mode mode = GET_MODE (reg);
    unsigned int i;
  
+   /* If we are accessing REG in some mode other that what we set it in,
+      make sure that the replacement is valid.  In particular, consider
+ 	(set (reg:DI r11) (...))
+ 	(set (reg:SI r9) (reg:SI r11))
+ 	(set (reg:SI r10) (...))
+ 	(set (...) (reg:DI r9))
+      Replacing r9 with r11 is invalid.  */
+   if (mode != vd->e[regno].mode)
+     {
+       if (HARD_REGNO_NREGS (regno, mode)
+ 	  > HARD_REGNO_NREGS (regno, vd->e[regno].mode))
+ 	return NULL_RTX;
+     }
+ 
    for (i = vd->e[regno].oldest_regno; i != regno; i = vd->e[i].next_regno)
      if (TEST_HARD_REG_BIT (reg_class_contents[class], i)
  	&& (vd->e[i].mode == mode
*************** copyprop_hardreg_forward_1 (bb, vd)
*** 1544,1549 ****
--- 1558,1572 ----
  	  unsigned int i;
  	  rtx new;
  
+ 	  /* If we are accessing SRC in some mode other that what we
+ 	     set it in, make sure that the replacement is valid.  */
+ 	  if (mode != vd->e[regno].mode)
+ 	    {
+ 	      if (HARD_REGNO_NREGS (regno, mode)
+ 		  > HARD_REGNO_NREGS (regno, vd->e[regno].mode))
+ 		goto no_move_special_case;
+ 	    }
+ 
  	  /* If the destination is also a register, try to find a source
  	     register in the same class.  */
  	  if (REG_P (SET_DEST (set)))
*************** copyprop_hardreg_forward_1 (bb, vd)
*** 1578,1583 ****
--- 1601,1607 ----
  		  }
  	      }
  	}
+       no_move_special_case:
  
        /* For each input operand, replace a hard register with the
  	 eldest live copy that's in an appropriate register class.  */
*************** debug_value_data (vd)
*** 1735,1741 ****
  	     j != INVALID_REGNUM;
  	     j = vd->e[j].next_regno)
  	  {
! 	    if (TEST_HARD_REG_BIT (set, vd->e[j].next_regno))
  	      {
  		fprintf (stderr, "[%u] Loop in regno chain\n", j);
  		return;
--- 1759,1765 ----
  	     j != INVALID_REGNUM;
  	     j = vd->e[j].next_regno)
  	  {
! 	    if (TEST_HARD_REG_BIT (set, j))
  	      {
  		fprintf (stderr, "[%u] Loop in regno chain\n", j);
  		return;
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/toplev.c,v
retrieving revision 1.566
diff -c -p -d -r1.566 toplev.c
*** toplev.c	2002/01/06 03:51:09	1.566
--- toplev.c	2002/01/08 06:05:45
*************** parse_options_and_default_flags (argc, a
*** 4663,4669 ****
        flag_omit_frame_pointer = 1;
  #endif
        flag_guess_branch_prob = 1;
!       /* flag_cprop_registers = 1; */
      }
  
    if (optimize >= 2)
--- 4663,4669 ----
        flag_omit_frame_pointer = 1;
  #endif
        flag_guess_branch_prob = 1;
!       flag_cprop_registers = 1;
      }
  
    if (optimize >= 2)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]