Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8286177

C2: "failed: non-reduction loop contains reduction nodes" assert failure

    XMLWordPrintable

Details

    • b24

    Backports

      Description

        Similarly to JDK-8279622, a node marked as a reduction is hoisted out of its original reduction loop into an outer loop that is not marked as a reduction. The assertion introduced in JDK-8279622 catches this inconsistency and fails. Unlike JDK-8279622 though, the inconsistent reduction marking in this case is not fatal, in that it would not lead to a miscompilation should the assertion be disabled. This is because the inconsistently marked loop(s) contains safepoints, which inhibits SLP vectorization.

        HOW TO REPRODUCE

        $ javac Test.java FuzzerUtils.java
        $ java Test

        # Internal Error (/home/roland/jdk-jdk/src/hotspot/share/opto/superword.cpp:113), pid=4077494, tid=4077507
        # assert(!lpt->has_reduction_nodes() || cl->is_reduction_loop()) failed: non-reduction loop contains reduction nodes
        #
        # JRE version: OpenJDK Runtime Environment (19.0) (fastdebug build 19-internal-adhoc.roland.jdk-jdk)
        # Java VM: OpenJDK 64-Bit Server VM (fastdebug 19-internal-adhoc.roland.jdk-jdk, mixed mode, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, linux-amd64)
        # Problematic frame:
        # V [libjvm.so+0x1a3cb04] SuperWord::transform_loop(IdealLoopTree*, bool)+0x424

        FAILURE ANALYSIS

        The node corresponding to (acc += j) is marked as a reduction together with its (inner) loop:

          int i = 0, acc = 0;
          do {
              int j = 0;
              do { // inner loop marked as a reduction
                  if (b) {
                      acc += j; // node marked as a reduction
                  }
                  j++;
              } while (j < 5);
              i++;
          } while (i < 100);
          return acc;

        After unrolling and constant-folding the inner loop (b is always true), the node formerly corresponding to (acc += j), and now corresponding to (acc += 10), is hoisted into the outer loop, which is not marked as a reduction. This creates an inconsistent state that is later caught by the failing assertion:

          int i = 0, acc = 0;
          do {
              acc += 10; // node marked as a reduction (inconsistent, outer loop is not marked as a reduction)
              i++;
          } while (i < 100);
          return acc;

        Attachments

          1. FuzzerUtils.java
            13 kB
            Roland Westrelin
          2. hs_err_pid4077494.log
            68 kB
            Roland Westrelin
          3. replay_pid4077494.log
            114 kB
            Roland Westrelin
          4. Test.java
            9 kB
            Roland Westrelin

          Issue Links

            Activity

              People

                rcastanedalo Roberto Castaneda Lozano
                roland Roland Westrelin
                Votes:
                0 Vote for this issue
                Watchers:
                7 Start watching this issue

                Dates

                  Created:
                  Updated:
                  Resolved: