This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: [lno] Bootstrap failure on Alpha due to miscompilation
Hello,
> > lno fails to bootstrap on Alpha for several days now; it segfaults
> > while compiling libgcc in the second stage, so apparently it
> > miscompiles itself.
> >
> > The only test suite failure that does not already occur on mainline
> > Alpha or on lno ia64 (according to gcc-testresults) is
> > gcc.c-torture/execute/961017-1.c. There, lno compiles at -O and above
> >
> > unsigned char z = 0;
> > do ; while (--z > 0);
> >
> > to a loop over the whole 64 bit space:
> >
> > clr $1
> > [...]
> > $L2: lda $1,1($1)
> > bne $1,$L2
> >
> > I'm not sure, however, whether it is this problem that causes the
> > bootstrap failure (people don't often rely on unsigned wrapping
> > semantics in loops...).
>
> I will have a look at this testsuite failure; however I do not have an
> access to the Alpha machine just now, so I won't be of much help with
> the bootstrap problem.
this patch fixes the testsuite failure.
Zdenek
Index: ChangeLog.lno
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/ChangeLog.lno,v
retrieving revision 1.1.2.212
diff -c -3 -p -r1.1.2.212 ChangeLog.lno
*** ChangeLog.lno 7 Jul 2004 15:46:37 -0000 1.1.2.212
--- ChangeLog.lno 8 Jul 2004 04:49:16 -0000
***************
*** 1,5 ****
--- 1,10 ----
2004-07-07 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+ * tree-ssa-loop-ivopts.c (cand_value_at): Handle types correctly.
+ (may_eliminate_iv): Verify there is no overflow.
+
+ 2004-07-07 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
* tree-ssa-loop-ivopts.c (find_bivs, find_givs_in_stmt_scev):
Ensure that step of the iv satisfies cst_and_fits_in_hwi.
(determine_use_iv_cost_outer): Preserve the fact that the cost
Index: tree-ssa-loop-ivopts.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-loop-ivopts.c,v
retrieving revision 1.1.2.43
diff -c -3 -p -r1.1.2.43 tree-ssa-loop-ivopts.c
*** tree-ssa-loop-ivopts.c 7 Jul 2004 15:46:37 -0000 1.1.2.43
--- tree-ssa-loop-ivopts.c 8 Jul 2004 04:49:16 -0000
*************** iv_value (struct iv *iv, tree niter)
*** 3219,3231 ****
static tree
cand_value_at (struct loop *loop, struct iv_cand *cand, tree at, tree niter)
{
! tree type = TREE_TYPE (niter);
if (stmt_after_increment (loop, cand, at))
! niter = fold (build (PLUS_EXPR, type, niter,
! convert (type, integer_one_node)));
! return iv_value (cand->iv, niter);
}
/* Check whether it is possible to express the condition in USE by comparison
--- 3219,3231 ----
static tree
cand_value_at (struct loop *loop, struct iv_cand *cand, tree at, tree niter)
{
! tree val = iv_value (cand->iv, niter);
! tree type = TREE_TYPE (cand->iv->base);
if (stmt_after_increment (loop, cand, at))
! val = fold (build (PLUS_EXPR, type, val, cand->iv->step));
! return val;
}
/* Check whether it is possible to express the condition in USE by comparison
*************** may_eliminate_iv (struct loop *loop,
*** 3238,3244 ****
enum tree_code *compare, tree *bound)
{
edge exit;
! struct tree_niter_desc *niter;
/* For now just very primitive -- we work just for the single exit condition,
and are quite conservative about the possible overflows. TODO -- both of
--- 3238,3245 ----
enum tree_code *compare, tree *bound)
{
edge exit;
! struct tree_niter_desc *niter, new_niter;
! tree wider_type, type, base;
/* For now just very primitive -- we work just for the single exit condition,
and are quite conservative about the possible overflows. TODO -- both of
*************** may_eliminate_iv (struct loop *loop,
*** 3251,3263 ****
niter = &loop_data (loop)->niter;
if (!niter->niter
! || !operand_equal_p (niter->assumptions, boolean_true_node, 0)
! || !operand_equal_p (niter->may_be_zero, boolean_false_node, 0))
return false;
- /* FIXME -- we ignore the possible overflow here. For example
- in case the loop iterates MAX_UNSIGNED_INT / 2 times and
- the step of candidate is 4, this is wrong. */
if (exit->flags & EDGE_TRUE_VALUE)
*compare = EQ_EXPR;
else
--- 3252,3261 ----
niter = &loop_data (loop)->niter;
if (!niter->niter
! || !integer_nonzerop (niter->assumptions)
! || !integer_zerop (niter->may_be_zero))
return false;
if (exit->flags & EDGE_TRUE_VALUE)
*compare = EQ_EXPR;
else
*************** may_eliminate_iv (struct loop *loop,
*** 3265,3270 ****
--- 3263,3291 ----
*bound = cand_value_at (loop, cand, use->stmt, niter->niter);
+ /* Let us check there is not some problem with overflows, by checking that
+ the number of iterations is unchanged. */
+ base = cand->iv->base;
+ type = TREE_TYPE (base);
+ if (stmt_after_increment (loop, cand, use->stmt))
+ base = fold (build (PLUS_EXPR, type, base, cand->iv->step));
+
+ new_niter.niter = NULL_TREE;
+ number_of_iterations_cond (TREE_TYPE (cand->iv->base), base,
+ cand->iv->step, NE_EXPR, *bound, NULL_TREE,
+ &new_niter);
+ if (!new_niter.niter
+ || !integer_nonzerop (new_niter.assumptions)
+ || !integer_zerop (new_niter.may_be_zero))
+ return false;
+
+ wider_type = TREE_TYPE (new_niter.niter);
+ if (TYPE_PRECISION (wider_type) < TYPE_PRECISION (TREE_TYPE (niter->niter)))
+ wider_type = TREE_TYPE (niter->niter);
+ if (!operand_equal_p (fold_convert (wider_type, niter->niter),
+ fold_convert (wider_type, new_niter.niter), 0))
+ return false;
+
return true;
}