Skip to content

Non-determinsm in GVNSink #77852

Closed
Closed
@ilovepi

Description

@ilovepi

We've found non-deterministic behavior when using GNVSink.

A reproducer is included here.
gvn-reduced.zip

I've included the reduced case, my reduction script, and some IR files from -print-after-all w/ the module context.
In case it helps, I'm including theC++ code here.

#define a(e, ab) e->ac = e->ac ?: ab
#define b(e, ab) return a(e, ab)
struct A {
  long d;
  const char *ac;
};
bool g();
char a;
bool f;
static bool h(unsigned *i, bool p2) {
  A *e = 0;
  if (p2)
    ;
  char b;
  do {
    if (g())
      if (b) {
        if (f)
          b(e, "");
        if (a)
          b(e, "");
      }
    b = 7;
  } while (a);
  *i = 5;
  return true;
}
bool fn3(bool i) {
  unsigned c(h(&c, i));
  return true;
}

Ultimately, what we're seeing is that sometimes the GVNSink pass doesn't transform the IR. It seems that depending on the ordering of blocks in the Predecessors list, GVN may or may not trigger.

This is non-deterministic, because the list is ordered by pointer, which has no stable ordering w.r.t. the order in which blocks are analyzed and values sunk. This happens here

In fact, when I attempted to sort this list based on the ordering of blocks in the function, several tests broke due to the optimization no longer occurring. GVNSink/struct.ll is one I remember offhand, but there were others, too.

After playing around with some of this, I suspected that the break around

was the big issue, since it bails out differently based on the ordering of the blocks, but replacing it with a continue (and incrementing the iterator) causes other code gen issues, despite fixing the nondeterminism.

Note that the use of stable_sort later in this routine doesn't fix this issue as it occurs after the nondeterminism has already been introduced in the LockStepReverseIterator.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugIndicates an unexpected problem or unintended behaviorllvm:GVNGVN and NewGVN stages (Global value numbering)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions