RFH and fix for PR32367

Sebastian Pop sebpop@gmail.com
Wed Jun 20 09:44:00 GMT 2007


Hello,

On 6/19/07, Zdenek Dvorak <rakdver@kam.mff.cuni.cz> wrote:
> IIRC, we intentionally allow the components of chrecs to be varying in
> the loop -- instantiate_parameters/resolve_mixers are responsible for
> eliminating such chrecs.

It is only the CHREC_RIGHT part that might contain chrecs varying in
the same loop.  CHREC_LEFT is the initial value when entering the loop
and it shouldn't contain varying elements in that loop.  This is also
what we assume when doing plus or apply operations on chrecs.

> It might be better to find why this does
> not happen (i.e., why instantiate_parameters/resolve_mixers are not
> called or do not eliminate these chrecs) and fix the problem there.
>

The problem occurs before the calls to instantiate_parameters or
resolve_mixers.  It occurs during the analysis part, i.e. in the code

*************** interpret_rhs_modify_stmt (struct loop *
*** 1611,1616 ****
--- 1615,1630 ----

    switch (TREE_CODE (opnd1))
      {
+     case POINTER_PLUS_EXPR:
+       opnd10 = TREE_OPERAND (opnd1, 0);
+       opnd11 = TREE_OPERAND (opnd1, 1);
+       chrec10 = analyze_scalar_evolution (loop, opnd10);
+       chrec11 = analyze_scalar_evolution (loop, opnd11);
+       chrec10 = chrec_convert (type, chrec10, at_stmt);
+       chrec11 = chrec_convert (sizetype, chrec11, at_stmt);
+       res = chrec_fold_plus (type, chrec10, chrec11);
+       break;
+
      case PLUS_EXPR:
        opnd10 = TREE_OPERAND (opnd1, 0);
        opnd11 = TREE_OPERAND (opnd1, 1);

At this point we have the following values:
(gdb) call debug_generic_expr (chrec10)
{ptr_7, +, (unsigned int) (n_20 + 65535) * 4}_1
(gdb) call debug_generic_expr (chrec11)
(unsigned int) {n_6 + 65535, +, 1}_1 * 4
(gdb) call debug_generic_expr (res)
{ptr_7 + (unsigned int) {n_6 + 65535, +, 1}_1 * 4, +, (unsigned int)
(n_20 + 65535) * 4}_1

The multiplication and other operations on chrecs are independent of
instantiate_parameters and resolve_mixers.  In this case, the initial
condition CHREC_LEFT should not be varying in loop_1, i.e. we just
added two affine functions in loop_1, so it is chrec_fold_plus that is
causing this error because the unfolded multiplication for chrec11 was
considered as a constant expression in loop_1.

> > A further fix would improve fold to distribute the multiplication in
> > the case of an (unsigned int) MULT_EXPR with a PLUS_EXPR already
> > casted to (unsigned int), i.e.
> >
> > #0  fold_build2_stat (code=MULT_EXPR, type=0xb7c41000, op0=0xb7cda6a0,
> > op1=0xb7c32444) at ../../gcc/fold-const.c:12944
> > (gdb)  call debug_generic_expr (type)
> > unsigned int
> > (gdb)  call debug_generic_expr (op0)
> > (unsigned int) (n_20 + 65535)
> > (gdb)  call debug_generic_expr (op1)
> > 4
> > (gdb)  call debug_generic_expr (tem)
> > (unsigned int) (n_20 + 65535) * 4
> >
> > I would expect to see the result in "tem" to be:
> > (unsigned int) (n_20 * 4 + 262140)
> >
> > As I'm not familiar with fold, I'd appreciate your help and suggestions
> > on how to implement this transform.
>
> In general, this cannot be done unless you know that the multiplication
> does not overflow (assuming that the inner type is signed).

Okay.

The inner type is short unsigned int, and it does overflow on the
multiplication 65535 * 4 mod 65536, so the result is not what I was
expecting but something like (unsigned int) (n_20 * 4 + 65532) if we
strip the nops.



More information about the Gcc-patches mailing list