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