unrolling bug

Michael Hayes m.hayes@elec.canterbury.ac.nz
Fri Dec 4 19:31:00 GMT 1998


Jeffrey A Law writes:
 > 
 > This is causing gcc to mis-compile g++, at least on the x86.
 > 
 > Compile this testcase either on x86-linux native or with an x86 cross
 > compiler using -O -funroll-loops

This patch appears to fix the problem.

Sat Dec  5 16:23:31 1998  Michael Hayes  <m.hayes@elec.canterbury.ac.nz>

	* loop.c (check_dbra_loop): New argument loop_info.
	Update initial and final loop values in loop_info structure
	if loop reversed.

Index: loop.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/loop.c,v
retrieving revision 1.100
diff -c -3 -p -r1.100 loop.c
*** loop.c	1998/11/25 21:19:16	1.100
--- loop.c	1998/12/05 03:29:02
*************** static int basic_induction_var PROTO((rt
*** 312,318 ****
  static rtx simplify_giv_expr PROTO((rtx, int *));
  static int general_induction_var PROTO((rtx, rtx *, rtx *, rtx *, int, int *));
  static int consec_sets_giv PROTO((int, rtx, rtx, rtx, rtx *, rtx *));
! static int check_dbra_loop PROTO((rtx, int, rtx));
  static rtx express_from_1 PROTO((rtx, rtx, rtx));
  static rtx express_from PROTO((struct induction *, struct induction *));
  static rtx combine_givs_p PROTO((struct induction *, struct induction *));
--- 312,318 ----
  static rtx simplify_giv_expr PROTO((rtx, int *));
  static int general_induction_var PROTO((rtx, rtx *, rtx *, rtx *, int, int *));
  static int consec_sets_giv PROTO((int, rtx, rtx, rtx, rtx *, rtx *));
! static int check_dbra_loop PROTO((rtx, int, rtx, struct loop_info *));
  static rtx express_from_1 PROTO((rtx, rtx, rtx));
  static rtx express_from PROTO((struct induction *, struct induction *));
  static rtx combine_givs_p PROTO((struct induction *, struct induction *));
*************** strength_reduce (scan_start, end, loop_t
*** 4041,4047 ****
    /* Try to prove that the loop counter variable (if any) is always
       nonnegative; if so, record that fact with a REG_NONNEG note
       so that "decrement and branch until zero" insn can be used.  */
!   check_dbra_loop (loop_end, insn_count, loop_start);
  
    /* Create reg_map to hold substitutions for replaceable giv regs.  */
    reg_map = (rtx *) alloca (max_reg_before_loop * sizeof (rtx));
--- 4041,4047 ----
    /* Try to prove that the loop counter variable (if any) is always
       nonnegative; if so, record that fact with a REG_NONNEG note
       so that "decrement and branch until zero" insn can be used.  */
!   check_dbra_loop (loop_end, insn_count, loop_start, loop_info);
  
    /* Create reg_map to hold substitutions for replaceable giv regs.  */
    reg_map = (rtx *) alloca (max_reg_before_loop * sizeof (rtx));
*************** product_cheap_p (a, b)
*** 6634,6643 ****
     final_[bg]iv_value.  */
  
  static int
! check_dbra_loop (loop_end, insn_count, loop_start)
       rtx loop_end;
       int insn_count;
       rtx loop_start;
  {
    struct iv_class *bl;
    rtx reg;
--- 6634,6644 ----
     final_[bg]iv_value.  */
  
  static int
! check_dbra_loop (loop_end, insn_count, loop_start, loop_info)
       rtx loop_end;
       int insn_count;
       rtx loop_start;
+      struct loop_info *loop_info;
  {
    struct iv_class *bl;
    rtx reg;
*************** check_dbra_loop (loop_end, insn_count, l
*** 7064,7069 ****
--- 7065,7076 ----
  	      bl->biv->insn = p;
  	      bl->initial_value = start_value;
  	      bl->biv->add_val = new_add_val;
+ 
+ 	      /* Update loop info.  */
+ 	      loop_info->initial_value = bl->initial_value;
+ 	      loop_info->initial_equiv_value = bl->initial_value;
+ 	      loop_info->final_value = const0_rtx;
+ 	      loop_info->final_equiv_value = const0_rtx;
  
  	      /* Inc LABEL_NUSES so that delete_insn will
  		 not delete the label.  */



More information about the Gcc-patches mailing list