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