Fix wrong code generated by unroll-and-jam pass
commit3ec926d36fbf7cb3ff45759471139f3a71d1c4de
authorEric Botcazou <ebotcazou@adacore.com>
Thu, 6 Oct 2022 13:13:50 +0000 (6 15:13 +0200)
committerEric Botcazou <ebotcazou@adacore.com>
Thu, 6 Oct 2022 13:16:29 +0000 (6 15:16 +0200)
tree038eb343866568a2a1fcc078210bcd8ef7adb271
parentb9d04e915fe0f4cdcca40e6de65ae384ba82a429
Fix wrong code generated by unroll-and-jam pass

There is a loophole in the unroll-and-jam pass that can quickly result in
wrong code generation.  The code reads:

    if (!compute_data_dependences_for_loop (outer, true, &loop_nest,
                                &datarefs, &dependences))
        {
          if (dump_file && (dump_flags & TDF_DETAILS))
            fprintf (dump_file, "Cannot analyze data dependencies\n");
          free_data_refs (datarefs);
          free_dependence_relations (dependences);
          continue;
        }

but compute_data_dependences_for_loop may return true even if the analysis
is reported as failing by compute_affine_dependence for a dependence pair:

(compute_affine_dependence
  ref_a: data[_14], stmt_a: data[_14] = i_59;
  ref_b: data[_14], stmt_b: data[_14] = i_59;
Data ref a:
Data ref b:
affine dependence test not usable: access function not affine or constant.
) -> dependence analysis failed

Note that this is a self-dependence pair and the code for them reads:

          /* Nothing interesting for the self dependencies. */
          if (dra == drb)
            continue;

This means that the pass may reorder "complex" accesses to the same memory
location in successive iterations, which is OK for reads but not for writes.

gcc/
* gimple-loop-jam.cc (tree_loop_unroll_and_jam): Bail out for a self
dependency that is a write-after-write if the access function is not
affine or constant.

gcc/testsuite/
* gcc.c-torture/execute/20221006-1.c: New test.
gcc/gimple-loop-jam.cc
gcc/testsuite/gcc.c-torture/execute/20221006-1.c [new file with mode: 0644]