[PATCH] D144053: [LICM] Ensure LICM can hoist invariant.group

luxufan via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 16 07:37:43 PST 2023


StephenFan added a comment.

I have a question what's the behavior the compiler would raise if we violate the !invariant.group 's semantic? For this case:

  define i32 @foo(ptr nocapture %p, ptr nocapture %q) {
  entry:
    %0 = load i32, ptr %p, align 4, !invariant.load !0
    store i8 2, ptr %p, align 1
    %1 = load i32, ptr %p, align 4, !invariant.load !0
    %add = add nsw i32 %1, %0
    ret i32 %add
  }
  
  !0 = !{}
  }

if runs GVN on it, this program is not changed.

But in this patch, we just check if the load's clobber def is a memoryphi and locates in loopheader, for this case

  define void @test(i64 %v, ptr %arg, ptr %arg1) {
  bb2:                                              ; preds = %bb
    br label %bb5
  
  bb5:                                              ; preds = %bb5, %bb2
    %tmp6 = phi i64 [ 0, %bb2 ], [ %tmp10, %bb5 ]
    %tmp3 = load i64, ptr %arg1, align 4, !invariant.group !0
    store i64 %tmp6, ptr %arg1, align 8
    %tmp10 = add nuw nsw i64 %tmp6, %tmp3
    %tmp11 = icmp eq i64 %tmp10, 200
    br i1 %tmp11, label %bb12, label %bb5
  
  bb12:                                             ; preds = %bb5, %bb
    ret void
  }

It hoists the load instruction even if there is a store that writes a new value to `%arg1` pointer operand.

And I found that for

  define i32 @foo(ptr nocapture %p, ptr nocapture %q) {
  entry:
    %0 = load i32, ptr %p, align 4, !invariant.load !3
    %conv = trunc i32 %0 to i8
    store i8 %conv, ptr %q, align 1
    %1 = load i32, ptr %p, align 4, !invariant.load !3
    %add = add nsw i32 %1, 1
    ret i32 %add
  }
  
  !3 = !{}

GVN removes `%1 = load i32, ptr %p, align 4, !invariant.load !3`. The reason is although `%q` mayalias `%p`, they are not the same pointer operand. According the docs, the value under `%p` will not be changed. So I think In this patch we can just check if clobber defs' pointer operand is the same as the load instruction to decide if we can hoist it.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144053/new/

https://reviews.llvm.org/D144053



More information about the llvm-commits mailing list