Skip to content

Missed GVN/PRE for load instruction #59312

@weiguozhi

Description

@weiguozhi

Compile the test case with

clang -fno-omit-frame-pointer -fno-exceptions -O3 -c reduce2.ii -o reduce2.o --save-temps
struct u {
  bool ax();
  void bc();
  bool bd();
  long az;
  long bb;
};

inline bool u::ax() {
  if (bb > az)
    return true;
  if (bd())
    return false;
  return true;
}

inline void u::bc() {
  if (!ax())
    return;
  az++;
  return;
}

inline void foo(u *v) {
  if (!v->ax())
    return;
  if (v->az)
    v->bc();
  v->bc();
}

void bv(int l, int e) {
  for (; l!=e; ++l) {
    u m;
    while (m.ax())
      foo(&m);
  }
}

I got

    ...
    incq    %rcx
    movq    %rcx, -40(%rbp)
.LBB0_18:                               # %_Z3fooP1u.exit
                                        #   in Loop: Header=BB0_3 Depth=2
    movq    -40(%rbp), %rcx                              // 1
   
   ... 

    testb   %al, %al
    jne .LBB0_18
# %bb.8:                                # %if.endthread-pre-split.i
                                        #   in Loop: Header=BB0_3 Depth=2
    movq    -40(%rbp), %rcx                              // 2

   ...

    testb   %al, %al
    jne .LBB0_18
# %bb.16:                               # %_ZN1u2axEv.exit.if.end_crit_edge.i12.i
                                        #   in Loop: Header=BB0_3 Depth=2
    movq    -40(%rbp), %rcx                              // 3

    ...

Instructions 2 and 3 can be moved before jne, then instruction 1 can be deleted.
It looks like a missed GVN/PRE for load instruction.

Metadata

Metadata

Assignees

No one assigned

    Labels

    llvm:GVNGVN and NewGVN stages (Global value numbering)miscompilation

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions