gfortran.fortran-torture/execute/scalarize.f90 is miscompiled at least
on x86_64-linux with -O2 -ftree-loop-linear (other miscompiled fortran
tests with -ftree-loop-linear are forall_1.f90 and der_type.f90).

The only linear transformed loop in scalarize.f90 is the
b(:, 5:1:-1) = a
one (i.e.
int8 S.2;

S.2 = 0;
while (1)
  {
    if (S.2 > 4) goto L.6; else (void) 0;
    {
      int8 D.1343;
      int8 D.1342;
      int8 S.3;

      D.1342 = (NON_LVALUE_EXPR <S.2> + 1) * 6 + -7;
      D.1343 = (5 - S.2) * 6 + -7;
      S.3 = 1;
      while (1)
        {
          if (S.3 > 6) goto L.5; else (void) 0;
          b[NON_LVALUE_EXPR <S.3> + D.1343] = a[NON_LVALUE_EXPR <S.3> +
D.1342];
          S.3 = S.3 + 1;
        }
      L.5:;
    }
    S.2 = S.2 + 1;
  }
L.6:;
).  When entering ltrans, this is not perfect nest, but perfect_nestify
changes it.  I believe that transformation is valid:

We have before ltrans (with loop entry L13 and loop exit
L85):
<L12>:;
  if (S.2_40 > 4) goto <L85>; else goto <L86>;
<L86>:;
  # S.2_165 = PHI <S.2_40(13), 0(11)>;
<L13>:;
  S.2_40 = S.2_165 + 1;
  D.1393_41 = S.2_40 * 6;
  D.1394_43 = 5 - S.2_165;
  D.1395_44 = D.1394_43 * 6;
  pretmp.59_117 = D.1395_44 + -7;
  pretmp.59_121 = D.1393_41 + -7;
  # S.3_171 = PHI <S.3_51(16), 1(14)>;
<L15>:;
  D.1343_45 = pretmp.59_117;
  D.1397_47 = pretmp.59_117 + S.3_171;
  D.1342_42 = pretmp.59_121;
  D.1398_48 = pretmp.59_121 + S.3_171;
  D.1399_49 = a[D.1398_48];
  b[D.1397_47] = D.1399_49;
  S.3_51 = S.3_171 + 1;
  if (S.3_51 > 6) goto <L12>; else goto <L87>;
<L87>:;
  goto <bb 15> (<L15>);
This isn't perfect nest due to the pretmp.59_* MODIFY_EXPRs
and their temporaries, and perfect_nestify transforms this into:
<L12>:;
  if (S.2_40 > 4) goto <L99>; else goto <L86>;
<L86>:;
  # S.2_165 = PHI <S.2_40(13), 0(11)>;
<L13>:;
  S.2_40 = S.2_165 + 1;
  # S.3_171 = PHI <S.3_51(16), 1(14)>;
<L15>:;
  D.1393_41 = S.2_40 * 6;
  D.1394_43 = 5 - S.2_165;
  D.1395_44 = D.1394_43 * 6;
  pretmp.59_117 = D.1395_44 + -7;
  pretmp.59_121 = D.1393_41 + -7;
  D.1343_45 = pretmp.59_117;
  D.1397_47 = pretmp.59_117 + S.3_171;
  D.1342_42 = pretmp.59_121;
  D.1398_48 = pretmp.59_121 + S.3_171;
  D.1399_49 = a[D.1398_48];
  b[D.1397_47] = D.1399_49;
  S.3_51 = S.3_171 + 1;
  if (S.3_51 > 6) goto <L12>; else goto <L87>;
<L87>:;
  goto <bb 15> (<L15>);
...
<L99>:;
  goto <bb 44> (<L100>);
  # perfectiv.73_65 = PHI <0(43), perfectiv.73_4(46)>;
<L100>:;
  uboundvar.74_155 = 4 + -1;
  perfectiv.73_4 = perfectiv.73_65 + 1;
  if (uboundvar.74_155 >= perfectiv.73_4) goto <L101>; else goto <L85>;
<L101>:;
  goto <bb 44> (<L100>);

(this was dumped before perfect_nest call at the end of perfect_nestify).
It looks just fine to me, all it did was move the pretmp.95_* and their
temporaries setting back into the L15 loop and create a pointless empty
loop which further optimizations surely remove.

The problem is either in perfect_nest_p (i.e. question whether what
perfect_nestify created is a valid perfect nest, but identical basic blocks
could as well come just from earlier passes without perfect_nestify being ever
called), or if lambda_loopnest_to_gcc_loopnest screw this up.

The problematic statement is the:
S.2_40 = S.2_165 + 1;
which is stmt_is_bumper_for_loop for the outer loop, but isn't used solely
as the bumper, but also in the inner loop:
D.1393_41 = S.2_40 * 6;


-- 
           Summary: -ftree-loop-linear miscompiles scalarize.f90
           Product: gcc
           Version: 4.3.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: jakub at gcc dot gnu dot org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29832

Reply via email to